static int construct_http_headers()

in src/uhttp.c [858:987]


static int construct_http_headers(HTTP_HEADERS_HANDLE http_header, size_t content_len, STRING_HANDLE buffData, bool chunk_data, const char* hostname, int port_num)
{
    (void)chunk_data;
    int result = 0;
    size_t headerCnt = 0;
    if ( (http_header != NULL) && HTTPHeaders_GetHeaderCount(http_header, &headerCnt) != HTTP_HEADERS_OK)
    {
        LogError("Failed in HTTPHeaders_GetHeaderCount");
        result = MU_FAILURE;
    }
    else
    {
        bool hostname_found = false;
        for (size_t index = 0; index < headerCnt && result == 0; index++)
        {
            char* header;
            if (HTTPHeaders_GetHeader(http_header, index, &header) != HTTP_HEADERS_OK)
            {
                result = MU_FAILURE;
                LogError("Failed in HTTPHeaders_GetHeader");
            }
            else
            {
                size_t dataLen = safe_add_size_t(strlen(header), 2);
                size_t malloc_size = safe_add_size_t(dataLen, 1);

                char* sendData;
                if (malloc_size == SIZE_MAX ||
                    (sendData = malloc(malloc_size)) == NULL)
                {
                    result = MU_FAILURE;
                    LogError("Failed in allocating header data, size:%zu", malloc_size);
                }
                else
                {
                    if (strcmp(header, HTTP_HOST) == 0)
                    {
                        hostname_found = true;
                    }

                    if (snprintf(sendData, malloc_size, "%s\r\n", header) <= 0)
                    {
                        result = MU_FAILURE;
                        LogError("Failed in constructing header data");
                    }
                    else
                    {
                        if (STRING_concat(buffData, sendData) != 0)
                        {
                            result = MU_FAILURE;
                            LogError("Failed in building header data");
                        }
                    }
                    free(sendData);
                }
                free(header);
            }
        }
        if (!hostname_found)
        {
            // calculate the size of the host header
            size_t host_len = safe_add_size_t(strlen(HTTP_HOST), strlen(hostname));
            host_len = safe_add_size_t(host_len, MAX_CONTENT_LENGTH);
            host_len = safe_add_size_t(host_len, 2);

            size_t malloc_size = safe_add_size_t(host_len, 1);
            char* host_header;
            if (malloc_size == SIZE_MAX ||
                (host_header = malloc(malloc_size)) == NULL)
            {
                LogError("Failed allocating host header, size:%zu", malloc_size);
                result = MU_FAILURE;
            }
            else
            {
                if (snprintf(host_header, malloc_size, "%s: %s:%d\r\n", HTTP_HOST, hostname, port_num) <= 0)
                {
                    LogError("Failed constructing host header");
                    result = MU_FAILURE;
                }
                else if (STRING_concat(buffData, host_header) != 0)
                {
                    LogError("Failed adding the host header to the http item");
                    result = MU_FAILURE;
                }
                free(host_header);
            }
        }

        if (result == 0)
        {
            /* Codes_SRS_UHTTP_07_015: [uhttp_client_execute_request shall add the Content-Length to the request if the contentLength is > 0] */
            size_t fmtLen = safe_add_size_t(strlen(HTTP_CONTENT_LEN), HTTP_CRLF_LEN);
            fmtLen = safe_add_size_t(fmtLen, 25);

            size_t malloc_size = safe_add_size_t(fmtLen, 1);
            char* content;
            if ((content = malloc(malloc_size)) == NULL)
            {
                LogError("Failed allocating chunk header, size:%zu", malloc_size);
                result = MU_FAILURE;
            }
            else
            {
                /* Codes_SRS_UHTTP_07_015: [on_bytes_received shall add the Content-Length http header item to the request.] */
                if (sprintf(content, "%s: %u%s", HTTP_CONTENT_LEN, (unsigned int)content_len, HTTP_CRLF_VALUE) <= 0)
                {
                    result = MU_FAILURE;
                    LogError("Failed allocating content len header data");
                }
                else
                {
                    if (STRING_concat(buffData, content) != 0)
                    {
                        result = MU_FAILURE;
                        LogError("Failed building content len header data");
                    }
                }
                free(content);
            }

            if (STRING_concat(buffData, "\r\n") != 0)
            {
                result = MU_FAILURE;
                LogError("Failed sending header finalization data");
            }
        }
    }
    return result;
}