HTTP_CLIENT_RESULT uhttp_client_execute_request()

in src/uhttp.c [1286:1422]


HTTP_CLIENT_RESULT uhttp_client_execute_request(HTTP_CLIENT_HANDLE handle, HTTP_CLIENT_REQUEST_TYPE request_type, const char* relative_path,
    HTTP_HEADERS_HANDLE http_header_handle, const unsigned char* content, size_t content_len, ON_HTTP_REQUEST_CALLBACK on_request_callback, void* callback_ctx)
{
    HTTP_CLIENT_RESULT result;
    LIST_ITEM_HANDLE list_item;

    /* Codes_SRS_UHTTP_07_012: [If handle, relativePath, or httpHeadersHandle is NULL then http_client_execute_request shall return HTTP_CLIENT_INVALID_ARG] */
    if (handle == NULL || on_request_callback == NULL ||
        (content != NULL && content_len == 0) || (content == NULL && content_len != 0) )
    {
        result = HTTP_CLIENT_INVALID_ARG;
        LogError("Invalid parameter sent to execute_request");
    }
    else
    {
        HTTP_CLIENT_HANDLE_DATA* http_data = (HTTP_CLIENT_HANDLE_DATA*)handle;

        http_data->recv_msg.on_request_callback = on_request_callback;
        http_data->recv_msg.user_ctx = callback_ctx;
        if (setup_init_recv_msg(&http_data->recv_msg) != 0)
        {
            /* Codes_SRS_UHTTP_07_017: [If any failure encountered http_client_execute_request shall return HTTP_CLIENT_ERROR] */
            LogError("Failure allocating http http_data items");
            result = HTTP_CLIENT_ERROR;
        }
        else
        {
            HTTP_SEND_DATA* send_data = (HTTP_SEND_DATA*)malloc(sizeof(HTTP_SEND_DATA));
            if (send_data == NULL)
            {
                LogError("Failure allocating http data items");
                BUFFER_delete(http_data->recv_msg.msg_body);
                http_data->recv_msg.msg_body = NULL;
                HTTPHeaders_Free(http_data->recv_msg.resp_header);
                http_data->recv_msg.resp_header = NULL;
                result = HTTP_CLIENT_ERROR;
            }
            else
            {
                memset(send_data, 0, sizeof(HTTP_SEND_DATA));
                /* Codes_SRS_UHTTP_07_041: [HTTP_CLIENT_REQUEST_TYPE shall support all request types specified under section 9.1.2 in the spec.] */
                send_data->request_type = request_type;
                if ( (content_len > 0) && (send_data->content = BUFFER_create(content, content_len)) == NULL)
                {
                    LogError("Failure allocating content buffer");
                    result = HTTP_CLIENT_ERROR;
                    BUFFER_delete(http_data->recv_msg.msg_body);
                    http_data->recv_msg.msg_body = NULL;
                    HTTPHeaders_Free(http_data->recv_msg.resp_header);
                    http_data->recv_msg.resp_header = NULL;
                    free(send_data);
                }
                else if ((send_data->header_line = STRING_new()) == NULL)
                {
                    LogError("Failure allocating content buffer");
                    result = HTTP_CLIENT_ERROR;
                    BUFFER_delete(send_data->content);
                    BUFFER_delete(http_data->recv_msg.msg_body);
                    http_data->recv_msg.msg_body = NULL;
                    HTTPHeaders_Free(http_data->recv_msg.resp_header);
                    http_data->recv_msg.resp_header = NULL;
                    free(send_data);
                }
                else if (construct_http_headers(http_header_handle, content_len, send_data->header_line, false, http_data->host_name, http_data->port_num))
                {
                    LogError("Failure allocating content buffer");
                    result = HTTP_CLIENT_ERROR;
                    BUFFER_delete(send_data->content);
                    STRING_delete(send_data->header_line);
                    BUFFER_delete(http_data->recv_msg.msg_body);
                    http_data->recv_msg.msg_body = NULL;
                    HTTPHeaders_Free(http_data->recv_msg.resp_header);
                    http_data->recv_msg.resp_header = NULL;
                    free(send_data);
                }
                else if ((list_item = singlylinkedlist_add(http_data->data_list, send_data)) == NULL)
                {
                    STRING_delete(send_data->header_line);
                    BUFFER_delete(send_data->content);
                    LogError("Failure adding send data to list");
                    result = HTTP_CLIENT_ERROR;
                    BUFFER_delete(http_data->recv_msg.msg_body);
                    http_data->recv_msg.msg_body = NULL;
                    HTTPHeaders_Free(http_data->recv_msg.resp_header);
                    http_data->recv_msg.resp_header = NULL;
                    free(send_data);
                }
                else
                {
                    if (relative_path != NULL)
                    {
                        if ((send_data->relative_path = STRING_construct(relative_path)) == NULL)
                        {
                            (void)singlylinkedlist_remove(http_data->data_list, list_item);
                            STRING_delete(send_data->header_line);
                            BUFFER_delete(send_data->content);
                            LogError("Failure allocating relative path buffer");
                            BUFFER_delete(http_data->recv_msg.msg_body);
                            http_data->recv_msg.msg_body = NULL;
                            HTTPHeaders_Free(http_data->recv_msg.resp_header);
                            http_data->recv_msg.resp_header = NULL;
                            free(send_data);
                            result = HTTP_CLIENT_ERROR;
                        }
                        else
                        {
                            /* Codes_SRS_UHTTP_07_018: [upon success http_client_execute_request shall return HTTP_CLIENT_OK.] */
                            result = HTTP_CLIENT_OK;
                        }
                    }
                    else
                    {
                        if ((send_data->relative_path = STRING_construct("/")) == NULL)
                        {
                            (void)singlylinkedlist_remove(http_data->data_list, list_item);
                            STRING_delete(send_data->header_line);
                            BUFFER_delete(send_data->content);
                            LogError("Failure allocating relative path buffer");
                            BUFFER_delete(http_data->recv_msg.msg_body);
                            http_data->recv_msg.msg_body = NULL;
                            HTTPHeaders_Free(http_data->recv_msg.resp_header);
                            http_data->recv_msg.resp_header = NULL;
                            free(send_data);
                            result = HTTP_CLIENT_ERROR;
                        }
                        else
                        {
                            /* Codes_SRS_UHTTP_07_018: [upon success http_client_execute_request shall return HTTP_CLIENT_OK.] */
                            result = HTTP_CLIENT_OK;
                        }
                    }
                }
            }
        }
    }
    return result;
}