から非常に限られた応答を取得し、私は私がどのように、なぜについて見当もつかない、次のような問題に遭遇しました。また、レスポンスをテストするクライアントのサンプルも使用しました。クライアントは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
それは疑わしいです: '' \ r "+ stream.str()+" \ r "'特に、 'std :: to_string(stream.str()。length())'の直後です。あなたが追加した2つの '\ r'文字がコンテンツの長さに占めるべきではないと確信していますか?それは「2」の超過を説明するでしょう。 – spectras
余計なメッセージが消えても、それを削除してもトリックはしません! –
'length'の型は何ですか? '"%。* s "'の幅指定子として非intを使うべきではありません。非関連のヒントでは、 'kpis.end() - 1'の代わりに' std :: prev(kpis.end()) 'を使うことができるので、コンテナ/イテレータの型から独立して、もの。 – jweyrich