Beispiel #1
0
void parser::parse_spdy_rst_stream(boost::system::error_code &ec,
                                   const spdy_control_frame_info& frame)
{
    boost::uint32_t stream_id = 0;
    boost::uint32_t status_code = 0;
    
    // First complete the check for size and flag
    // The flag for RST frame should be 0, The length should be 8
    if(frame.flags != 0 || frame.length != 8 ){
        return;
    }

    // Get the 31 bit stream id
    
    boost::uint32_t four_bytes = algorithm::to_uint32(m_read_ptr);
    stream_id = four_bytes & 0x7FFFFFFF;
    
    m_read_ptr += 4;
    
    // Get the status code
    status_code = algorithm::to_uint32(m_read_ptr);
    
    char const* const status_code_str = rst_stream_status(status_code);
    if(status_code_str){
        PION_LOG_INFO(m_logger, "SPDY Status Code is : " << status_code_str);
    }else{
        PION_LOG_INFO(m_logger, "SPDY RST Invalid status code : " << status_code);
    }
}
Beispiel #2
0
void PionOneToOneScheduler::startup(void)
{
	// lock mutex for thread safety
	boost::mutex::scoped_lock scheduler_lock(m_mutex);
	
	if (! m_is_running) {
		PION_LOG_INFO(m_logger, "Starting thread scheduler");
		m_is_running = true;
		
		// make sure there are enough services initialized
		while (m_service_pool.size() < m_num_threads) {
			boost::shared_ptr<ServicePair>	service_ptr(new ServicePair());
			m_service_pool.push_back(service_ptr);
		}

		// schedule a work item for each service to make sure that it doesn't complete
		for (ServicePool::iterator i = m_service_pool.begin(); i != m_service_pool.end(); ++i) {
			keepRunning((*i)->first, (*i)->second);
		}
		
		// start multiple threads to handle async tasks
		for (boost::uint32_t n = 0; n < m_num_threads; ++n) {
			boost::shared_ptr<boost::thread> new_thread(new boost::thread( boost::bind(&PionScheduler::processServiceWork,
																					   this, boost::ref(m_service_pool[n]->first)) ));
			m_thread_pool.push_back(new_thread);
		}
	}
}
void server::remove_resource(const std::string& resource)
{
    std::unique_lock<std::mutex> resource_lock(m_resource_mutex, std::try_to_lock);
    const std::string clean_resource(strip_trailing_slash(resource));
    m_resources.erase(clean_resource);
    PION_LOG_INFO(m_logger, "Removed request handler for HTTP resource: " << clean_resource);
}
Beispiel #4
0
void HTTPServer::removeResource(const std::string& resource)
{
	boost::mutex::scoped_lock resource_lock(m_resource_mutex);
	const std::string clean_resource(stripTrailingSlash(resource));
	m_resources.erase(clean_resource);
	PION_LOG_INFO(m_logger, "Removed request handler for HTTP resource: " << clean_resource);
}
Beispiel #5
0
void plugin_server::set_service_option(const std::string& resource,
                                 const std::string& name, const std::string& value)
{
    const std::string clean_resource(strip_trailing_slash(resource));
    m_services.run(clean_resource, boost::bind(&http::plugin_service::set_option, _1, name, value));
    PION_LOG_INFO(m_logger, "Set web service option for resource ("
                  << resource << "): " << name << '=' << value);
}
void server::add_resource(const std::string& resource,
                             request_handler_t request_handler)
{
    std::unique_lock<std::mutex> resource_lock(m_resource_mutex, std::try_to_lock);
    const std::string clean_resource(strip_trailing_slash(resource));
    m_resources.insert(std::make_pair(clean_resource, request_handler));
    PION_LOG_INFO(m_logger, "Added request handler for HTTP resource: " << clean_resource);
}
Beispiel #7
0
void HTTPServer::addResource(const std::string& resource,
							 RequestHandler request_handler)
{
	boost::mutex::scoped_lock resource_lock(m_resource_mutex);
	const std::string clean_resource(stripTrailingSlash(resource));
	m_resources.insert(std::make_pair(clean_resource, request_handler));
	PION_LOG_INFO(m_logger, "Added request handler for HTTP resource: " << clean_resource);
}
Beispiel #8
0
void plugin_server::load_service(const std::string& resource, const std::string& service_name)
{
    const std::string clean_resource(strip_trailing_slash(resource));
    http::plugin_service *service_ptr;
    service_ptr = m_services.load(clean_resource, service_name);
    http::server::add_resource(clean_resource, boost::ref(*service_ptr));
    service_ptr->set_resource(clean_resource);
    PION_LOG_INFO(m_logger, "Loaded web service plug-in for resource (" << clean_resource << "): " << service_name);
}
Beispiel #9
0
void plugin_server::add_service(const std::string& resource, http::plugin_service *service_ptr)
{
    plugin_ptr<http::plugin_service> plugin_ptr;
    const std::string clean_resource(strip_trailing_slash(resource));
    service_ptr->set_resource(clean_resource);
    m_services.add(clean_resource, service_ptr);
    http::server::add_resource(clean_resource, boost::ref(*service_ptr));
    PION_LOG_INFO(m_logger, "Loaded static web service for resource (" << clean_resource << ")");
}
void server::add_redirect(const std::string& requested_resource,
                             const std::string& new_resource)
{
    std::unique_lock<std::mutex> resource_lock(m_resource_mutex, std::try_to_lock);
    const std::string clean_requested_resource(strip_trailing_slash(requested_resource));
    const std::string clean_new_resource(strip_trailing_slash(new_resource));
    m_redirects.insert(std::make_pair(clean_requested_resource, clean_new_resource));
    PION_LOG_INFO(m_logger, "Added redirection for HTTP resource " << clean_requested_resource << " to resource " << clean_new_resource);
}
Beispiel #11
0
void HTTPServer::addRedirect(const std::string& requested_resource,
							 const std::string& new_resource)
{
	boost::mutex::scoped_lock resource_lock(m_resource_mutex);
	const std::string clean_requested_resource(stripTrailingSlash(requested_resource));
	const std::string clean_new_resource(stripTrailingSlash(new_resource));
	m_redirects.insert(std::make_pair(clean_requested_resource, clean_new_resource));
	PION_LOG_INFO(m_logger, "Added redirection for HTTP resource " << clean_requested_resource << " to resource " << clean_new_resource);
}
Beispiel #12
0
void PionScheduler::shutdown(void)
{
	// lock mutex for thread safety
	boost::mutex::scoped_lock scheduler_lock(m_mutex);
	
	if (m_is_running) {
		
		PION_LOG_INFO(m_logger, "Shutting down the thread scheduler");
		
		while (m_active_users > 0) {
			// first, wait for any active users to exit
			PION_LOG_INFO(m_logger, "Waiting for " << m_active_users << " scheduler users to finish");
			m_no_more_active_users.wait(scheduler_lock);
		}

		// shut everything down
		m_is_running = false;
		stopServices();
		stopThreads();
		finishServices();
		finishThreads();
		
		PION_LOG_INFO(m_logger, "The thread scheduler has shutdown");

		// Make sure anyone waiting on shutdown gets notified
		m_scheduler_has_stopped.notify_all();
		
	} else {
		
		// stop and finish everything to be certain that no events are pending
		stopServices();
		stopThreads();
		finishServices();
		finishThreads();
		
		// Make sure anyone waiting on shutdown gets notified
		// even if the scheduler did not startup successfully
		m_scheduler_has_stopped.notify_all();
	}
}
Beispiel #13
0
void parser::parse_spdy_ping_frame(boost::system::error_code &ec,
                                   const spdy_control_frame_info& frame)
{
    // First complete the check for size 
    // The length should be 4 always
    if(frame.length != 4){
        return;
    }
  
    boost::uint32_t ping_id = 0;
    
    // Get the 32 bit ping id
    
    ping_id = algorithm::to_uint32(m_read_ptr);
    
    m_read_ptr += 4;
    
    PION_LOG_INFO(m_logger, "SPDY " << "Ping ID is : " << ping_id);
}
Beispiel #14
0
void PionSingleServiceScheduler::startup(void)
{
	// lock mutex for thread safety
	boost::mutex::scoped_lock scheduler_lock(m_mutex);
	
	if (! m_is_running) {
		PION_LOG_INFO(m_logger, "Starting thread scheduler");
		m_is_running = true;
		
		// schedule a work item to make sure that the service doesn't complete
		m_service.reset();
		keepRunning(m_service, m_timer);
		
		// start multiple threads to handle async tasks
		for (boost::uint32_t n = 0; n < m_num_threads; ++n) {
			boost::shared_ptr<boost::thread> new_thread(new boost::thread( boost::bind(&PionScheduler::processServiceWork,
																					   this, boost::ref(m_service)) ));
			m_thread_pool.push_back(new_thread);
		}
	}
}
Beispiel #15
0
void parser::parse_spdy_goaway_frame(boost::system::error_code &ec,
                                     const spdy_control_frame_info& frame)
{
    // First complete the check for size
    // The length should be 4 always
    if(frame.length != 4){
        return;
    }
    
    boost::uint32_t last_good_stream_id = 0;
    boost::uint32_t status_code = 0;
    
    // Get the 31 bit stream id
    
    boost::uint32_t four_bytes = algorithm::to_uint32(m_read_ptr);
    last_good_stream_id = four_bytes & 0x7FFFFFFF;
    
    m_read_ptr += 4;
    
    // Get the status code
    
    status_code = algorithm::to_uint32(m_read_ptr);
    
    // Chek if there was an error
    if(status_code == 1){
        
        PION_LOG_ERROR(m_logger, "There was a Protocol Error");
        set_error(ec, ERROR_PROTOCOL_ERROR);
        return;
    }else if (status_code == 11) {
        
        PION_LOG_ERROR(m_logger, "There was an Internal Error");
        set_error(ec, ERROR_INTERNAL_SPDY_ERROR);
        return;
    }
    
    PION_LOG_INFO(m_logger, "SPDY " << "Status Code is : " << status_code);
    
}
Beispiel #16
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);
	}
}