6 years, 11 months ago.

HTTPS post to custom TCP port number

I've been trying out the HTTPS post examples described here: https://os.mbed.com/teams/sandbox/code/http-example/

But I've been unable to get the example to work using my target server, which has a non-standard HTTPS port number (777, rather than 443).

I can open the socket to that custom port, using

TLSSocket* socket = new TLSSocket(network, "myserverhostname", 777, SSL_CA_PEM); if (socket->connect() != 0) { printf("TLS Connect failed %d\n", socket->error()); return; }

The TLS handshake and certificate validation goes just fine. But after I create any sort of request (get or post):

HttpsRequest* get_req = new HttpsRequest(socket, HTTP_GET, "https://myserverhostname:777/ingress/messages"); HttpResponse* get_res = get_req->send();

And then send that request, I keep receiving in reply a 400 invalid hostname error:

<!DOCTYPE HTML PUBLIC "-W3CDTD HTML 4.01EN""http://www.w3.org/TR/html4/strict.dtd"> <HTML><HEAD><TITLE>Bad Request</TITLE> <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD> <BODY><h2>Bad Request - Invalid Hostname</h2> <hr><p>HTTP Error 400. The request hostname is invalid.</p> </BODY></HTML>

Is there a mistake I'm making that immediately stands out to anyone? Thanks!

In http_request_builder.h, can you uncomment line 110, and dump the full request here?

posted by Jan Jongboom 14 Dec 2017

1 Answer

6 years, 11 months ago.

I've pushed a fix to mbed-http. Can you verify if this solves your issue, if so I'll update the examples. You can do this by right clicking on mbed-http, then press 'Update...' (or if you're using Mbed CLI, go into mbed-http folder and run `hg pull`).

(Host header did not include port number for non-default ports, was no problem on my test server, but apparently other servers choke on it).

Accepted Answer

Marvelous!!! That's amazingthank you so much; that indeed did the trick.

posted by Dan Lopez 14 Dec 2017

If you've a moment, I've set up a while(true) loop to loop through that POST line , followed by a delay of a few seconds, but right when I try to debug this code, the TLS handshake fails with

----- Setting up TLS connection -----
Connecting to myserverhostname:777
Starting the TLS handshake...
CMSIS-RTOS error: Stack underflow (status: 0x1, task ID: 0x200101B0, task name: )

I'm running this code on a K64F, which should have plenty of resources for the code; it's rather odd because I can send a single HTTPS post without any problem, but as soon as I add the line that turns the code block into a loop, I start seeing the stack underflow again. Thanks again for all the help! The code I'm referring to looks like

    TLSSocket* socket = new TLSSocket(network, ENDPOINT_HOST, ENDPOINT_PORT, SSL_CA_PEM);
    socket->set_debug(true);
    if (socket->connect() != 0) {
        printf("TLS Connect failed %d\n", socket->error());
        return 1;
    }
    
    // ------------------------------------------------------------------------
    // Main loop
    //while (true) // This is the line that triggers the stack underflow error
    {
        // Read the sensor values; see https://os.mbed.com/components/FXOS8700Q/
        acc.getAxis(acc_data);
    
        // ------------------------------------------------------------------------
        // Assemble the message:
    
        string body = DEVICE_NAME + "," + DEVICE_TEMPLATE + "\n" + 
            "X-acceleration:" + float_to_string(acc_data.x);

        // ------------------------------------------------------------------------
        // POST request
        {

            // Create the new request
            //HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, TARGET_URL);
            HttpsRequest* post_req = new HttpsRequest(socket, HTTP_POST, TARGET_URL);
        
            // Turn on debugging - this hides TLS connection information
            post_req->set_debug(true);
        
            // Add headers: content type and authentication
            post_req->set_header("Content-Type", "application/json");
        
            // Note: the header value is "Basic " plus the base64 encoding of username:password
            post_req->set_header("Authorization", BASIC_AUTH_HEADER);
        
            // Send the body
            HttpResponse* post_res = post_req->send(body.c_str(), strlen(body.c_str()));
            
        
            // Check the response for an error
            if (!post_res) {
                printf("HttpRequest failed (error code %d)\n", post_req->get_error());
                return 1;
            }
        
            // Print the response
            dump_response(post_res);
        
            // Free up the request object
            delete post_req;
        }
    
        // Wait
        wait(SECONDS_BETWEEN_MESSAGES);
    }
posted by Dan Lopez 14 Dec 2017

A simple trick would be to increase stack size for the main thread (or spin up a new thread with larger stack and run from there): https://os.mbed.com/docs/v5.6/reference/configuration.html

posted by Jan Jongboom 15 Dec 2017