c++ - Client only gets very limited response from REST service -
i ran following problem have no clue how , why:
i have written webservice in c++. have used example client should test response.
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( ) ); ( 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; } and service streams response in chunks (or supposed stream response in chunks) first, streams parameters of request such start_date, end_date , kpis. second, requested data streamed.
here stream_result_parameter function:
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" } }); } now, problem occured after added content-length stops , closes conversation between client , him(the service). curl gives me following error
* trying ::1... * tcp_nodelay set * connected localhost (::1) port 3030 (#0) > /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 non pipelined read: excess = 2, size = 94, maxdownload = 94, bytecount = 0 called app endpoint app: 17 start date: wed. february 1 2017 * connection #0 host localhost left intact end date: tue. january 31 2017 does excess have it?
lastly, want show output test client , curl if take content-length away.
client.cpp output:
*** 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]}... but curl gives me need:
* trying ::1... * tcp_nodelay set * connected localhost (::1) port 3030 (#0) > /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 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 (please note did not want copy 17400 lines part of complete , rightful output)
maybe violating rule or missing else can't think of it. in advance
update:
the excess message gone once accounted "/r"s still response sent , no more chunks can follow:
* trying ::1... * tcp_nodelay set * connected localhost (::1) port 3030 (#0) > /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 host localhost left intact
once response received application end.
auto future = http::async(request, [](const shared_ptr<request>, const shared_ptr<response> response){ fprintf(stderr, "printing async response\n"); print(response); }); future.wait(); please see github issue final result.
Comments
Post a Comment