2017-08-15 7 views
0

から非常に限られた応答を取得し、私は私がどのように、なぜについて見当もつかない、次のような問題に遭遇しました。また、レスポンスをテストするクライアントのサンプルも使用しました。クライアントはRESTサービス

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とのKPIとしてリクエストのパラメータをストリーム。第2に、要求されたデータがストリーミングされる。

ここ

が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" } }); 
}  

、私の問題が発生しました。 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行をコピーしたくなかったのでご注意くださいので、完全にその一部だけと正当な出力)

多分私はいくつかのルールに違反しているか、何か他のものを見逃していますが、私はそれについて考えることはできません。事前のおかげで

UPDATE:

私は "/r"秒を占めたが、それでも応答が送信され、これ以上チャンクが続かないことができたら、余分なメッセージがなくなっている

* 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

それは疑わしいです: '' \ r "+ stream.str()+" \ r "'特に、 'std :: to_string(stream.str()。length())'の直後です。あなたが追加した2つの '\ r'文字がコンテンツの長さに占めるべきではないと確信していますか?それは「2」の超過を説明するでしょう。 – spectras

+0

余計なメッセージが消えても、それを削除してもトリックはしません! –

+0

'length'の型は何ですか? '"%。* s "'の幅指定子として非intを使うべきではありません。非関連のヒントでは、 'kpis.end() - 1'の代わりに' std :: prev(kpis.end()) 'を使うことができるので、コンテナ/イテレータの型から独立して、もの。 – jweyrich

答えて

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を参照してください。

+0

さて、私が投稿した更新を見てください。これはcurlで、あなたのclient.cppではありません。 私はセッションを閉じたくはありません。ちょうどsession-> yieldを使ってhttp応答。 –

+0

はい、HTTP応答をストリーミングするために使用できます。商業環境でも広く使用されています。 – Corvusoft

+0

申し訳ありませんが、あなたはクライアント側からストリーミングできますか? – Corvusoft