VincentDM
VincentDM

Reputation: 489

boost::asio http server unable to return valid response to Postman

I'm trying to do a minimal server answering to http requests. I think it partially works since the session is disconnected when I'm sending an answer, but when I'm using a tool like Postman, I'm getting a message like "Could not get any response".

Not knowing much about network yet, I guess I'm just probably unaware of some http concepts :)

Here's the code I'm using:

#define _SECURE_SCL 0
#include <boost/asio.hpp>
#include <iostream>
using namespace std;
using namespace boost::asio;
using namespace boost::asio::ip;

//
// TCP Session
//
class TcpSession : public enable_shared_from_this<TcpSession>
{
  uint8_t      mData[4096];
  tcp::socket  mSocket;  
  unsigned int mTcpSessionId;

public:
  TcpSession(tcp::socket && iSocket, unsigned int && iTcpAudioSessionId) 
  : mSocket(move(iSocket)),
    mTcpSessionId(iTcpAudioSessionId) 
  {}

  ~TcpSession() {}

  void start() {
    doRead();
  }

private:

  void doRead() {
    shared_ptr<TcpSession> self(shared_from_this());

    mSocket.async_read_some( buffer(mData, 4096),
      [this, self](boost::system::error_code ec, size_t iBytesReceived)
    {
      if(ec) {
        cout << "Session error : " << ec.value() << " " << ec.message() << endl;
        return;
      }

      if (iBytesReceived > 0) {
        cout << string(reinterpret_cast<char*>(mData), iBytesReceived) << endl;
        mSocket.send(buffer("HTTP / 1.1 200 OK\r\n\r\n"));
      }

      doRead();
    });
  }

}; // end of TcpSession


//
// TCP Server
//
class TcpServer
{
  tcp::acceptor mAcceptor;
  tcp::socket   mSocket;
  unsigned int  mTcpSessionCount;

public:
  TcpServer(io_service& iService, const short iPort) :
    mAcceptor(iService, tcp::endpoint(tcp::v4(), iPort)),
    mSocket(iService),
    mTcpSessionCount(0) {
    mAcceptor.set_option(tcp::acceptor::reuse_address());
    accept();
  }

private:
  void accept() {
    mAcceptor.async_accept(mSocket, [this](boost::system::error_code ec) {
      if(!ec) {
        make_shared<TcpSession>(move(mSocket), mTcpSessionCount++)->start();
      }
      else {
        cout << "Server error message " << ec.message() << endl;
      }

      accept();
    });
  }
}; // end of TcpServer


int main() {
  io_service ioService;
  TcpServer mTcpServer(ioService, 2112);
  ioService.run();
}

Upvotes: 0

Views: 230

Answers (1)

kenba
kenba

Reputation: 4549

Your HTTP response:

"HTTP / 1.1 200 OK\r\n\r\n"

is badly formed as there should not be any spaces between HTTP, / and 1.1. Also, since you are replying with 200 OK response, the response should contain a content-length field of zero, i.e.:

"HTTP/1.1 200 OK\r\ncontent-length: 0\r\n\r\n"

or you could simply send 204 No Content instead, i.e.:

"HTTP/1.1 204 No Content\r\n\r\n"

For more awareness of http concepts see: RFC7230 Message Format and RFC7231 204 No Content.

Upvotes: 1

Related Questions