Sending file over HTTP - Bad Request

Hi,

I'm trying to send files over HTTP, using the nRF9160. In order to do this, I'm using the https_client sample. It was working with the initial configuration (HEAD request, to example.com). Now I just changed the host, and request, and I get all the time 400 Bad Request, even though the request was successful with with python socket. I also tried the head request with the new host, and it worked.

Here is the C request I'm trying to send with the DK and the https_client sample, that gets a Bad Request :

 

#define HTTP_POST   \
	"POST /upload HTTP/1.1\r\n"\
	"Host: xxxxxx.eu:8000\r\n"\
	"Content-Length: 202\r\n"\
	"Content-Type: multipart/form-data; boundary=------------------------a56f48d03f4a08e5\r\n"\
	"\r\n"\
	"--------------------------a56f48d03f4a08e5\r\n"\
	"Content-Disposition: form-data; name=\"files\"; filename=\"mytestfile.txt\"\r\n"\
	"Content-Type: text/plain\r\n"\
	"\r\n"\
	"AABBCCDD\r\n"\
	"\r\n"\
	"--------------------------a56f48d03f4a08e5--\r\n"\

Once printed, the request is the following (single quotes at start and end are printed on purpose to see the start and end of the request) : 

And here is the python request, with which I could send a file :

request = """POST /upload HTTP/1.1
Host: xxxxxx.eu:8000
Content-Length: 202
Content-Type: multipart/form-data; boundary=------------------------a56f48d03f4a08e5

--------------------------a56f48d03f4a08e5
Content-Disposition: form-data; name="files"; filename="mytestfile.txt"
Content-Type: text/plain

AABBCCDD

--------------------------a56f48d03f4a08e5--
"""

Is it only an error in the request, or it could be something else ?

Thanks for your help !

Kind regards,

Armand

Parents
  • Hi,

     

    If you want to upload a file, you need to construct your POST correctly.

    "\r\n\r\n" is effectively end of the header, so your current POST might not behave as you intend it to. You should also dynamically align the Content-Length according to your http body length.

    https://stackoverflow.com/questions/50447483/end-of-http-header

     

    A side-note, if you are using HTTPS, be sure to change your CA root according to the domain that you're connecting to. You can see the chain by using openssl, similar to what is done here:

     RE: changing certificate in https_client sample 

     

    Kind regards,

    Håkon

  • Hi,

    Thanks for your answer.

    I realized I did have a content-length issue, however this seems solved. I am now meeting another problem : the recv() function (official doc) never returns... Here is the part of the code from the https_client sample (https_client sample) that causes trouble :

    off = 0;
    	do {
    		printk("Before recv()\n");
    		bytes = recv(fd, &recv_buf[off], RECV_BUF_SIZE - off, 0);
    		printk("After recv()\n");
    		if (bytes < 0) {
    			LOG_ERR("recv() failed, err %d", errno);
    			clean_up();
    		}
    		off += bytes;
    	} while (bytes != 0 /* peer closed connection */);

    The output is the following :

    The recv() function is called one first time, and runs just fine. It returns 148 at the first iteration. It is in the second iteration that it keeps the whole program from moving on.

    I suspect that this is caused by the \r\n\r\n that you mentionned before. Maybe the end of the request is not clearly identified by the server ?

    Anyway, I'll keep on investigating this, and thanks for your suggestions.

    By the way, I had already updated the CA to fit my server.

    EDIT : I realized that the code gets stuck in recv() because it is called as blocking. I'm trying to change this, using fcntl(fd, F_SETFL, O_NONBLOCK); but without great success so far. I'll let you know.

    Kind regards,

    Armand

Reply
  • Hi,

    Thanks for your answer.

    I realized I did have a content-length issue, however this seems solved. I am now meeting another problem : the recv() function (official doc) never returns... Here is the part of the code from the https_client sample (https_client sample) that causes trouble :

    off = 0;
    	do {
    		printk("Before recv()\n");
    		bytes = recv(fd, &recv_buf[off], RECV_BUF_SIZE - off, 0);
    		printk("After recv()\n");
    		if (bytes < 0) {
    			LOG_ERR("recv() failed, err %d", errno);
    			clean_up();
    		}
    		off += bytes;
    	} while (bytes != 0 /* peer closed connection */);

    The output is the following :

    The recv() function is called one first time, and runs just fine. It returns 148 at the first iteration. It is in the second iteration that it keeps the whole program from moving on.

    I suspect that this is caused by the \r\n\r\n that you mentionned before. Maybe the end of the request is not clearly identified by the server ?

    Anyway, I'll keep on investigating this, and thanks for your suggestions.

    By the way, I had already updated the CA to fit my server.

    EDIT : I realized that the code gets stuck in recv() because it is called as blocking. I'm trying to change this, using fcntl(fd, F_SETFL, O_NONBLOCK); but without great success so far. I'll let you know.

    Kind regards,

    Armand

Children
Related