0

I've been trying for days to upload plain text files to a web server (both IIS and NGINX) via HTTP PUT/POST, from a C# desktop app, unsuccessfully

However, I'm no further along. I have had various threads here, and on StackOverflow regarding specific issues), but given how trivial it was to GET files from the file server - I'm starting to wonder if I'm missing the point.

Can a web server even accept a file POST, without additional scripting running server side? I.e. do common web servers, Apache, IIS, NGINX etc 'know what to do' with a file upload, out of the box?

2
  • 1
    Accepting files on the server is considerably more involved. You don't want anyone to have unrestricted access to upload anything Nov 17, 2023 at 7:17
  • Thanks, would you be able to expand on this please? Essentially this is for a desktop app to be able to upload user logs, so in they respect I was users (anyone) to have unrestricted access (I.e. they don't have to enter a username and password) to upload logs. Nov 17, 2023 at 13:03

6 Answers 6

1

No they don't, you run an application on the webserver which accepts the file and stores it for example in a file or database. There are quite simple examples available for almost any language. If you don't want to work on the server side you might also try for example Amazon AWS S3 which has a hosted service API you can send files to. Then you don't have to deal with it directly to test.

Here is a simple example for PHP for example:

https://www.php.net/manual/en/features.file-upload.post-method.php

There is also a simple web form so you can test the server first before working on the C# app.

For test setting this is fine, in production you need to ensure that you have authentication set up so no other person can upload files. Make sure to read about that.

Also maybe good to know that you can install a webserver manually but you can also download a MAMP (Mac) or WAMP (Windows) package to have a complete server running in minutes for your testing. https://www.mamp.info/de/mac/ That makes getting running easy.

3
  • I'm interested to know why this answer is downvoted? Is there something factually incorrectly? Ultimately I was planning on running my web server in AWS EC2, and have actually set this up already before reverting to a local host for early testing. AWS S2 however might simplify things greatly for me... Nov 17, 2023 at 12:47
  • 1
    I think because it starts with "no" and the other answers start with "yes". Amazon S3 or lambdas are also potential good options; with more work on the client side you can upload directly into S3.
    – pjc50
    Nov 17, 2023 at 14:23
  • 1
    Well, only a couple of hours later after getting started with S3 (compared to several days with Windows & NGINX) - and our pre-existing .NET desktop app is uploading logs to S3 via HTTPS, and successfully downloading files too, in a highly scalable cloud location which was ultimately where we wanted to end up. Now this was the solution I was looking for! Thanks Luc, if only I could clear off the downvotes on this! Nov 17, 2023 at 17:08
4

Yes, it can. You may add protocols such as WebDAV to your Nginx or IIS, or FTP to IIS (as far as I know, there is no FTP support for Nginx).

Regarding WebDAV, you can map it then as a drive in Windows on client side.

This being said, of your goal is to be able to store files in the cloud, a better (easier, more reliable) option would be to use an existing service, such as Google Drive.


Since I posted the answer, the OP specified that the purpose is:

To allow specific C# desktop applications to upload user logs to a web location from anywhere around the world.

For logging purposes, one may want to consider solutions such as Logstash, with data stored in Elasticsearch or a similar database, the benefit being that it would be more searchable. Or use a product designed specifically for that, such as Stackify.

Here again, cloud services may be extremely helpful, occasionally providing a C# NuGet package that will make it possible for your application to stream the logs to the cloud provider with as few lines of code as possible. And, of course, you'll get the benefit of being able to search those logs, filter them, or attach specific actions (for instance, sending an SMS when a given message is encountered).

If you want to avoid cloud, still, never ever let users to upload whatever they want to your server. There are, essentially, two reasons.

  1. If the users can upload whatever they want, this may give them a possibility to submit an executable script that may end up being executed on your server, eventually giving root access to it.

  2. With no control as to what exactly is stored on your server, you make it possible to be sued. For instance, hosting viruses, content that infringes copyright law, or child pornography could have very serious consequences in many countries. And “sorry, that's not mine” won't work here, as you are storing this content, and you allowed it to be uploaded on your server.

When you say “Yes it can, you may add...,” may I clarify—this means they can't—until adding FTP, WebDAV etc.?

Those are usually extensions that you have to explicitly add. But they don't require any custom development. You just add them, and configure them accordingly, just as you configure the web server when it comes to serving static files.

But, again, this is a wrong approach in your case. Don't do that.

5
  • With DAV, it's as simple as "curl -T"
    – pjc50
    Nov 17, 2023 at 9:48
  • 1
    I'd argue FTP is not part of a web server (but I acknowledge that "web" and "internet" are often used interchangably, however imprecise that may be). Nov 17, 2023 at 10:04
  • Thanks, no that's absolutely not my intention - I've got plenty of NAS storage available. This is to allow specific C# desktop applications to upload user logs to a web location from anywhere around the world. When you say "Yes it can, you may add...", may I clarify - this means they can't - until adding FTP, WebDAV etc...? Nov 17, 2023 at 13:01
  • @jwilo: see the edit. Nov 17, 2023 at 15:59
  • Thanks Arseni, this was a very insightful answer. As per the marked solution, we've gone with an AWS S3 solution and have it up and running already, and am just familiarising myself with the various access controls/permissions etc. Thanks again! Nov 17, 2023 at 17:13
2

Can a web server even accept a file POST, without additional scripting running server side? I.e. do common web servers, Apache, IIS, NGINX etc 'know what to do' with a file upload, out of the box?

Yes, but you need to make sure to configure authentication, and tends to be turned off by default to prevent the internet filling up your web server with junk.

NGINIX supports webdav: https://www.filestash.app/2021/12/09/nginx-webdav/

4
  • Thanks for this! So, when I was using IIS for a few days, I came across endless recommendations not to use WebDAV - you mention authentication, does that mean these web servers can handle a file upload, if authenticated, without WebDAV, or WebDAV is the means to do this? I hope this doesn't sound like a low effort reply, I've been on this for 3 days straight... Nov 17, 2023 at 12:58
  • WebDAV is one means to do this. There are other means to do this. None of them are enabled "out of the box" because of the security risks, so you need to pick one and enable/configure it.
    – pjc50
    Nov 17, 2023 at 14:24
  • With things like this, part of your problem is there are too many possible solutions, so you need to pick some to constrain the solution space. You can run C# on the server, for example. pragimtech.com/blog/blazor/put-in-asp.net-core-rest-api
    – pjc50
    Nov 17, 2023 at 14:27
  • Yes, the myriad of options was pretty intimidating for somebody not from a web background... Thankfully the marked solution provided exactly what we needed! Thanks for your help. Nov 17, 2023 at 17:11
2

HTTP is deliberately designed to be generic, so it can be used for lots of different applications. There is no such thing as a "file" in HTTP, so it is impossible for an HTTP server to 'know what to do' with a file upload. There are Operating Systems which don't have the concept of a "file" at all, and you can run HTTP servers on them, for example.

What you are doing, is PUTting a representation of a resource to a URI. You have to, somehow, tell the HTTP server how to interpret that request.

There are other protocols you could use, though, which are specifically designed for file transfer. For example, there is the File Transfer Protocol (FTP). FTP servers 'know what to do' with uploaded files, because that is their job.

1
  • 1
    Thanks! I've avoided FTP due to my own experience of needing to configure ports for FTP, something I don't want users to have to deal with. So I think the really interesting and key bit of this answer is the 'somehow'. How do I do this on the web server? Nov 17, 2023 at 12:54
0

It may helpful, if you could included some info from your previous question (Which is technology is preferably for uploading desktop application usage statistics, SFTP, or HTTPS?) to give some context as to why you are asking the question.

When I gave the answer to the previous question, the direction I was suggesting was that you wrote some code (in the language of your choice) to handle the POST request. That said, it is typically possible to configure a web servers to accept direct uploads of files, for example here is a working configuration for Nginx (tested on Mac using Homebrew):

Replace the server block in the standard /opt/homebrew/etc/nginx/nginx.conf with:

server {
    listen 127.0.0.1;

    location ~ "/upload/([0-9a-zA-Z-.]*)$" {
       dav_methods              PUT;
       client_body_temp_path    /tmp/incoming;
       alias                    /tmp/upload/$1;
       create_full_put_path     on;
       dav_access               group:rw  all:r;

       client_body_in_file_only on;
       client_body_buffer_size  128k;
       client_max_body_size     100M;
    }
}

You will also need to make sure the directories exist and the the web server can write to them:

mkdir        /tmp/incomming /tmp/upload
chown nobody /tmp/incomming /tmp/upload

Then you would upload a file with a command like:

curl -T test.txt http://localhost/upload/test.txt

Note: In this case I am using a PUT since I am giving the path to upload to in the path (that may or may not be desirable).

If you choose to use a standard Nginx config (without writing any custom code) you lose some of the advantages of being able to directly trigger a workflow / return ID's back to the client per my previous answer. However you could monitor the file system to look for new files to trigger such a workflow.

0

A HTTP server could implement such functionality, there’s nothing in the spec preventing it as far as I know. But I don’t know of one that does, presumably because it’s a security nightmare and of nearly zero utility, and not just because no one has ever thought of it before.

Why is it of nearly zero utility you might ask...HTTP has become the dominant protocol, beating out things like ftp and gopher, primarily because it is easily amenable to running external code for each command (passing the message on to another application), which allows it to do what the other protocols do and more.

For GET it frequently makes sense to simply return a static resource without referencing an external application, but that is not the case for PUTting an item on the server. In fact the most common case of PUTting a file results in the file being stored in a database somewhere, and not as a resource that the HTTP server knows about.

In short, you need to have some code that is run on your PUT/POST, how you do that will depend upon what server you are using and what kind of code you want to run. You mentioned IIS, where it would be easy make an api endpoint or “page” that accepts a file for processing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.