void HttpConnection::io(Socket *, int revents) { TRACE("io(revents=%04x) isHandlingRequest:%d", revents, flags_ & IsHandlingRequest); ref(); if (revents & ev::ERROR) { log(Severity::error, "Potential bug in connection I/O watching. Closing."); abort(); goto done; } if ((revents & Socket::Read) && !readSome()) goto done; if ((revents & Socket::Write) && !writeSome()) goto done; if (!process()) goto done; switch (status()) { case ReadingRequest: watchInput(worker_->server_.maxReadIdle()); break; case KeepAliveRead: watchInput(worker_->server_.maxKeepAlive()); default: break; } done: unref(); }
void HttpConnection::io(Socket *, int revents) { TRACE(1, "io(revents=%04x) isHandlingRequest:%d", revents, isHandlingRequest()); ref(); if (revents & ev::ERROR) { log(Severity::error, "Potential bug in connection I/O watching. Closing."); abort(); goto done; } // socket is ready for read? if ((revents & Socket::Read) && !readSome()) goto done; // socket is ready for write? if ((revents & Socket::Write) && !writeSome()) goto done; switch (status()) { case ReadingRequest: TRACE(1, "io(): status=%s. Watch for read.", status_str()); watchInput(worker_->server_.maxReadIdle()); break; case KeepAliveRead: if (isInputPending()) { do { // we're in keep-alive state but have (partial) request in buffer pending // so do process it right away TRACE(1, "io(): status=%s. Pipelined input pending.", status_str()); process(); } while (isInputPending() && status() == KeepAliveRead); if (status() == KeepAliveRead) { // we're still in keep-alive state but no (partial) request in buffer pending // so watch for socket input event. TRACE(1, "io(): status=%s. Watch for read (keep-alive).", status_str()); watchInput(worker_->server_.maxKeepAlive()); } } else { // we are in keep-alive state and have no (partial) request in buffer pending // so watch for socket input event. TRACE(1, "io(): status=%s. Watch for read (keep-alive).", status_str()); watchInput(worker_->server_.maxKeepAlive()); } break; case ProcessingRequest: case SendingReplyDone: case SendingReply: case Undefined: // should never be reached TRACE(1, "io(): status=%s. Do not touch I/O watcher.", status_str()); break; } done: unref(); }
/** start first async operation for this HttpConnection. * * This is done by simply registering the underlying socket to the the I/O service * to watch for available input. * * \note This method must be invoked right after the object construction. * * \see stop() */ void HttpConnection::start(ServerSocket* listener, Socket* client, const HttpWorker::ConnectionHandle& handle) { handle_ = handle; listener_ = listener; socket_ = client; socket_->setReadyCallback<HttpConnection, &HttpConnection::io>(this); sink_.setSocket(socket_); #if defined(TCP_NODELAY) if (worker_->server().tcpNoDelay()) socket_->setTcpNoDelay(true); #endif #if !defined(NDEBUG) setLoggingPrefix("HttpConnection[%d,%llu|%s:%d]", worker_->id(), id_, remoteIP().c_str(), remotePort()); #endif TRACE("starting (fd=%d)", socket_->handle()); ref(); // <-- this reference is being decremented in close() worker_->server_.onConnectionOpen(this); if (isAborted()) { // The connection got directly closed (aborted) upon connection instance creation (e.g. within the onConnectionOpen-callback), // so delete the object right away. close(); return; } request_ = new HttpRequest(*this); ref(); if (socket_->state() == Socket::Handshake) { TRACE("start: handshake."); socket_->handshake<HttpConnection, &HttpConnection::handshakeComplete>(this); } else { #if defined(TCP_DEFER_ACCEPT) && defined(WITH_TCP_DEFER_ACCEPT) TRACE("start: processing input"); // it is ensured, that we have data pending, so directly start reading if (readSome()) process(); else close(); TRACE("start: processing input done"); #else TRACE("start: watchInput."); // client connected, but we do not yet know if we have data pending watchInput(worker_->server_.maxReadIdle()); #endif } unref(); }
void HttpProxy::ProxyConnection::io(Socket* s, int revents) { TRACE("io(0x%04x)", revents); if (revents & Socket::Read) readSome(); if (revents & Socket::Write) writeSome(); }
San2::Cppl::ErrorCode TerminalReceiver::receive() { unsigned int bytesRead; const unsigned int dataSize = 512; char data[dataSize]; while(readSome(data, dataSize, &bytesRead) == San2::Cppl::ErrorCode::SUCCESS) { fwrite(data, 1, bytesRead, stdout); fflush(stdout); // important, really ! Otherwise it sucks and does not write everything at once. } return San2::Cppl::ErrorCode::SUCCESS; }
void startReading() { if (sslStream_) { // begin ssl handshake sslStream_->async_handshake(boost::asio::ssl::stream_base::server, boost::bind(&AsyncConnectionImpl<SocketType>::handleHandshake, AsyncConnectionImpl<SocketType>::shared_from_this(), boost::asio::placeholders::error)); } else { readSome(); } }
void FakeHttpServer::onNewConnection(rapid::ConnectionPtr pConn) { static const std::string s_httpReplyContent{ "HTTP/1.1 200 OK\r\n" "Content-Length: 100\r\n" "Connection: keep-alive\r\n" "Host: 127.0.0.1\r\n" "\r\n" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }; auto pRecvBuffer = pConn->getReceiveBuffer(); auto pSendBuffer = pConn->getSendBuffer(); do { pRecvBuffer->retrieve(pRecvBuffer->readable()); pSendBuffer->append(s_httpReplyContent); if (!pConn->sendAsync()) { break; } } while (pRecvBuffer->readSome(pConn)); }
void HttpRequest::handleRead ( const boost::system::error_code &e, std::size_t bytes_transferred ) { shared_ptr<RequestManager> manager = this->manager.lock(); shared_ptr<HttpServer> server = this->server.lock(); assert(manager && server); if ( !e ) { boost::tribool result; boost::tie ( result, boost::tuples::ignore ) = parser.parse ( shared_from_this(), buffer.data(), buffer.data() + bytes_transferred ); if ( result ) { manager->enqueue ( shared_from_this() ); } else if ( !result ) { if (checkifAnswered()) return; answer ( HttpRequest::Reply::bad_request ); } else { readSome(); } } else if ( e != boost::asio::error::operation_aborted ) { server->stopRequest ( shared_from_this() ); } }
void HttpRequest::startCollectingData() { readSome(); }