Standard mechanism to send a single file into a POST request - file

I am looking for a standard way of sending a POST request with a single file in it, as it contains a single file we are looking for something else than multipart/form-data,
We thought about using the Content-Disposition header or the Content-Type, the first one looks like it is only valid for a multipart request or as a response header (not request), not sure if only using the Content-Type to a file type would be enough.

Related

POST files using HTTP action - encoding problems

I have problems to upload attachments to JIRA REST API using HTTP POST with the HTTP action. It works with text files (Content-Type: text/plain) but when I'm posting other files such as PDF and images the files are not uploaded correctly; they get the wrong file size and are not readable.
I assume it's a problem with the encoding. I've tried to use the binary function on the file contents but it does not help. According to JIRA the REST API doesn't accept base64-encoded files.
Have anyone of you been successful in posting attachments (other than text files) to JIRA or another API?
I found how to do it. The body of the HTTP request should contain special attributes for Multipart and Content-Type as described here: https://learn.microsoft.com/en-us/azure/connectors/connectors-native-http#content-with-multipartform-data-type
So the HTTP POST should look like this:

How can I send a file along the headers of a POST call, while having regular data in the request body

I had an existing POST API which was used to sent an object to server. Now I want to attach a file to the header of the same file. Is it possible to do such a thing. Can a request have multiple content-type.
I tried using ngFileUpload directive, and provide my object to data field of Upload.upload method. However, by doing this the entire data object seems to go in header and the request fails.
Any suggestions for sending file in headers and JSON in request body of a POST call??
I eventually found out that a HTTP request can have a single Content-type. This is as per the standards. However it is still possible and quite easy to send data along with a file using the FormData Object. The support for FormData though is not across all the versions of various browsers.

Access-Control-Allow-Origin Issue with API

I have written a pretty simple API in PHP and am running it as a service (https://protoapi-dot-rehash-148415.appspot.com/events/).
When I try to load a data grid with the JSON from the API, I am getting the dreaded "No 'Access-Control-Allow-Origin' header is present on the requested resource." error on the page on which I want to consume the JSON. (http://proto-angular-dot-rehash-148415.appspot.com/events.php)
I've tried a couple of different methods to add Access-Control-Allow-Origin: "*" to the app.yaml file and to the header in the PHP file that produces the API. I think it doesn't work in the yaml because you cannot apply http_headers to dynamic files, and it doesn't work in the file because of the compression.
Is there any other way to make this work, short of putting the API and the app in the same service? I'd hate to do that because I am using mod_rewrite for the API and it will probably cause chaos on my app.
Any insights would be greatly appreciated!
-Mike
The header won't do any good unless you add it server-side, on the events API. The server is what dictates CORS permissions. You could send it messages or files all day with the right headers at the top and it will just ignore them. The allow-origin header has to come from the server to allow the cross-origin resource sharing (CORS) to take place.
I would recommend prepending the header in the function that offers up the API or handles the requests. Your events API spits out a lot of JSON. Right before that JSON, have your API spit out the header Access-Control-Allow-Origin: * and you should be all set.
As a sanity check you can also try adding Access-Control-Allow-Headers: Content-Type and see if that helps. Based on your comment about the Content-Type header, this may be part of the problem. It should be added the same way as the other one; have your API send it prior to your events JSON on its own line (put a \n to make a new line inside the string literal).

What is happened behind the scene, when you submit a file using POST

When a user selected a file and click submit, all the other input fields are transferred in HTTP header. But what happened to the file? How did it get transferred to the server? What protocol has been used?
When you POST data to a server, said data will be transmitted in the HTTP body rather than the HTTP header. The file will be encoded as either application/x-www-form-urlencoded or multipart/form-data (as described in the HTML 4.01 specification).

how http server received file from client

I have written code for sending client user passwords to an HTTP server for verification via HTTP. I generate the query string (containing usr, pwd) and send the request to the server. That works.
But now I have to send a file (text/xml) to that server. I don't know how it can be done.
Do we have to write some code on the server or only in the client?
What are the mechanisms on the server for accepting file and on the client for sending files?
The HTTP protocol is really simple, actually:
the client sends a line containing HTTP method name, URL and protocol version
the client sends an RFC822 header containing request parameters and, if a data block follows, details about the data block.
the client sends the data block
the server sends a line containing protocol version, status code and message
the server sends an RFC822 header containing response parameters and, if a data block follows (or the client performed a HEAD request), details about the data block
the server sends the data block, unless the method is HEAD.
the connection is either torn down, or the protocol restarted.
Typically, servers will understand at least these methods:
GET (client does not send data block, server sends data block)
HEAD (same as GET, but server omits response data block)
POST (client sends data block, server responds with data block)
PUT (client sends data block, server does not send data block)
There is some implied semantics in the choice of method, in that GET requests never modify server state and their results may be cached and reused (which is what allows the browser to go back and forth between pages), while POST requests do change server state -- incidentally, this is what you do when you upload a file.
So, in order to send a file, prepare a POST or PUT request (depending on whether you expect a reply document, or if a simple acknowledgement status code is sufficient), which consists of the request line, the headers containing extra protocol info ("Host:", "User-Agent:", ...), the headers describing the file ("Content-Type:", "Content-Length:", ...), an empty line, and the file contents, and send that over a TCP connection, then read back the status line, the response headers and the response file (if you asked for one).
It depends on the server's application how to load the file.
You may need to send the file using the HTTP "POST" method instead of "GET".
POST /your_uri HTTP/1.1
Host: www.yourhost.com
Content-type: application/x-www-form-urlencoded
Content-length: 41
filename=test.xml&data=yoururlencodeddata
The server application may expect files encoded with "multipart/form-data" boundaries, something like that:
Content-type: multipart/form-data, boundary=AaBb01x
--AaBb01x
content-disposition: form-data; name="yourfield"
Your field data
--AaBb01x
content-disposition: form-data; name="yourfilefield"; filename="filename.xml"
Content-Type: text/xml
<root>your xml data</root>
--AaBb01x
If its a XML file it is easy.
You can add Content-Type: text/xml in the HTTP header and append the XML file data after the \r\n\r\n of the HTTP header and send it via the socket to the webserver.
The webserver will understand from the HTTP header that it contains XML file and takes the file. In the case of a bnary file, you will need to convert it to base64.
For example I have used a buffer to store the http request. Now if you send this buffer to the socket connected to the webserver, the FileName.xml will be saved in the webserver. For this to work the upload.php has to able to work with POST data.
The boundary is to show the boundary between the data and is needed by the HTTP protocol. It can be any random generated number and make sure the start boundary and the close boundary numbers are equal. Also content length is the length of the file.
`
char buf[2048] = "POST http://www.nameofyoursite.com/upload.php HTTP/1.1\r\n"
"Host: www.nameofyoursite.com\r\n"
"Content-Type: multipart-form-data, boundary=1234567\r\n"
"Content-Length: 15\r\n\r\n"
"--1234567\r\n"
"Content-Disposition: form-data; name=\"uploadedfile\"; filename=\"FileName.xml\"\r\n"
"Content-Type: text/xml\r\n"
"<xml>This is a test</xml>\r\n"
"--1234567--\r\n";
`

Resources