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)); }
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; }
/** * 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")); }
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; }
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(); }
/** * 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(); }
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 }
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); } }
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())); } }