connection.cc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <asiolink/asio_wrapper.h>
  7. #include <http/connection.h>
  8. #include <http/connection_pool.h>
  9. #include <boost/bind.hpp>
  10. #include <iostream>
  11. using namespace isc::asiolink;
  12. namespace isc {
  13. namespace http {
  14. void
  15. HttpConnection::
  16. SocketCallback::operator()(boost::system::error_code ec, size_t length) {
  17. callback_(ec, length);
  18. }
  19. HttpConnection:: HttpConnection(asiolink::IOService& io_service,
  20. HttpAcceptor& acceptor,
  21. HttpConnectionPool& connection_pool,
  22. const HttpResponseCreatorPtr& response_creator,
  23. const HttpAcceptorCallback& callback)
  24. : socket_(io_service),
  25. socket_callback_(boost::bind(&HttpConnection::socketReadCallback, this,
  26. _1, _2)),
  27. socket_write_callback_(boost::bind(&HttpConnection::socketWriteCallback,
  28. this, _1, _2)),
  29. acceptor_(acceptor),
  30. connection_pool_(connection_pool),
  31. response_creator_(response_creator),
  32. request_(response_creator_->createNewHttpRequest()),
  33. parser_(new HttpRequestParser(*request_)),
  34. acceptor_callback_(callback),
  35. buf_() {
  36. parser_->initModel();
  37. }
  38. HttpConnection::~HttpConnection() {
  39. close();
  40. }
  41. void
  42. HttpConnection::asyncAccept() {
  43. HttpAcceptorCallback cb = boost::bind(&HttpConnection::acceptorCallback,
  44. this, _1);
  45. acceptor_.asyncAccept(socket_, cb);
  46. }
  47. void
  48. HttpConnection::close() {
  49. socket_.close();
  50. }
  51. void
  52. HttpConnection::doRead() {
  53. TCPEndpoint endpoint;
  54. socket_.asyncReceive(static_cast<void*>(buf_.data()), buf_.size(), 0, &endpoint,
  55. socket_callback_);
  56. }
  57. void
  58. HttpConnection::doWrite() {
  59. if (!output_buf_.empty()) {
  60. TCPEndpoint endpoint;
  61. socket_.asyncSend(output_buf_.data(),
  62. output_buf_.length(), &endpoint,
  63. socket_write_callback_);
  64. }
  65. }
  66. void
  67. HttpConnection::acceptorCallback(const boost::system::error_code& ec) {
  68. if (!acceptor_.isOpen()) {
  69. return;
  70. }
  71. if (ec) {
  72. connection_pool_.stop(shared_from_this());
  73. }
  74. acceptor_callback_(ec);
  75. if (!ec) {
  76. doRead();
  77. }
  78. }
  79. void
  80. HttpConnection::socketReadCallback(boost::system::error_code ec, size_t length) {
  81. std::string s(&buf_[0], buf_[0] + length);
  82. parser_->postBuffer(static_cast<void*>(buf_.data()), length);
  83. parser_->poll();
  84. if (parser_->needData()) {
  85. doRead();
  86. } else {
  87. request_->finalize();
  88. HttpResponsePtr response = response_creator_->createHttpResponse(request_);
  89. output_buf_ = response->toString();
  90. doWrite();
  91. }
  92. }
  93. void
  94. HttpConnection::socketWriteCallback(boost::system::error_code ec,
  95. size_t length) {
  96. if (length <= output_buf_.size()) {
  97. output_buf_.erase(0, length);
  98. doWrite();
  99. } else {
  100. output_buf_.clear();
  101. }
  102. }
  103. } // end of namespace isc::http
  104. } // end of namespace isc