2016-08-28 6 views
0

私のC++アプリケーションではHTTPサーバーが必要で、自分自身で作成することにしました.HTTP取得要求を送信するときには正常に動作しますが、HTTP POST要求を読み取るときには、HTTP POST要求を読み取るためのHTTPサーバーの昇格

問題は、HTTP投稿要求を送信すると、最後のヘッダーが正しく読み取られないため、投稿要求を取得できないということです。

これは私のコードです:

void HttpSession::readHeaders(std::shared_ptr<HttpSession> pThis) { 
    boost::asio::async_read_until(pThis->socket_, pThis->buff_, '\r\n\r\n', 
           [pThis](const boost::system::error_code &e, std::size_t s) { 
     std::istream headersStream(&pThis->buff_); 
     std::string header; 
     while(std::getline(headersStream, header, '\n')) { 
      if(header != "\r") { 
       if(header.back() == '\r') header = header.substr(0, header.length() - 1); 
       qDebug() << QString::fromStdString(header); 
       //Some stuff to get content-length to contentLength_ 
     } 
    } 

    if(contentLength_ > 0) { 
     qDebug() << "Reading:"; 
     readBody(pThis); 
    } 

    std::shared_ptr<std::string> str = std::make_shared<std::string>(pThis->headers_.getResponse()); 
    boost::asio::async_write(pThis->socket_, boost::asio::buffer(str->c_str(), str->length()), 
          [pThis, str](const boost::system::error_code &e, std::size_t s) { 
     qDebug() << "Written"; 
    }); 
} 

void HttpSession::readBody(std::shared_ptr<HttpSession> pThis) { 
    boost::asio::async_read(pThis->socket_, pThis->data_, boost::asio::transfer_at_least(1), 
           [pThis](const boost::system::error_code &e, std::size_t s) { 
     std::istream body(&pThis->data_); 
     std::string line; 
     body >> line; 
     qDebug() << QString::fromStdString(line); 
    }); 
} 

buff_data_変数は次のように宣言されますboost::asio::streambufHttpSessionクラスは、ヘッダーを格納し、すべてのウェブページを処理するクラスです。そのクラスのコードは問題ではないので、私はそのクラスのコードを含めなかった。

HTTP POSTリクエストに/ URLの出力はこの1つである:

"POST /url HTTP/1.1" 
"Host: 192.168.1.41:8080" 
"Connection: keep-alive" 
"Content-Length: 10" 
"Cache-Control: max-age=0" 
"Origin: http://192.168.1.41:8080" 
"Upgrade-Insecure-Requests: 1" 
"User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36" 
"Content-Type: application/x-www-form-urlencoded" 
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" 
"Referer: http://192.168.1.41:8080/" 
"Accept-Encoding: gzip, deflate" 
"Accept-Langua" 
Reading: 
"ge:" 

あなたが見ることができるように、たAccept-Languageヘッダは、この画像では、あなたがそのPOSTを見ることができますが、正しく読んではありません要求は適切に行われます。 this

GETリクエストを送信すると、すべて正常に動作することに注意してください。ですから、私は、async_read_untilがブロックしないので、非同期的に読み込むことと何か関係がありますので、readBodyasync_read関数は、読み込む前に読み込みます。私は同期して読みますか?クライアントごとに1つのHttpSessionクラスを作成すると、複数のクライアントをどちらの方法でも処理できますか? (私は本当に複数のユーザーをサポートする必要はありませんが、それでもいいです)。このような私は、クライアントの扱いについて

void HttpServer::run() { 
    using namespace boost::asio; 
    io_service io_service; 
    ip::tcp::endpoint endpoint{ip::tcp::v4(), 8080}; 
    ip::tcp::acceptor acceptor{io_service, endpoint}; 
    acceptor.listen(); 
    runServer(acceptor, io_service); 

    io_service.run(); 

    while(true) QThread::msleep(5000); 
} 

void HttpServer::runServer(boost::asio::ip::tcp::acceptor& acceptor, boost::asio::io_service& io_service) { 
    std::shared_ptr<HttpSession> ses = std::make_shared<HttpSession>(io_service); 
    acceptor.async_accept(ses->socket_, 
    [ses, &acceptor, &io_service](const boost::system::error_code& accept_error) { 
     runServer(acceptor, io_service); 
     if(!accept_error) HttpSession::interact(ses); 
    }); 
} 

ヘルプのすべての種類が認識されるであろう!コードの改善があれば、教えてください。ありがとう!

+0

私自身の学習のために、あなたのコードをすべて見ることができますか?私は似たようなことをやろうとしています。参照してください:http://stackoverflow.com/questions/41254225 –

答えて

1

問題は'\r\n\r\n'と思います。これは文字列ではなく、charです。

warning: implicit conversion from 'int' to 'char' changes value from 218762506 to 10 [-Wconstant-conversion] 

"\r\n\r\n"であることを交換してみてください:

コンパイラは、通常のようなもので、これについて警告すべきです。

+0

私は家に帰るとき、それを試してみます、ありがとう。しかし、とにかく、GETリクエストで動作するのは奇妙ではないのですか? – lpares12

+0

私は今問題を理解しています、ありがとう。コンパイラは私に警告しませんでした。多分qtコンパイラと関係があります。 – lpares12

関連する問題