Esempio n. 1
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. 2
0
/// handles requests for EchoService
void EchoService::operator()(HTTPRequestPtr& request, TCPConnectionPtr& tcp_conn)
{
	// this web service uses static text to test the mixture of "copied" with
	// "static" (no-copy) text
	static const std::string REQUEST_ECHO_TEXT("[Request Echo]");
	static const std::string REQUEST_HEADERS_TEXT("[Request Headers]");
	static const std::string QUERY_PARAMS_TEXT("[Query Parameters]");
	static const std::string COOKIE_PARAMS_TEXT("[Cookie Parameters]");
	static const std::string POST_CONTENT_TEXT("[POST Content]");
	static const std::string USER_INFO_TEXT("[USER Info]");
	
	// Set Content-type to "text/plain" (plain ascii text)
	HTTPResponseWriterPtr writer(HTTPResponseWriter::create(tcp_conn, *request,
															boost::bind(&TCPConnection::finish, tcp_conn)));
	writer->getResponse().setContentType(HTTPTypes::CONTENT_TYPE_TEXT);
	
	// write request information
	writer->writeNoCopy(REQUEST_ECHO_TEXT);
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	writer
		<< "Request method: "
		<< request->getMethod()
		<< HTTPTypes::STRING_CRLF
		<< "Resource originally requested: "
		<< request->getOriginalResource()
		<< HTTPTypes::STRING_CRLF
		<< "Resource delivered: "
		<< request->getResource()
		<< HTTPTypes::STRING_CRLF
		<< "Query string: "
		<< request->getQueryString()
		<< HTTPTypes::STRING_CRLF
		<< "HTTP version: "
		<< request->getVersionMajor() << '.' << request->getVersionMinor()
		<< HTTPTypes::STRING_CRLF
		<< "Content length: "
		<< (unsigned long)request->getContentLength()
		<< HTTPTypes::STRING_CRLF
		<< HTTPTypes::STRING_CRLF;
			 
	// write request headers
	writer->writeNoCopy(REQUEST_HEADERS_TEXT);
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	std::for_each(request->getHeaders().begin(), request->getHeaders().end(),
				  boost::bind(&writeDictionaryTerm, writer, _1, false));
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);

	// write query parameters
	writer->writeNoCopy(QUERY_PARAMS_TEXT);
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	std::for_each(request->getQueryParams().begin(), request->getQueryParams().end(),
				  boost::bind(&writeDictionaryTerm, writer, _1, true));
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	
	// write cookie parameters
	writer->writeNoCopy(COOKIE_PARAMS_TEXT);
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	std::for_each(request->getCookieParams().begin(), request->getCookieParams().end(),
				  boost::bind(&writeDictionaryTerm, writer, _1, false));
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	
	// write POST content
	writer->writeNoCopy(POST_CONTENT_TEXT);
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	if (request->getContentLength() != 0) {
		writer->write(request->getContent(), request->getContentLength());
		writer->writeNoCopy(HTTPTypes::STRING_CRLF);
		writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	}
	
	// if authenticated, write user info
	PionUserPtr user = request->getUser();
	if (user) {
		writer->writeNoCopy(USER_INFO_TEXT);
		writer->writeNoCopy(HTTPTypes::STRING_CRLF);
		writer->writeNoCopy(HTTPTypes::STRING_CRLF);
		writer << "User authenticated, username: " << user->getUsername();
		writer->writeNoCopy(HTTPTypes::STRING_CRLF);
	}
    
	// send the writer
	writer->send();
}