客户端只能从REST服务获得非常有限的响应

时间:2017-08-15 11:56:03

标签: c++ rest http curl restbed

我遇到了以下问题,我不知道如何以及为什么:

我用C ++编写了一个web服务。我还为应该测试响应的客户端使用了一个示例。

client.cpp

#include <memory>
#include <future>
#include <cstdio>
#include <cstdlib>
#include <restbed>

using namespace std;
using namespace restbed;

void print( const shared_ptr< Response >& response )
{
    fprintf( stderr, "*** Response ***\n" );
    fprintf( stderr, "Status Code:    %i\n", response->get_status_code( ) );
    fprintf( stderr, "Status Message: %s\n", response->get_status_message( ).data( ) );
    fprintf( stderr, "HTTP Version:   %.1f\n", response->get_version( ) );
    fprintf( stderr, "HTTP Protocol:  %s\n", response->get_protocol( ).data( ) );

    for ( const auto header : response->get_headers( ) )
    {
        fprintf( stderr, "Header '%s' > '%s'\n", header.first.data( ), header.second.data( ) );
    }

    auto length = response->get_header( "Content-Length", 0 );

    Http::fetch( length, response );

    fprintf( stderr, "Body:           %.*s...\n\n", length, response->get_body( ).data( ) );
}

int main( ){
    auto request = make_shared<Request>(
            Uri("http://localhost:3030/apps/17?start_date=2017-02-01&end_date=2017-01-31&kpis=foo,bar"));
    request->set_header("Accept", "application/json");
    request->set_header("Host", "localhost");

    auto response = Http::sync(request);
    print(response);

    auto future = Http::async(request, [](const shared_ptr<Request>, const shared_ptr<Response> response){
        fprintf(stderr, "Printing async response\n");
        print(response);
    });

    future.wait();

    return EXIT_SUCCESS;
}

我的服务以块的形式传输响应(或者应该以块的形式传输响应) 首先,它流式传输请求的参数,例如start_date,end_date和kpis。其次,流式传输所请求的数据。

这是stream_result_parameter函数:

void stream_result_parameter(std::shared_ptr<restbed::Session> session, const Parameter params,
                             const std::string endpoint, const std::string mime_type)
{
    std::stringstream       stream;

    if(mime_type.compare("application/json") == 0)
    {
        std::vector<std::string> kpis = params.get_kpis();
        stream << "\n{\n"
               << "\"result_parameter\":{\n"
               << "\"App\":" << params.get_app_id() << ",\n"
               << "\"start_date\":" << params.get_start_date() << ",\n"
               << "\"end_date\":" << params.get_end_date() << ",\n"
               << "\"Kpis\":[";

        for(std::vector<std::string>::iterator kpi = kpis.begin(); kpi != kpis.end(); ++kpi)
        {
            if(kpi == kpis.end()-1)
            {
                stream << *kpi << "]\n},";
            }
            else
            {
                stream << *kpi << ",";
            }

        }

    }
    else
    {
        if(endpoint.compare("app") == 0 )
        {
            stream << "Called App Endpoint App: "
                   << std::to_string(params.get_app_id())
                   << "\r\nStart Date: "
                   << params.get_start_date()
                   << "\r\nEnd Date: "
                   << params.get_end_date()
                   <<"\n";

        }
        else
        {
            stream << "Called Cohorts Endpoint App: "
                   << std::to_string(params.get_app_id())
                   << "\r\nStart Date: "
                   << params.get_start_date()
                   << "\r\nEnd Date: "
                   << params.get_end_date()
                   <<"\n";

        }
    }
    session->yield(200, "\r"+stream.str()+"\r",
                   { { "Content-Length", std::to_string( stream.str().length())},
                     { "Content-Type", mime_type },
                     { "Connection", "keep-alive" } });
}     

现在,在我将Content-Length添加到它之后,我的问题就出现了,它只是停止并关闭客户端和他(服务)之间的对话。 curl给了我以下错误

*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3030 (#0)
> GET /apps/17?start_date=2017-02-01&end_date=2017-01-31&kpis=foo,bar HTTP/1.1
> Host: localhost:3030
> User-Agent: curl/7.54.0
> Accept:text/csv
> 
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Length: 94
< Content-Type: text/csv
< 
* Excess found in a non pipelined read: excess = 2, size = 94, maxdownload = 94, bytecount = 0
Called App Endpoint App: 17
Start Date: Wed. February 1 2017
* Connection #0 to host localhost left intact
End Date: Tue. January 31 2017

多余的东西与它有关吗?

最后,如果我将内容长度带走,我想向我展示测试客户端和curl的输出。

client.cpp输出:

*** Response ***
Status Code:    200
Status Message: OK
HTTP Version:   1.1
HTTP Protocol:  HTTP
Header 'Connection' > 'keep-alive'
Header 'Content-Type' > 'application/json'
Body:           ...

Printing async response
*** Response ***
Status Code:    200
Status Message: OK
HTTP Version:   1.1
HTTP Protocol:  HTTP
Header 'Connection' > 'keep-alive'
Header 'Content-Length' > '64'
Header 'Content-Type' > 'application/json'
Body:           
"result_set":{
"i":1,
"j values": [
{"j":1,"kpi_values":[1,1]}...

但是curl给了我所需要的一切:

*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3030 (#0)
> GET /apps/17?start_date=2017-02-01&end_date=2017-01-31&kpis=foo,bar HTTP/1.1
> Host: localhost:3030
> User-Agent: curl/7.54.0
> Accept:text/csv
> 
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Type: text/csv
* no chunk, no close, no size. Assume close to signal end
< 
Called App Endpoint App: 17
Start Date: Wed. February 1 2017
End Date: Tue. January 31 2017
1,1,1,1
1,2,1,2
1,3,1,3
1,4,1,4
1,5,1,0
1,6,1,1
1,7,1,2
1,8,1,3
1,9,1,4
1,10,1,0
2,1,2,1
2,2,2,2
2,3,2,3
2,4,2,4
2,5,2,0
2,6,2,1
2,7,2,2
2,8,2,3
2,9,2,4
2,10,2,0

(请注意我不想复制17400行,因此它只是完整合法输出的一部分)

也许我违反了一些规则或遗漏了别的东西,但我无法想到它。提前致谢

更新:

一旦我考虑了"/r" s,但是过多的消息消失了,但仍然发送了响应,并且不再有任何块可以跟随:

*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3030 (#0)
> GET /apps/17?start_date=2017-02-01&end_date=2017-01-31&kpis=foo,bar HTTP/1.1
> Host: localhost:3030
> User-Agent: curl/7.54.0
> Accept:text/csv
> 
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Length: 96
< Content-Type: text/csv
< 
Called App Endpoint App: 17
Start Date: Wed. February 1 2017
End Date: Tue. January 31 2017
* Connection #0 to host localhost left intact

1 个答案:

答案 0 :(得分:0)

收到回复后,您的申请将会结束。

auto future = Http::async(request, [](const shared_ptr<Request>, const shared_ptr<Response> response){
    fprintf(stderr, "Printing async response\n");
    print(response);
});

future.wait();

请参阅github issue了解最终结果。