acl-dev / acl

C/C++ server and network library, including coroutine,redis client,http/https/websocket,mqtt, mysql/postgresql/sqlite client with C/C++ for Linux, Android, iOS, MacOS, Windows, etc..
https://acl-dev.cn
GNU Lesser General Public License v3.0
2.83k stars 937 forks source link

在http fiber下,在handler里面使用http_request的问题。 #319

Closed okman334 closed 8 months ago

okman334 commented 9 months ago

使用wizard生成的http fiber框架,然后在handler处理函数里面使用了 acl::http_request去请求第三方的数据,然后再把请求到的数据回写给客户端。但这时就会出现客户端迟迟收不到数据,直到链接断开时,客户端才会读取到数据。如果不使用 acl::http_request请求数据则是正常的,使用其他http client或者任意返回一些数据给客户端都是ok的。 代码如下:

  service.Get("/test2", [](HttpRequest& req, HttpResponse& res){
        acl::string body;
        acl::http_request client("192.168.1.108:5008", 10, 10);
        acl::http_header& hdr = client.request_header();
        //req.set_ssl(__ssl_conf);

        hdr.set_method(acl::HTTP_METHOD_GET);
        hdr.set_url("/test")
                .set_content_type("text/plain")
                .set_keep_alive(true);

        if (!client.request(NULL, 0))
        {
            printf("send request error\r\n");
            return false;
        }

        if (!client.get_body(body))
        {
            printf("get_body error\r\n");
            return false;
        }

        LOG(WARNING) << "get body : " << body.c_str();
        return res.write(body);
});   

断点看,res.write(body)是已经正常返回了的。会不会fiber下hook的某个系统函数有什么问题。求作者大神或者其他大佬指导一下。

zhengshuxin commented 9 months ago

应该是你没有设置响应的数据长度导致的,可以在调用 res.write(body) 前调用: res.setContentLength(body.size()) ,有两种方式: 方式一:

res.setChunkedTransferEncoding(true);
return res.write(body) && res.write(NULL, 0);

方式二:

res.setContentLength(body.size());
return res.write(body);
okman334 commented 9 months ago

额。还真是这样。眼拙了,我还在write那个地方调了很久,也没发现有什么问题😂,谢谢作者大神。

okman334 commented 9 months ago

现在访问http是ok了。还有一个问题想问问大神。 我使用/acl/lib_fiber/samples/https_client这个例子访问https,出现这个报错,就是读消息头报错了。 openssl_conf.cpp(366), openssl_dll_load: /usr/local/lib/libcrypto.so, /usr/local/lib/libssl.so loaded! OpenSSL loaded, crypto=/usr/local/lib/libcrypto.so, ssl=/usr/local/lib/libssl.socall fiber_schedule http_request.cpp(410), request: read response header error

我又跟踪了好一会,最后发现。如果我在读消息头(http_request.cpp的第405行之前)之前,断点1-2秒,就会正常读出https返回的消息。如果直接跑过去,就会报上面的错误。断点位置在bool http_request::request(const void* data, size_t len)里面,如图。

image

linux和macOS下都有这个问题。麻烦有空帮忙看看😂🌹

zhengshuxin commented 8 months ago

问题修复了,原因是这两个例子中的超时时间设成0导致的,改成10就OK了。超时值为0在之前旧版本acl里表示无限等待,后来的含义变成不等待,所以这两个例子中的超时值为0是不对的。

okman334 commented 8 months ago

好的,谢谢帅气的大神。