Convert cURL REST request to PIC32 C-language TCP client

24 views Asked by At

I am trying to call a REST API endpoint on a dummy JSON server.

  1. First, I call it from the Macos terminal using cURL:

curl -v https://dummyjson.com/products/1

This correctly returns a HTTP 200 status with the expected JSON payload:-

*   Trying 104.196.232.237:443...
* Connected to dummyjson.com (104.196.232.237) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* TLSv1.2 (IN), TLS handshake, Server hello (2):
.....[omitted for brevity]....
* SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=dummyjson.com
*  start date: Aug 27 08:05:06 2023 GMT
*  expire date: Nov 25 08:05:05 2023 GMT
*  subjectAltName: host "dummyjson.com" matched cert's "dummyjson.com"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* using HTTP/2
* h2 [:method: GET]
* h2 [:scheme: https]
* h2 [:authority: dummyjson.com]
* h2 [:path: /products/1]
* h2 [user-agent: curl/8.1.2]
* h2 [accept: */*]
* Using Stream ID: 1 (easy handle 0x7fa815011800)
> GET /products/1 HTTP/2
> Host: dummyjson.com
> User-Agent: curl/8.1.2
> Accept: */*
> 
< HTTP/2 200 
< access-control-allow-origin: *
< x-dns-prefetch-control: off
< x-frame-options: SAMEORIGIN
< strict-transport-security: max-age=15552000; includeSubDomains
< x-download-options: noopen
< x-content-type-options: nosniff
< x-xss-protection: 1; mode=block
< x-ratelimit-limit: 120
< x-ratelimit-remaining: 119
< date: Fri, 22 Sep 2023 13:08:31 GMT
< x-ratelimit-reset: 1695388130
< content-type: application/json; charset=utf-8
< content-length: 519
< etag: W/"207-QowjjkZS3dPvv4L6zPF2KPB7cKk"
< vary: Accept-Encoding
< server: railway
< 
* Connection #0 to host dummyjson.com left intact
{"id":1,"title":"iPhone 9","description":"An apple mobile which is nothing like apple","price":549,"discountPercentage":12.96,"rating":4.69,"stock":94,"brand":"Apple","category":"smartphones","thumbnail":"https://i.dummyjson.com/data/products/1/thumbnail.jpg","images":["https://i.dummyjson.com/data/products/1/1.jpg","https://i.dummyjson.com/data/products/1/2.jpg","https://i.dummyjson.com/data/products/1/3.jpg","https://i.dummyjson.com/data/products/1/4.jpg","https://i.dummyjson.com/data/products/1/thumbnail.jpg"]}
  1. Next, I try to call the same JSON server from a PIC32 in C-code but the TCPIP state machine gets stuck waiting for a connection:
bool postJSONTest()
{
    strcpy(pHeaderBuffer, (char*)"GET /products/1 HTTP/1.1\r\n");
    strcat(pHeaderBuffer, (char*)"Host: dummyjson.com \r\n");
    strcat(pHeaderBuffer, (char*)"Content-Type: text/plain charset=utf-8\r\n");
    strcat(pHeaderBuffer, (char*)"Content-Length: 519 \r\n");
    strcat(pHeaderBuffer, (char*)"Accept-Language: en-us \r\n");
    strcat(pHeaderBuffer, (char*)"Accept-Encoding: gzip, deflate \r\n");
    strcat(pHeaderBuffer, (char*)"Connection: Keep-Alive \r\n\r\n");

    strcpy(buffPost, (char*)pHeaderBuffer);

    TCPIP_TCP_ArrayPut(tis_appData.socket, (const uint8_t*)buffPost, (uint16_t)strlen(buffPost));

    // EOL
    TCPIP_TCP_ArrayPut(tis_appData.socket, (const uint8_t*)"\r\n", 2);
    TCPIP_TCP_ArrayPut(tis_appData.socket, (const uint8_t*)"\r\n", 2);

    // flush all data through socket
    return TCPIP_TCP_Flush(tis_appData.socket);
}

  1. For comparison, I can make a similar call from the same PIC32 to Google Analytics (Measurement Protocol), whereupon I get a HTTP 200 result:
    // Header
    strcpy(pHeaderBuffer, (char*)"POST /collect HTTP/1.1\r\n");
    strcat(pHeaderBuffer, (char*)"Host: ");
    strcat(pHeaderBuffer, (char*)GAServer); // "www.google-analytics.com"
    strcat(pHeaderBuffer, (char*)"\r\n");
    strcat(pHeaderBuffer, (char*)"Content-Type: text/xml; charset=utf-8\r\n");
    strcat(pHeaderBuffer, (char*)"Content-Length: ");
    lenPayload = strlen(pPayloadBuffer);
    uitoa(lenPayload, (uint8_t*)ContentLength);
    strcat(pHeaderBuffer, (char*)ContentLength);
    strcat(pHeaderBuffer, (char*)"\r\n");
    strcat(pHeaderBuffer, (char*)"Accept-Language: en-us \r\n");
    strcat(pHeaderBuffer, (char*)"Accept-Encoding: gzip, deflate \r\n");
    strcat(pHeaderBuffer, (char*)"Connection: Keep-Alive \r\n\r\n");

    strcpy(buffPost, (char*)pHeaderBuffer);
    strcat(buffPost, (char*)pPayloadBuffer);

    TCPIP_TCP_ArrayPut(tis_appData.socket, (const uint8_t*)buffPost, (uint16_t)strlen(buffPost));

    // EOL
    TCPIP_TCP_ArrayPut(tis_appData.socket, (const uint8_t*)"\r\n", 2);
    TCPIP_TCP_ArrayPut(tis_appData.socket, (const uint8_t*)"\r\n", 2);

    // flush all data through socket
    return TCPIP_TCP_Flush(tis_appData.socket);

Conclusion: I am guessing my error is somewhere in the HTTP request to dummyJSON.com

Any ideas?

Thanks in advance, Quijote

0

There are 0 answers