aws / amazon-freertos

DEPRECATED - See README.md
https://aws.amazon.com/freertos/
MIT License
2.54k stars 1.1k forks source link

[BUG] HTTPClientSend does not update statusCode #3502

Closed Froopas closed 2 years ago

Froopas commented 2 years ago

Hello,

When sending a Http request to a server I cannot read the status code from the HTTPResponse_t struct. It is just the initial value.

aggarg commented 2 years ago

If you receive a response from the server, this line should update the status code - https://github.com/FreeRTOS/coreHTTP/blob/main/source/core_http_client.c#L687

Couple of things to do -

Thanks.

Froopas commented 2 years ago

Hello,

The return value of HTTPClient_Send is "HTTPSuccess". When using wireshark, the request goes through and a response is sent. I can access the body of the response but not the status code.

When debuging it does not seem as if the program reaches the line 687.

aggarg commented 2 years ago

Does the control reach the call to llhttp_execute at this line - https://github.com/FreeRTOS/coreHTTP/blob/main/source/core_http_client.c#L1192

When you see the packet on wireshark, what is the status code?

Froopas commented 2 years ago

The program does reach line 1192.

The response in Wireshark is the correct one, for the first call it is 400 and second it is 200. In the header buffer of the response is also the correct status code, but not in the variable.

aggarg commented 2 years ago

Did you increase the log level for the coreHTTP library to debug?

Froopas commented 2 years ago

I tried but I don't think I succeeded.

aggarg commented 2 years ago

What change did you make? Also, which hardware platform are you using? Can you share your code?

Froopas commented 2 years ago

I added the line

define LIBRARY_LOG_LEVEL LOG_DEBUG

aggarg commented 2 years ago

Is it possible for you to share code?

Froopas commented 2 years ago

Unfortunately I am having some git issues, as such I can't push my code to my repo. But here is the function which uses HTTPClient_Send

static BaseType_t prvSendHttpRequest( const TransportInterface_t * pxTransportInterface,
                                      const char * pcMethod,
                                      size_t xMethodLen,
                                      const char * pcPath,
                                      size_t xPathLen,
                                                          const char* pHost,
                                      const char* pBody,
                                      int* respCode,
                                      const char* respBody)
{
    /* Return value of this method. */
    BaseType_t xStatus = pdPASS;

    /* Configurations of the initial request headers that are passed to
     * #HTTPClient_InitializeRequestHeaders. */
    HTTPRequestInfo_t xRequestInfo;
    /* Represents a response returned from an HTTP server. */
    HTTPResponse_t xResponse;
    /* Represents header data that will be sent in an HTTP request. */
    HTTPRequestHeaders_t xRequestHeaders;

    /* Return value of all methods from the HTTP Client library API. */
    HTTPStatus_t xHTTPStatus = HTTPSuccess;

    configASSERT( pcMethod != NULL );
    configASSERT( pcPath != NULL );

    /* Initialize all HTTP Client library API structs to 0. */
    ( void ) memset( &xRequestInfo, 0, sizeof( xRequestInfo ) );
    ( void ) memset( &xResponse, 0, sizeof( xResponse ) );
    ( void ) memset( &xRequestHeaders, 0, sizeof( xRequestHeaders ) );

    /* Initialize the request object. */

    xRequestInfo.pHost = pHost;
    xRequestInfo.hostLen = strlen(pHost);
    xRequestInfo.pMethod = pcMethod;
    xRequestInfo.methodLen = strlen(pcMethod);
    xRequestInfo.pPath = pcPath;
    xRequestInfo.pathLen = strlen(pcPath);

    /* Set "Connection" HTTP header to "keep-alive" so that multiple requests
     * can be sent over the same established TCP connection. */
    xRequestInfo.reqFlags = HTTP_REQUEST_KEEP_ALIVE_FLAG;

    /* Set the buffer used for storing request headers. */
    xRequestHeaders.pBuffer = ucUserBuffer;
    xRequestHeaders.bufferLen = democonfigUSER_BUFFER_LENGTH;

    xHTTPStatus = HTTPClient_InitializeRequestHeaders( &xRequestHeaders,
                                                       &xRequestInfo );

    if (xHTTPStatus == HTTPSuccess )
    {
        // Add content type to header
        const char* pKey = "Content-Type";
        const char* pValue = "application/json";
        xHTTPStatus = HTTPClient_AddHeader(&xRequestHeaders, pKey, strlen(pKey), pValue, strlen(pValue));
    }

    if( xHTTPStatus == HTTPSuccess )
    {
        /* Initialize the response object. The same buffer used for storing
         * request headers is reused here. */
        xResponse.pBuffer = ucUserBuffer;
        xResponse.bufferLen = democonfigUSER_BUFFER_LENGTH;

        IotLogInfo( ( "Sending HTTP %.*s request to %.*s%.*s...",
                   ( int32_t ) xRequestInfo.methodLen, xRequestInfo.pMethod,
                   ( int32_t ) strlen(pHost), pHost,
                   ( int32_t ) xRequestInfo.pathLen, xRequestInfo.pPath ) );
        IotLogInfo( ( "Request Headers:\n%.*s\n"
                    "Request Body:\n%.*s\n",
                    ( int32_t ) xRequestHeaders.headersLen,
                    ( char * ) xRequestHeaders.pBuffer,
                    ( int32_t ) strlen(pBody), pBody ) );

        /* Send the request and receive the response. */
        xHTTPStatus = HTTPClient_Send( pxTransportInterface,
                                       &xRequestHeaders,
                                       ( uint8_t * ) pBody,
                                       strlen(pBody),
                                       &xResponse,
                                       0 );
    }
    else
    {
        IotLogError( ( "Failed to initialize HTTP request headers: Error=%s.",
                    HTTPClient_strerror( xHTTPStatus ) ) );
    }

    if( xHTTPStatus == HTTPSuccess )
    {
        IotLogInfo( ( "Received HTTP response from %.*s%.*s...\n",
                   ( int32_t ) strlen(pHost), pHost,
                   ( int32_t ) xRequestInfo.pathLen, xRequestInfo.pPath ) );
        IotLogDebug( ( "Response Headers:\n%.*s\n",
                    ( int32_t ) xResponse.headersLen, xResponse.pHeaders ) );
        IotLogDebug( ( "Status Code:\n%u\n",
                    xResponse.statusCode ) );
        IotLogDebug( ( "Response Body:\n%.*s\n",
                    ( int32_t ) xResponse.bodyLen, xResponse.pBody ) );
        memcpy(respBody, xResponse.pBody, xResponse.bodyLen);
        *respCode = xResponse.statusCode;
    }
    else
    {
        IotLogError( ( "Failed to send HTTP %.*s request to %.*s%.*s: Error=%s.",
                    ( int32_t ) xRequestInfo.methodLen, xRequestInfo.pMethod,
                    ( int32_t ) strlen(pHost), pHost,
                    ( int32_t ) xRequestInfo.pathLen, xRequestInfo.pPath,
                    HTTPClient_strerror( xHTTPStatus ) ) );
    }

    if( xHTTPStatus != HTTPSuccess )
    {
        xStatus = pdFAIL;
    }

    return xStatus;
}
aggarg commented 2 years ago

Nothing looks wrong at the first glance. So it may be an issue in the library. Have you resolved the git issue so that I can use your code to repro this issue?

Froopas commented 2 years ago

Here is the repository, https://github.com/Anton-Master-Thesis/pred-main-xmc4700-kit/tree/Ah-Connection.

The file where the HTTP requests are used are https://github.com/Anton-Master-Thesis/pred-main-xmc4700-kit/blob/Ah-Connection/amazon-freertos/vendors/infineon/boards/xmc4700_relaxkit/aws_demos/application_code/Arrowhead/ah_task.c

I am using a xmc4700 board with a extension with a ISM43340 Wifi module.

aggarg commented 2 years ago

Since a lot of your code depends on hardware that I do not have, I took this example and verified that the status code field is getting updated - https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext

Would you please check that you have the latest coreHTTP?

aggarg commented 2 years ago

I was going through your code and realized that you are using a wrapper over coreHTTP. Can you change all these to IOT_LOG_DEBUG and see if you get any clue - https://github.com/Anton-Master-Thesis/pred-main-xmc4700-kit/blob/Ah-Connection/amazon-freertos/vendors/infineon/boards/xmc4700_relaxkit/aws_demos/config_files/iot_config.h#L43

If not, DM me and we can setup a session to debug this together.

aggarg commented 2 years ago

I am closing this issue. Feel free to reopen or create a new issue if you still face any issue.