void Connection::handleWriteResponse(ReplyPtr reply) { LOG_DEBUG(socket().native() << ": handleWriteResponse() " << haveResponse_ << " " << responseDone_); if (haveResponse_) startWriteResponse(reply); else { if (!responseDone_) { /* * Keep reply open and wait for more data. */ } else { reply->logReply(request_handler_.logger()); if (reply->closeConnection()) ConnectionManager_.stop(shared_from_this()); else { request_parser_.reset(); request_.reset(); responseDone_ = false; while (rcv_buffers_.size() > 1) rcv_buffers_.pop_front(); if (rcv_remaining_ < rcv_buffers_.back().data() + rcv_buffer_size_) handleReadRequest0(); else startAsyncReadRequest(rcv_buffers_.back(), KEEPALIVE_TIMEOUT); } } } }
void Connection::handleReadRequest0() { #ifdef DEBUG try { LOG_DEBUG(socket().native() << "incoming request: " << socket().remote_endpoint().port() << ": " << std::string(remaining_, std::min((unsigned long)(buffer_.data() - remaining_ + buffer_size_), (long unsigned)1000))); } catch (...) { } #endif // DEBUG boost::tribool result; boost::tie(result, remaining_) = request_parser_.parse(request_, remaining_, buffer_.data() + buffer_size_); if (result) { Reply::status_type status = request_parser_.validate(request_); bool doWebSockets = server_->controller()->configuration().webSockets(); if (doWebSockets) request_.enableWebSocket(); LOG_DEBUG(socket().native() << "request: " << status); if (status >= 300) sendStockReply(status); else { if (request_.webSocketVersion >= 0) request_.urlScheme = "ws" + urlScheme().substr(4); else request_.urlScheme = urlScheme(); try { request_.port = socket().local_endpoint().port(); reply_ = request_handler_.handleRequest(request_); reply_->setConnection(shared_from_this()); moreDataToSendNow_ = true; } catch (asio_system_error& e) { LOG_ERROR("Error in handleRequest0(): " << e.what()); handleError(e.code()); return; } handleReadBody(); } } else if (!result) { sendStockReply(StockReply::bad_request); } else { startAsyncReadRequest(buffer_, request_parser_.initialState() ? KEEPALIVE_TIMEOUT : CONNECTION_TIMEOUT); } }
void Connection::start() { LOG_DEBUG(socket().native() << ": start()"); request_parser_.reset(); request_.reset(); try { request_.remoteIP = socket().remote_endpoint().address().to_string(); } catch (std::exception& e) { LOG_ERROR("remote_endpoint() threw: " << e.what()); } asio_error_code ignored_ec; socket().set_option(asio::ip::tcp::no_delay(true), ignored_ec); startAsyncReadRequest(buffer_, CONNECTION_TIMEOUT); }
void Connection::handleReadRequest0() { Buffer& buffer = rcv_buffers_.back(); #ifdef DEBUG try { LOG_DEBUG(socket().native() << "incoming request: " << socket().remote_endpoint().port() << " (avail= " << (rcv_buffer_size_ - (rcv_remaining_ - buffer.data())) << "): " << std::string(rcv_remaining_, std::min((unsigned long)(buffer.data() - rcv_remaining_ + rcv_buffer_size_), (long unsigned)1000))); } catch (...) { } #endif // DEBUG boost::tribool result; boost::tie(result, rcv_remaining_) = request_parser_.parse(request_, rcv_remaining_, buffer.data() + rcv_buffer_size_); if (result) { Reply::status_type status = request_parser_.validate(request_); // FIXME: Let the reply decide whether we're doing websockets, move this logic to WtReply bool doWebSockets = server_->controller()->configuration().webSockets() && (server_->controller()->configuration().sessionPolicy() != Wt::Configuration::DedicatedProcess || server_->configuration().parentPort() != -1); if (doWebSockets) request_.enableWebSocket(); LOG_DEBUG(socket().native() << "request: " << status); if (status >= 300) sendStockReply(status); else { if (request_.webSocketVersion >= 0) { // replace 'http' with 'ws' request_.urlScheme[0] = 'w'; request_.urlScheme[1] = 's'; strncpy(request_.urlScheme + 2, urlScheme() + 4, 7); request_.urlScheme[9] = 0; } else strncpy(request_.urlScheme, urlScheme(), 9); ReplyPtr reply; try { reply = request_handler_.handleRequest (request_, lastWtReply_, lastProxyReply_, lastStaticReply_); reply->setConnection(shared_from_this()); } catch (asio_system_error& e) { LOG_ERROR("Error in handleRequest0(): " << e.what()); handleError(e.code()); return; } rcv_body_buffer_ = false; handleReadBody(reply); } } else if (!result) { sendStockReply(StockReply::bad_request); } else { rcv_buffers_.push_back(Buffer()); startAsyncReadRequest(rcv_buffers_.back(), request_parser_.initialState() ? KEEPALIVE_TIMEOUT : CONNECTION_TIMEOUT); } }