Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

共用一个TCP连接,发送Content-Length为0的PUT请求和其他请求时,PUT的后一个请求无法正常处理 #66

Open
rainzm opened this issue Jan 10, 2019 · 0 comments

Comments

@rainzm
Copy link

rainzm commented Jan 10, 2019

aliyun-oss-c-sdk版本:3.6.0
libcurl版本:7.63.0
问题:当我用aos_http_io_initialize()初始化网络和其他资源后,先后发起一个Content-Length为0的PUT请求(比如设置bucket的ACL)和一个GET请求,毋庸置疑,这两个HTTP请求会共用同一条TCP连接。发送第一个PUT请求时,虽然设置了”Content-Length:0“,并没有主动设置“Transfer-Encoding:chunked”(我查阅了代码),但是在发送的包里还是发现了“Transfer-Encoding:chunked”这个header,这导致服务器端忽略了Content-length,从而不能正确区分两个HTTP请求的边界,导致第二个请求失败。(当PUT请求的Content-length不为0时(比如分块上传),并没有发现“Transfer-Encoding”header)。

解决:我查阅了libcurl官方文档,发现对于“Transfer-Encoding”有这样的描述:

Enforcing chunked transfer-encoding
By making sure a request uses the custom header "Transfer-Encoding: chunked" when doing a non-GET HTTP operation, libcurl will switch over to "chunked" upload, even though the size of the data to upload might be known. By default, libcurl usually switches over to chunked upload automatically if the upload data size is unknown.

对于PUT请求,有这样的描述:

A parameter set to 1 tells the library to use HTTP PUT to transfer data. The data should be set with CURLOPT_READDATA and CURLOPT_INFILESIZE.

因此我在aos_transport.c的aos_curl_transport_setup()函数中添加了一句:

switch (t->req->method) {
        case HTTP_HEAD:
            curl_easy_setopt_safe(CURLOPT_NOBODY, 1);
            break;
        case HTTP_PUT:
            curl_easy_setopt_safe(CURLOPT_UPLOAD, 1);
            /* modify here */
            curl_easy_setopt_safe(CURLOPT_INFILESIZE, t->req->body_len);
            break;
        case HTTP_POST:
            curl_easy_setopt_safe(CURLOPT_POST, 1);
            break;
        case HTTP_DELETE:
            curl_easy_setopt_safe(CURLOPT_CUSTOMREQUEST, "DELETE");
            break;
        default: // HTTP_GET
            break;
    }

现在它正常工作了,我觉得需要报告一下。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant