]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5217] Imrpoved errors handling in Http connection.
authorMarcin Siodelski <marcin@isc.org>
Fri, 14 Apr 2017 12:16:15 +0000 (14:16 +0200)
committerMarcin Siodelski <marcin@isc.org>
Fri, 14 Apr 2017 12:16:15 +0000 (14:16 +0200)
src/lib/http/connection.cc
src/lib/http/request_parser.cc

index 3bd85148fc564dc2c107e5c1f0bfecc7c64ea36d..d986f8a634a82eb01fd371a298cd16cd3c9af43f 100644 (file)
@@ -140,16 +140,39 @@ HttpConnection::acceptorCallback(const boost::system::error_code& ec) {
 }
 
 void
-HttpConnection::socketReadCallback(boost::system::error_code, size_t length) {
+HttpConnection::socketReadCallback(boost::system::error_code ec, size_t length) {
+    if (ec) {
+        // IO service has been stopped and the connection is probably
+        // going to be shutting down.
+        if (ec.value() == boost::asio::error::operation_aborted) {
+            return;
+
+        // EWOULDBLOCK and EAGAIN are special cases. Everything else is
+        // treated as fatal error.
+        } else if ((ec.value() != boost::asio::error::try_again) &&
+                   (ec.value() != boost::asio::error::would_block)) {
+            stopThisConnection();
+
+        // We got EWOULDBLOCK or EAGAIN which indicate that we may be able to
+        // read something from the socket on the next attempt. Just make sure
+        // we don't try to read anything now in case there is any garbage
+        // passed in length.
+        } else {
+            length = 0;
+        }
+    }
+
     if (length != 0) {
         LOG_DEBUG(http_logger, isc::log::DBGLVL_TRACE_DETAIL_DATA,
                   HTTP_DATA_RECEIVED)
             .arg(length)
             .arg(getRemoteEndpointAddressAsText());
+
+        std::string s(&buf_[0], buf_[0] + length);
+        parser_->postBuffer(static_cast<void*>(buf_.data()), length);
+        parser_->poll();
     }
-    std::string s(&buf_[0], buf_[0] + length);
-    parser_->postBuffer(static_cast<void*>(buf_.data()), length);
-    parser_->poll();
+
     if (parser_->needData()) {
         doRead();
 
@@ -172,8 +195,26 @@ HttpConnection::socketReadCallback(boost::system::error_code, size_t length) {
 }
 
 void
-HttpConnection::socketWriteCallback(boost::system::error_code,
-                                    size_t length) {
+HttpConnection::socketWriteCallback(boost::system::error_code ec, size_t length) {
+    if (ec) {
+        // IO service has been stopped and the connection is probably
+        // going to be shutting down.
+        if (ec.value() == boost::asio::error::operation_aborted) {
+            return;
+
+        // EWOULDBLOCK and EAGAIN are special cases. Everything else is
+        // treated as fatal error.
+        } else if ((ec.value() != boost::asio::error::try_again) &&
+                   (ec.value() != boost::asio::error::would_block)) {
+            stopThisConnection();
+
+        // We got EWOULDBLOCK or EAGAIN which indicate that we may be able to
+        // read something from the socket on the next attempt.
+        } else {
+            doWrite();
+        }
+    }
+
     if (length <= output_buf_.size()) {
         output_buf_.erase(0, length);
         doWrite();
index c10e3ba5630f9c6a48fcb9e485d7d18f462a1e8d..55c158dac3e413f068b010ea4e8366cba5eacbf2 100644 (file)
@@ -78,7 +78,8 @@ HttpRequestParser::poll() {
 
 bool
 HttpRequestParser::needData() const {
-    return (getNextEvent() == NEED_MORE_DATA_EVT);
+    return ((getNextEvent() == NEED_MORE_DATA_EVT) ||
+            (getNextEvent() == START_EVT));
 }
 
 bool