http_req处理源码

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kongshuai19900505/article/details/84135408

目录

 

1 接口总览

2 构造对象

3 析构对象

4 设置报文头

5 发送请求


1 接口总览

http_req是请求处理相关代码,这里面一共包含4个接口,即构造对象、释放资源、设置报文头以及发送请求

http_req *http_req_new(void);
void http_req_destroy(http_req *a_req);
int http_req_prepare(http_req *a_req);
int http_req_send(http_req *a_req, http_trans_conn *a_conn);

2 构造对象

http_req_new构造一个请求资源对象,具体内容可以参考前文的http_req结构体内容

/*
 * 返回值:分配好资源的http_req内容
 */
http_req *
http_req_new(void)
{
    http_req *l_return = NULL;

    l_return = (http_req *)malloc(sizeof(http_req));
    memset(l_return, 0, sizeof(http_req));
    /* 默认1.1版本 */
    l_return->http_ver = 1.1;
    l_return->headers = http_hdr_list_new();
    return l_return;
}

3 析构对象

当分配的资源使用完毕需要释放资源,则使用http_req_destroy接口

/*
 * 输入参数:http_req_new分配的http_req资源
 */
void
http_req_destroy(http_req *a_req)
{
    if (!a_req)
        return;
    if (a_req->headers)
        http_hdr_list_destroy(a_req->headers);
    free(a_req);
}

4 设置报文头

主要设置的是host信息,如果是post、put或者trace请求的话则设置Content-Length字段,如果没有设置代理的话则还需要设置User-Agent字段

/*
 * 输入参数:http_req,请求资源
 * 输出参数:http_req,http_req对象资源
 * 返回值: 0-成功 -1-失败
 */
int
http_req_prepare(http_req *a_req)
{
    int l_return = 0;
    char l_buf[30];

    if (!a_req)
        return -1;
    memset(l_buf, 0, 30);
    /* 设置请求域名或者host信息 */
    http_hdr_set_value(a_req->headers,http_hdr_Host,a_req->host);
    /* 监测报文是否带有报文体 */
    if ((a_req->type == http_req_type_post) ||
        (a_req->type == http_req_type_put) ||
        (a_req->type == http_req_type_trace))
    {
        sprintf(l_buf, "%d", a_req->body_len);
        http_hdr_set_value(a_req->headers,http_hdr_Content_Length,l_buf);
    }
    /* 如果未设置用户代理,则设置默认值 */
    if (http_hdr_get_value(a_req->headers, http_hdr_User_Agent) == NULL)
        http_hdr_set_value(a_req->headers, http_hdr_User_Agent,"libghttp/1.0");
    return l_return;
}

5 发送请求

在该接口内如果是异步处理的话则直接跳转到操作位置,将数据打包发送,如果是同步则按照既定步骤一步步的将数据处理发送。

/*
 * 输入参数:http_req,请求资源
 * 输入参数:a_conn,网络资源
 * 返回值: HTTP_TRANS_ERR 发送错误,HTTP_TRANS_NOT_DONE 没有传送结束,HTTP_TRANS_DONE 传送结束
 */
int
http_req_send(http_req *a_req, http_trans_conn *a_conn)
{
    char       *l_request = NULL;
    int         l_request_len = 0;
    int         i = 0;
    int         l_len = 0;
    int         l_headers_len = 0;
    int         l_rv = 0;
    char       *l_content = NULL;

    /* 如果是异步发送则直接跳转到操作位置 */
    if (a_conn->sync == HTTP_TRANS_ASYNC)
    {
        if (a_req->state == http_req_state_sending_request)
            goto http_req_state_sending_request_jump;
        if (a_req->state == http_req_state_sending_headers)
            goto http_req_state_sending_headers_jump;
        if (a_req->state == http_req_state_sending_body)
        goto http_req_state_sending_body_jump;
    }
    /* 分配足够的空间存储header首行 */
    l_request = malloc(30 + strlen(a_req->resource) + (a_conn->proxy_host ? (strlen(a_req->host) + 20) : 0));
    memset(l_request, 0, 30 + strlen(a_req->resource) + (a_conn->proxy_host ? (strlen(a_req->host) + 20) : 0));
    /* copy it into the buffer */
    if (a_conn->proxy_host)
    {
        l_request_len = sprintf(l_request,"%s %s HTTP/%01.1f\r\n",http_req_type_char[a_req->type],a_req->full_uri,a_req->http_ver);
    }
    else
    {
        l_request_len = sprintf(l_request,"%s %s HTTP/%01.1f\r\n",http_req_type_char[a_req->type],a_req->resource,a_req->http_ver);
    }
    printf("request:%s\n",l_request);
    /* 将请求header首行放到发送缓冲区*/
    http_trans_append_data_to_buf(a_conn, l_request, l_request_len);
    /* free up the request - we don't need it anymore */
    free(l_request);
    l_request = NULL;
    /* 设置状态 */
    a_req->state = http_req_state_sending_request;
http_req_state_sending_request_jump:
    /* 发送请求 */
    do {
        l_rv = http_trans_write_buf(a_conn);
        if ((a_conn->sync == HTTP_TRANS_ASYNC) && (l_rv == HTTP_TRANS_NOT_DONE))
            return HTTP_TRANS_NOT_DONE;
        if ((l_rv == HTTP_TRANS_DONE) && (a_conn->last_read == 0))
            return HTTP_TRANS_ERR;
    } while (l_rv == HTTP_TRANS_NOT_DONE);
    /* 重置缓冲区 */
    http_trans_buf_reset(a_conn);
    /* 将header里面的所有内容放到发送缓冲区 */
    for (i = 0; i < HTTP_HDRS_MAX; i++)
    {
        l_len = 0;
        if (a_req->headers->header[i])
        {
            l_len = strlen(a_req->headers->header[i]);
            if (l_len > 0)
            {
                http_trans_append_data_to_buf(a_conn, a_req->headers->header[i], l_len);
                l_headers_len += l_len;
                http_trans_append_data_to_buf(a_conn, ": ", 2);
                l_headers_len += 2;
                /* note, it's ok to have no value for a request */
                if ((l_len = strlen(a_req->headers->value[i])) > 0)
                {
                    http_trans_append_data_to_buf(a_conn, a_req->headers->value[i], l_len);
                    l_headers_len += l_len;
                }
                http_trans_append_data_to_buf(a_conn, "\r\n", 2);
                l_headers_len += 2;
            }
        }
    }
    http_trans_append_data_to_buf(a_conn, "\r\n", 2);
    l_headers_len += 2;
    /* set the state */
    a_req->state = http_req_state_sending_headers;
http_req_state_sending_headers_jump:
    /* 发送报文头 */
    do {
        l_rv = http_trans_write_buf(a_conn);
        if ((a_conn->sync == HTTP_TRANS_ASYNC) && (l_rv == HTTP_TRANS_NOT_DONE))
            return HTTP_TRANS_NOT_DONE;
        if ((l_rv == HTTP_TRANS_DONE) && (a_conn->last_read == 0))
            return HTTP_TRANS_ERR;
    } while (l_rv == HTTP_TRANS_NOT_DONE);
    /* reset the buffer */
    http_trans_buf_reset(a_conn);
    l_content = http_hdr_get_value(a_req->headers, http_hdr_Content_Length);
    if (l_content)
    {
        /* 将请求报文体放到发送缓冲区 */
        http_trans_append_data_to_buf(a_conn, a_req->body, a_req->body_len);
        a_req->state = http_req_state_sending_body;
    http_req_state_sending_body_jump:
        do {
            l_rv = http_trans_write_buf(a_conn);
            if ((a_conn->sync == HTTP_TRANS_ASYNC) && (l_rv == HTTP_TRANS_NOT_DONE))
                return HTTP_TRANS_NOT_DONE;
            if ((l_rv == HTTP_TRANS_DONE) && (a_conn->last_read == 0))
                return HTTP_TRANS_ERR;
        } while (l_rv == HTTP_TRANS_NOT_DONE);
        /* reset the buffer */
        http_trans_buf_reset(a_conn);
    }
    return HTTP_TRANS_DONE;
}

猜你喜欢

转载自blog.csdn.net/kongshuai19900505/article/details/84135408
今日推荐