HTTP Requests Using Sample Client

Hello,

I am trying to test out HTTP request methods from ssl_client2 to a test server. The GET and DELETE requests work fine, however the PUT and POST requests only send the headers to the server and no body. The server receives the PUT/POST response but returns an error of a 400 Bad Request, due to the PUT/POST body being empty.

I am modifying the GET_REQUEST with the appropriate headers and JSON-formatted parameters (just for testing purposes). Reading the documentation for mbedtls_ssl_write it says the function might do partial writes in some cases if the return value is non-negative and less than length, but when checking the values the return value is equal to the length so there should be no issues there.

I am able to use curl with the same headers and body to successfully make PUT/POST requests, so the server doesn’t like some format that is being passed from the client. I tried passing just plain text and other text just to see if a body is passed at all to the server, and it is empty every time.

Below is the GET_REQUEST that I am passing:

#define GET_REQUEST “POST %s / HTTP/1.0\n” \
“Content-type: application/json\r\n\r\n” \
“{"Subscription":{"encoding":"0","level":"+S0",” \
“"limit":"9","subscribedResource":"/sep2/edev/4",” \
“"notificationURI":"https://10.0.2.15:3443"}}” \
#define GET_REQUEST_END “\r\n\r\n”

My successful curl command was:

curl -H “Content-Type: application/json” -k --key key.pem --cacert rootcacert.pem --cert cert.pem https://10.0.2.15:8443/sep2/edev/4/sub --ciphers ECDHE-ECDSA-AES128-CCM8 -X POST -v -d ‘{“Subscription”:{“encoding”:“0”,“level”:“+S0”,“limit”:“7”,“subscribedResource”:“/sep2/edev/4”,“notificationURI”:“https://10.0.2.15:3443”}}’ //the different ports are intended

Is there something simple I am missing or doing incorrectly? I noticed there is an HTTP-client for Mbed OS but I’m assuming that isn’t needed here since we’re able to write the request in the first place?

Thanks in advance!

Hi @akagan
Thank you for your question!

Is it intentional that you have an additional '' character at the end of your GET_REQUEST definition?
If you showed your GET_REQUEST as it is in your code, and same lines, then your GET_REQUEST is:

“POST %s / HTTP/1.0\nContent-type: application/json\r\n\r\n{“Subscription”:“encoding”:“0”,“level”:”+S0",“limit”:“9”,“subscribedResource”:”/sep2/edev/4",“notificationURI”:“[https://10.0.2.15:3443](https://10.0.2.15:3443/)”}}#define GET_REQUEST_END “\r\n\r\n

And the you won’t have a definition for GET_REQUEST_END

Later in the code, you will have:

len = mbedtls_snprintf( (char *) buf, sizeof( buf ) - 1, GET_REQUEST,
                            opt.request_page );
    tail_len = (int) strlen( GET_REQUEST_END );

and tail_len would be calculated as 0
This would probably result in unexpected behavior, I believe.
Regards,
Mbed TLS Team member
Ron

Hi Ron,

Thank you for your response!

I actually included a different GET_REQUEST than I’ve been using, although they both don’t work. Here is the correct one with \" added to the values:

#define GET_REQUEST "POST / HTTP/1.0\n" \
"Content-type: application/json\r\n\r\n" \
"{\"Subscription\":{\"encoding\":\"0\",\"level\":\"+S0\"," \
"\"limit\":9,\"subscribedResource\":\"/sep2/edev/4\"," \
"\"notificationURI\":\"https://10.0.2.15:3443\"}}"

The (relevant) output of ssl_client2:

  > Write to server:len is 201
tail_len: 4
len+=tail_len: 205
written: 0
ret val of mbedtls_ssl_write: 205
written+=ret: 205
 205 bytes written in 1 fragments

POST / HTTP/1.0
Content-type: application/json

{"Subscription":{"encoding":"0","level":"+S0","limit":9,"subscribedResource":"/sep2/edev/4","notificationURI":"https://10.0.2.15:3443"}}


  < Read from server: 336 bytes read

HTTP/1.1 400 Bad Request
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,PUT,POST,DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Expose-Headers: Location
Content-Type: text/html; charset=utf-8
Content-Length: 22
Date: Tue, 21 May 2019 17:07:02 GMT
Connection: close

  . Closing the connection... done

Based on the printout it seems the quotations are correct. As you can see I’ve added a couple print statements in step 6 - Write the GET request - of the client. We can see tail_len and the value is not 0. Also, I’m not sure I’m seeing the reason why you included the notificationURI IP address enclosed in both brackets and parentheses?

Thanks again for the help!

Hi @akagan
Thank you for your information!

Since the error is an HTTP code, i don’t think htis is related to the TLS data.
However, I compared the working command from your curl command, and the failed command in TLS, and saw one difference:
curl:

“limit”:“7”

Mbed TLS:

"limit":9

I don’t think that the difference in the value matters, however, as you can see, in the working curl command you are sending the value as a string, and in the Mbed TLS command, you are sending the value as an integer. Could this be the issue?

Regards
Ron