Esempio n. 1
0
	virtual void handleConnection(TCPConnectionPtr& tcp_conn)
	{
		static const std::string HELLO_MESSAGE("Hello there!\x0D\x0A");
		tcp_conn->setLifecycle(TCPConnection::LIFECYCLE_CLOSE);	// make sure it will get closed
		tcp_conn->async_write(boost::asio::buffer(HELLO_MESSAGE),
							  boost::bind(&TCPConnection::finish, tcp_conn));
	}
Esempio n. 2
0
    void TCPServer::mapConnection(TCPConnectionPtr const & connPtr)
    {
    	std::string connStr = createConnectionStr(connPtr->remoteIp(), connPtr->remotePort());

		#if (((STREAMS_BOOST_VERSION / 100) % 1000) < 53)
			streams_boost::mutex::scoped_lock scoped_lock(mutex_);
		#else
			streams_boost::unique_lock<streams_boost::mutex> scoped_lock(mutex_);
		#endif

		connMap_[connStr] = connPtr;
    }
Esempio n. 3
0
	/**
	 * protected constructor restricts creation of objects (use create())
	 *
	 * @param tcp_conn TCP connection containing a new message to parse
	 * @param handler function called after the message has been parsed
	 */
	HTTPRequestReader(TCPConnectionPtr& tcp_conn, FinishedHandler handler)
		: HTTPReader(true, tcp_conn), m_http_msg(new HTTPRequest),
		m_finished(handler)
	{
		m_http_msg->setRemoteIp(tcp_conn->getRemoteIp());
		setLogger(PION_GET_LOGGER("pion.net.HTTPRequestReader"));
	}
Esempio n. 4
0
void TCP_Async_Server::startAccept() {
	waitingSocket = BUFFER_SIZE;
	int i=0;
	while(i++ < BUFFER_SIZE) {
		//Create a socket but haven't opened it yet. Socket opening requires accept/connect
		TCPConnectionPtr newConnectionPtr = TCPConnection::create(acceptor_.get_io_service());

		//One io_service can create how many sockets?

		/*This function is used to asynchronously accept a new connection into a
	socket. The function call always returns immediately.*/
		acceptor_.async_accept(newConnectionPtr->getSocket()
				,boost::bind(&TCP_Async_Server::acceptHandle, this,  newConnectionPtr, boost::asio::placeholders::error));
		std::cout << "Ready to accept a connection\n";
	}
}
	bool AsyncDataItem::getValidConnection(TCPConnectionPtr & connPtr)
	{
		if(connPtr = connWeakPtr_.lock()) {
			return connPtr->socket().is_open();
		}

		return false;
	}
Esempio n. 6
0
void TCP_Async_Server::acceptHandle(TCPConnectionPtr newConnectionPtr, const boost::system::error_code& error) {
	if(!error) {
		std::cout << "Start handling request\n";
		newConnectionPtr->start();
	}

	waitingSocket--;
	if(waitingSocket == 0)
		startAccept();
}
Esempio n. 7
0
	/**
	 * sends an HTTP response with content, but not content-length provided
	 *
	 * @param request the HTTP request to respond to
	 * @param tcp_conn the TCP connection to send the response over
	 */
	void sendResponseWithContentButNoLength(HTTPRequestPtr& request,
											TCPConnectionPtr& tcp_conn)
	{
		// make sure it will get closed when finished
		tcp_conn->setLifecycle(TCPConnection::LIFECYCLE_CLOSE);
		
		// prepare the response headers
		HTTPResponse http_response(*request);
		http_response.setDoNotSendContentLength();
		
		// send the response headers
		boost::system::error_code error_code;
		http_response.send(*tcp_conn, error_code);
		BOOST_REQUIRE(! error_code);
		
		// send the content buffer
		tcp_conn->write(boost::asio::buffer(m_big_buf, BIG_BUF_SIZE), error_code);
		BOOST_REQUIRE(! error_code);
		
		// finish (and close) the connection
		tcp_conn->finish();
	}
Esempio n. 8
0
void TCPServer::handleAccept(const boost::system::error_code& e, TCPConnectionPtr conn) {

    if (!_acceptorPtr->is_open()) {
        return;
    }

    if (!e) {
        LOG_INFO(logger, "Successfully accepted new connection to port (" << 
                 getSetup().GetPort() << ")" );

        _conn = conn;

        // Starts reading data from the socket
        conn->async_read(_msg,
                         boost::bind(&TCPServer::handleRead, this,
                                     boost::asio::placeholders::error));

    } else {
        LOG_ERROR(logger, "Error when accepting a new connection to port (" << 
                  getSetup().GetPort() << ") [error:" << e.message() << "]" );
    }

    // Do not starts a new accept operation as only one client can be connected
}
Esempio n. 9
0
void HTTPServer::handleRequest(HTTPRequestPtr& http_request,
							   TCPConnectionPtr& tcp_conn)
{
	if (! http_request->isValid()) {
		// the request is invalid or an error occured
		PION_LOG_INFO(m_logger, "Received an invalid HTTP request");
		m_bad_request_handler(http_request, tcp_conn);
		return;
	}
		
	PION_LOG_DEBUG(m_logger, "Received a valid HTTP request");

	// strip off trailing slash if the request has one
	std::string resource_requested(stripTrailingSlash(http_request->getResource()));

	// apply any redirection
	RedirectMap::const_iterator it = m_redirects.find(resource_requested);
	unsigned int num_redirects = 0;
	while (it != m_redirects.end()) {
		if (++num_redirects > MAX_REDIRECTS) {
			PION_LOG_ERROR(m_logger, "Maximum number of redirects (HTTPServer::MAX_REDIRECTS) exceeded for requested resource: " << http_request->getOriginalResource());
			m_server_error_handler(http_request, tcp_conn, "Maximum number of redirects (HTTPServer::MAX_REDIRECTS) exceeded for requested resource");
			return;
		}
		resource_requested = it->second;
		http_request->changeResource(resource_requested);
		it = m_redirects.find(resource_requested);
	}

	// if authentication activated, check current request
	if (m_auth) {
		// try to verify authentication
		if (! m_auth->handleRequest(http_request, tcp_conn)) {
			// the HTTP 401 message has already been sent by the authentication object
			PION_LOG_DEBUG(m_logger, "Authentication required for HTTP resource: "
				<< resource_requested);
			if (http_request->getResource() != http_request->getOriginalResource()) {
				PION_LOG_DEBUG(m_logger, "Original resource requested was: " << http_request->getOriginalResource());
			}
			return;
		}
	}
	
	// search for a handler matching the resource requested
	RequestHandler request_handler;
	if (findRequestHandler(resource_requested, request_handler)) {
		
		// try to handle the request
		try {
			request_handler(http_request, tcp_conn);
			PION_LOG_DEBUG(m_logger, "Found request handler for HTTP resource: "
						   << resource_requested);
			if (http_request->getResource() != http_request->getOriginalResource()) {
				PION_LOG_DEBUG(m_logger, "Original resource requested was: " << http_request->getOriginalResource());
			}
		} catch (HTTPResponseWriter::LostConnectionException& e) {
			// the connection was lost while or before sending the response
			PION_LOG_WARN(m_logger, "HTTP request handler: " << e.what());
			tcp_conn->setLifecycle(TCPConnection::LIFECYCLE_CLOSE);	// make sure it will get closed
			tcp_conn->finish();
		} catch (std::bad_alloc&) {
			// propagate memory errors (FATAL)
			throw;
		} catch (std::exception& e) {
			// recover gracefully from other exceptions thrown request handlers
			PION_LOG_ERROR(m_logger, "HTTP request handler: " << e.what());
			m_server_error_handler(http_request, tcp_conn, e.what());
		}
		
	} else {
		
		// no web services found that could handle the request
		PION_LOG_INFO(m_logger, "No HTTP request handlers found for resource: "
					  << resource_requested);
		if (http_request->getResource() != http_request->getOriginalResource()) {
			PION_LOG_DEBUG(m_logger, "Original resource requested was: " << http_request->getOriginalResource());
		}
		m_not_found_handler(http_request, tcp_conn);
	}
}
Esempio n. 10
0
    void TCPServer::handleWrite(SPL::blob & raw, std::string const & ipAddress, uint32_t port)
    {
//    	std::string connStr = broadcastResponse_ ? "" : createConnectionStr(ipAddress, port);

//		std::cerr << "writing to: " << connStr << std::endl;

//		TCPConnectionWeakPtr connWeakPtr;
//		bool connExist = false;

		TCPConnectionWeakPtrMap::iterator iter = broadcastResponse_ ? findFirstConnection() : findConnection(createConnectionStr(ipAddress, port));

    	if(iter == connMap_.end()) {
			if(!broadcastResponse_) errorHandler_.handleError(streams_boost::system::error_code(streams_boost::asio::error::connection_aborted), ipAddress, port);
    	}

		else {
			AsyncDataItemPtr asyncDataItemPtr = streams_boost::make_shared<AsyncDataItem>(errorHandler_);
			asyncDataItemPtr->setData<Format>(raw);

    		do {
				TCPConnectionWeakPtr connWeakPtr = iter->second;
				TCPConnectionPtr connPtr = connWeakPtr.lock();

				/// Validate existing connection
				if (connPtr && connPtr->socket().is_open()) {

					uint32_t * numOutstandingWritesPtr = connPtr->getNumOutstandingWritesPtr();

					/// Check if client consumes data from a socket
					if (*numOutstandingWritesPtr <= maxUnreadResponseCount_) {
						__sync_fetch_and_add(numOutstandingWritesPtr, 1);

						if(Format == mcts::block) {
							async_write(connPtr->socket(), asyncDataItemPtr->getBuffers(),
									connPtr->strand().wrap( streams_boost::bind(&AsyncDataItem::handleError, asyncDataItemPtr,
															streams_boost::asio::placeholders::error,
															connPtr->remoteIp(), connPtr->remotePort(), connWeakPtr)
									)
							);
						}
						else {
							async_write(connPtr->socket(), asyncDataItemPtr->getBuffer(),
									connPtr->strand().wrap( streams_boost::bind(&AsyncDataItem::handleError, asyncDataItemPtr,
															streams_boost::asio::placeholders::error,
															connPtr->remoteIp(), connPtr->remotePort(), connWeakPtr)
									)
							);
						}

						iter++;
					}
					else {
						connPtr->shutdown_conn(makeConnReadOnly_);
						if(makeConnReadOnly_) {
							iter++;
						}
						else {
							iter = unmapConnection(iter);
						}

						errorHandler_.handleError(streams_boost::system::error_code(streams_boost::asio::error::would_block), ipAddress, port, connWeakPtr);
					}
				}
				else {
					iter = unmapConnection(iter);
				}
			} while (broadcastResponse_ && (iter != connMap_.end()));
    	}

    }