示例#1
0
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();
}
示例#2
0
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();
}
示例#3
0
/** 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();
}
示例#4
0
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;
}
示例#6
0
 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();
    }
 }
示例#7
0
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));
}
示例#8
0
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() );
	}

}
示例#9
0
void HttpRequest::startCollectingData()
{
	readSome();
}