示例#1
0
int client_handler(int sock) {

    pid_t pid;
    pid = fork();

    if(pid < 0) {

        fprintf(stderr, "Fork failed\n");
        exit(1);

    } else if (pid == 0) {

        request_handler(sock);
        exit(0);

    } else {

        int return_val;    
        waitpid(pid, &return_val, 0);
        if(WEXITSTATUS(return_val) == 1)  return 1;

    }

    return 0;


}
示例#2
0
/* 
 * worker_thread - thread that initialized first, then invoke when 
 * reqeust comming in 
 */
void *worker_thread(void *vargp) {  
    #ifdef DEBUG
    printf("enter worker_thread\n");
    #endif
    Pthread_detach(pthread_self()); 
    while (1) { 
	    int client_fd = sbuf_remove(&sbuf);
        request_handler(client_fd);
    }    
}
示例#3
0
void Session::on_execute(uv_async_t* data, int status) {
#else
void Session::on_execute(uv_async_t* data) {
#endif
  Session* session = static_cast<Session*>(data->data);

  bool is_closing = false;

  RequestHandler* temp = NULL;
  while (session->request_queue_->dequeue(temp)) {
    RequestHandler::Ptr request_handler(temp);
    if (request_handler) {
      request_handler->dec_ref(); // Queue reference

      request_handler->init(session->config_,
                            session->keyspace(),
                            session->token_map_.get(),
                            session->prepared_metadata_);

      bool is_done = false;
      while (!is_done) {
        request_handler->next_host();

        if (!request_handler->current_host()) {
          request_handler->set_error(CASS_ERROR_LIB_NO_HOSTS_AVAILABLE,
                                     "All connections on all I/O threads are busy");
          break;
        }

        size_t start = session->current_io_worker_;
        for (size_t i = 0, size = session->io_workers_.size(); i < size; ++i) {
          const IOWorker::Ptr& io_worker = session->io_workers_[start % size];
          if (io_worker->execute(request_handler)) {
            session->current_io_worker_ = (start + 1) % size;
            is_done = true;
            break;
          }
          start++;
        }
      }
    } else {
      is_closing = true;
    }
  }

  if (is_closing) {
    session->pending_workers_count_ = session->io_workers_.size();
    for (IOWorkerVec::iterator it = session->io_workers_.begin(),
                               end = session->io_workers_.end();
         it != end; ++it) {
      (*it)->close_async();
    }
  }
}
示例#4
0
void* socket_handler(void *arg)
{
	int sock = *((int*)arg);
	int result = SOCKET_CONTINUE;

	printf("SOCKET %d CONNECTED\n", sock);
	while (result == SOCKET_CONTINUE) {
		result = request_handler(sock);
	}
	printf("SOCKET %d CLOSED\n", sock);
	close(sock);
	return NULL;

}
示例#5
0
Future::Ptr Session::execute(const Request::ConstPtr& request,
                             const Address* preferred_address) {
  ResponseFuture::Ptr future(new ResponseFuture());

  RequestHandler::Ptr request_handler(new RequestHandler(request, future, this));

  if (preferred_address) {
    request_handler->set_preferred_address(*preferred_address);
  }

  execute(request_handler);

  return future;
}
示例#6
0
/**
 * Reads data from a client socket and passes forward to handle a message or removes a player
 * and closes socket.
 * @param[in] client_fd          File descriptor of a client that is currently served.
 * @param     base_rdfs          Bit array holding file descriptors to be served by the server.
 * @param     players_list       Pointer to a list holding players.
 * @param     games_list         Pointer to a list holding games.
 * @param     threads_list       Pointer to a list holding threads.
 * @param     players_list_mutex Pointer to a mutex guarding players list.
 * @param     games_list_mutex   Pointer to a mutex guarding games list.
 * @param     threads_list_mutex Pointer to a mutex guarding threads list.
 */
void
communicate(int client_fd, fd_set *base_rdfs,
		players_list_s **players_list, games_list_s **games_list,
		threads_list_s **threads_list, pthread_mutex_t *players_list_mutex,
		pthread_mutex_t *games_list_mutex, pthread_mutex_t *threads_list_mutex) {
	char buffer[MAX_MSG_SIZE];
	ssize_t size;
	request_s request;
	memset(&request, 0, sizeof(request_s));
	size = bulk_read(client_fd, buffer, MAX_MSG_SIZE);
	if (size == MAX_MSG_SIZE) {
		fprintf(stderr, "Message received from fd: %d\n", client_fd);
		string_to_request(buffer, &request);
		request_handler(client_fd, &request, base_rdfs, players_list,
				games_list, threads_list, players_list_mutex, games_list_mutex,
				threads_list_mutex);
	}
	if (size == 0) {
		fprintf(stderr,
				"End of file. Removing player. Closing descriptor: %d\n",
				client_fd);
		pthread_mutex_lock(players_list_mutex);
		remove_player_from_list2(players_list, client_fd);
		pthread_mutex_unlock(players_list_mutex);
		if (TEMP_FAILURE_RETRY(close(client_fd)) < 0)
			ERR("close");
		FD_CLR(client_fd, base_rdfs);

	}
	if (size < 0) {
		fprintf(stderr, "Error. Removing player. Closing descriptor: %d\n",
				client_fd);
		pthread_mutex_lock(players_list_mutex);
		remove_player_from_list2(players_list, client_fd);
		pthread_mutex_unlock(players_list_mutex);
		if (TEMP_FAILURE_RETRY(close(client_fd)) < 0)
			ERR("close");
		FD_CLR(client_fd, base_rdfs);
	}
}
示例#7
0
void server::HttpServer::worker(server::TcpServerConnection* connection)
{
  server::HttpServerSession session;
  session.connection = connection;

  try
  {
    process_request(&session);
    check_request(&session);
    prepare_session(&session);
    request_handler(session);
    check_session_response(&session);
    send_response(&session);
  }
  catch(Exception& e)
  {
    bad_request(&session, e);
  }
  catch(std::bad_alloc& e)
  {
  }
}
示例#8
0
//------------------------------------------------------------------------------
/// Callback invoked when data has been received on the USB.
//------------------------------------------------------------------------------
static void UsbDataReceived(unsigned int unused,
                            unsigned char status,
                            unsigned int received,
                            unsigned int remaining)
{
  // Check that data has been received successfully
  if (status == USBD_STATUS_SUCCESS) {
//    // Check if bytes have been discarded
//    if ((received == DATABUFFERSIZE) && (remaining > 0)) {}
    
    source_id = USB_SOURCE;
    if (modbus_dev_state == DEV_FREE) {
      for (unsigned short i = 0; i < received; i++) {
        *(puchMsg + i) = *(usbBuffer + i);
      }
    }
    
//    received_tmp = received;
    request_handler(received);
  } else {
    usb_state = USB_READ_ERROR;
  }
}
示例#9
0
/*
 * Opens a TCP stream socket on all interfaces with port number PORTNO. Saves
 * the fd number of the server socket in *socket_number. For each accepted
 * connection, calls request_handler with the accepted fd number.
 */
void serve_forever(int* socket_number, void (*request_handler)(int))
{

  struct sockaddr_in server_address, client_address;
  size_t client_address_length = sizeof(client_address);
  int client_socket_number;
  pid_t pid;

  *socket_number = socket(PF_INET, SOCK_STREAM, 0);
  if (*socket_number == -1) {
    fprintf(stderr, "Failed to create a new socket: error %d: %s\n", errno, strerror(errno));
    exit(errno);
  }

  int socket_option = 1;
  if (setsockopt(*socket_number, SOL_SOCKET, SO_REUSEADDR, &socket_option,
        sizeof(socket_option)) == -1) {
    fprintf(stderr, "Failed to set socket options: error %d: %s\n", errno, strerror(errno));
    exit(errno);
  }

  memset(&server_address, 0, sizeof(server_address));
  server_address.sin_family = AF_INET;
  server_address.sin_addr.s_addr = INADDR_ANY;
  server_address.sin_port = htons(server_port);

  if (bind(*socket_number, (struct sockaddr*) &server_address,
        sizeof(server_address)) == -1) {
    fprintf(stderr, "Failed to bind on socket: error %d: %s\n", errno, strerror(errno));
    exit(errno);
  }

  if (listen(*socket_number, 1024) == -1) {
    fprintf(stderr, "Failed to listen on socket: error %d: %s\n", errno, strerror(errno));
    exit(errno);
  }

  printf("Listening on port %d...\n", server_port);

  while (1) {

    client_socket_number = accept(*socket_number, (struct sockaddr*) &client_address,
        (socklen_t*) &client_address_length);
    if (client_socket_number < 0) {
      fprintf(stderr, "Error accepting socket: error %d: %s\n", errno, strerror(errno));
      continue;
    }

    printf("Accepted connection from %s on port %d\n", inet_ntoa(client_address.sin_addr),
        client_address.sin_port);

    pid = fork();
    if (pid > 0) {
      close(client_socket_number);
    } else if (pid == 0) {
      signal(SIGINT, SIG_DFL); // Un-register signal handler (only parent should have it)
      close(*socket_number);
      request_handler(client_socket_number);
      close(client_socket_number);
      exit(EXIT_SUCCESS);
    } else {
      fprintf(stderr, "Failed to fork child: error %d: %s\n", errno, strerror(errno));
      exit(errno);
    }
  }

  close(*socket_number);

}
示例#10
0
int main(void) try
  {
    // the thread group
    boost::shared_ptr< boost::thread_group > p_threads(
      boost::make_shared< boost::thread_group>());

    // setup asio::io_service
    boost::shared_ptr< boost::asio::io_service > p_io_service(
      boost::make_shared< boost::asio::io_service >());
    boost::shared_ptr< boost::asio::io_service::work > p_work(
      boost::make_shared< boost::asio::io_service::work >(
        boost::ref(*p_io_service)));

    // io_service threads
    {
      int n_threads = 1;
      while(0 < n_threads--) {
        p_threads->create_thread(
          boost::bind(&boost::asio::io_service::run, p_io_service));
      }
    }

    // the shared work queue
    work_queue queue;

    // worker threads that will process the request; off the queue
    {
      int n_threads = 12;
      while(0 < n_threads--) {
        p_threads->create_thread(
          boost::bind(process_request, boost::ref(queue)));
      }
    }

    // setup the async server
    handler request_handler(queue);
    boost::shared_ptr< server > p_server_instance(
      boost::make_shared<server>(
        server::options(request_handler).
        address("0.0.0.0")
        .port("8800")
        .io_service(p_io_service)
        .reuse_address(true)
        .thread_pool(
          boost::make_shared<boost::network::utils::thread_pool>(
            2 , p_io_service, p_threads))));

    // setup clean shutdown
    boost::asio::signal_set signals(*p_io_service, SIGINT, SIGTERM);
    signals.async_wait(boost::bind(shut_me_down, _1, _2, p_server_instance));

    // run the async server
    p_server_instance->run();

    // we are stopped - shutting down

    p_threads->interrupt_all();

    p_work.reset();
    p_io_service->stop();

    p_threads->join_all();

    Log("Terminated normally");
    exit(EXIT_SUCCESS);
  }
 catch(const std::exception& e)
   {
     Log("Abnormal termination - exception:"<<e.what());
     exit(EXIT_FAILURE);
   }
示例#11
0
文件: BA.c 项目: kaisert/kilobot
int receive_message()
{
    get_message();
    if(message_rx[5] == 1 && message_rx[3] <= MAX_DIST) {
        switch(message_rx[2]) {
        case M_ERROR:
            break;
        case M_CHECK_ID:
            if(state < RECRUIT_REFERENCE) {
                if(check_id_handler ((uint8_t) message_rx[1], message_rx[3]) == 2)
                    state = CONSTRUCT_ID;
            }
            break;
        case M_CHANGE_ID:
            if(message_rx[1] == id){
                //reset, if I have to change ID
                RESET_COUNTER;
                message_out(EMPTY, id, M_CHANGE_ID);
                _delay_ms(250);
                state = CONSTRUCT_ID;
            } else {
                //drop the double id
                uint8_t faulty_id = message_rx[1];
                struct list_node *n;
                if((n = exists(neighbours, &faulty_id, &comp_id_neigh)) != 0)
                    remove_node(neighbours, n);
            }
            break;
        case M_ELECT_SEED_TOP:
            if(state == ELECT_SEED_TOP)
                return 1;
            break;
        case M_ELECT_SEED_BOTTOM:
            if(state == ELECT_SEED_BOTTOM)
                return 1;
            break;
        case M_NOT_ENOUGH_SEEDS:
            //if neighbour needs more seeders, new bottom election
            if((role != SEEDER) &&
                    (state == AWAIT_R_R || state == CHECK_SEEDER)) {
                role = BOTTOM_SEEDER;
                state = ELECT_SEED_BOTTOM;
                RESET_COUNTER;
            }
            break;
        case M_SEEDER:
            handle_seeder_m(message_rx[1]);
            break;
        case M_R_R_REQ_ATT:
        case M_R_R_ACK:
        case M_R_R_REQ_DIST:
            if(state >= RECRUIT_REFERENCE && message_rx[0] == id)
                request_handler();
            break;
        case M_R_R_LISTENING:
            if(message_rx[0] == id && state == RECRUIT_REFERENCE)
                return 1;
            break;
        case M_R_R_DIST:
            if(message_rx[1] == id && state == RECRUIT_REFERENCE)
                return 1;
            break;
        case M_R_R_ABORT1:
            if(message_rx[1] == id && state == RECRUIT_REFERENCE)
                return 1;
            break;
        }

    } else {
        return E_NO_NEW_MESSAGE;
    }
	return 0;
}
示例#12
0
void swd::connection::handle_read(const boost::system::error_code& e,
 std::size_t bytes_transferred) {
	/**
	 * If an error occurs then no new asynchronous operations are started. This
	 * means that all shared_ptr references to the connection object will disappear
	 * and the object will be destroyed automatically after this handler returns.
	 * The connection class's destructor closes the socket.
	 */
	if (e) {
		return;
	}

	/**
	 * Since there was no error we can start parsing the input now. The parser
	 * fills the object request_ with data.
	 */
	boost::tribool result;
	boost::tie(result, boost::tuples::ignore) =
		request_parser_.parse(
			request_,
			buffer_.data(),
			buffer_.data() + bytes_transferred
		);

	/**
	 * If result is true the complete request is parsed. If it is false there was
	 * an error. If it is indeterminate then the parsing is not complete yet and
	 * the program will read more input and append it to the old request_ object.
	 */
	if (indeterminate(result)) {
		/* Not finished yet with this request, start reading again. */
		this->start_read();

		/* And don't process the input yet. */
		return;
	}

	/* The handler used to process the reply. */
	swd::reply_handler reply_handler(reply_);

	try {
		if (!result) {
			swd::log::i()->send(swd::warning, "Bad request from "
			 + remote_address_.to_string());
			throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
		}

		/* Try to add a profile for the request. */
		try {
			swd::profile_ptr profile = swd::database::i()->get_profile(
				remote_address_.to_string(),
				request_->get_profile_id()
			);

			request_->set_profile(profile);
		} catch (swd::exceptions::database_exception& e) {
			swd::log::i()->send(swd::uncritical_error, e.what());
			throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
		}

		/* The handler used to process the incoming request. */
		swd::request_handler request_handler(request_);

		/* Only continue processing the reply if it is signed correctly. */
		if (!request_handler.valid_signature()) {
			swd::log::i()->send(swd::warning, "Bad signature from "
			 + remote_address_.to_string());
			throw swd::exceptions::connection_exception(STATUS_BAD_SIGNATURE);
		}

		/**
		 * Before the request can be processed the input has to be transfered
		 * from the encoded json string to a swd::parameters list.
		 */
		if (!request_handler.decode()) {
			swd::log::i()->send(swd::warning, "Bad json from "
			 + remote_address_.to_string());
			throw swd::exceptions::connection_exception(STATUS_BAD_JSON);
		}

		/* Process the request. */
		std::vector<std::string> threats;

		try {
			if (swd::database::i()->is_flooding(request_->get_client_ip(), request_->get_profile_id())) {
				throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
			}

			threats = request_handler.process();
		} catch (swd::exceptions::database_exception& e) {
			swd::log::i()->send(swd::uncritical_error, e.what());

			/**
			 * Problems with the database result in a bad request. If protection
			 * is enabled access to the site will not be granted.
			 */
			throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
		}

		if (!threats.empty()) {
			reply_->set_threats(threats);
			reply_->set_status(STATUS_ATTACK);
		} else {
			reply_->set_status(STATUS_OK);
		}
	} catch(swd::exceptions::connection_exception& e) {
		reply_->set_status(e.code());
	}

	/* Encode the reply. */
	reply_handler.encode();

	/* Send the answer to the client. */
	if (ssl_) {
		boost::asio::async_write(
			ssl_socket_,
			reply_->to_buffers(),
			strand_.wrap(
				boost::bind(
					&connection::handle_write,
					shared_from_this(),
					boost::asio::placeholders::error
				)
			)
		);
	} else {
		boost::asio::async_write(
			socket_,
			reply_->to_buffers(),
			strand_.wrap(
				boost::bind(
					&connection::handle_write,
					shared_from_this(),
					boost::asio::placeholders::error
				)
			)
		);
	}
}
示例#13
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);
	}
}
int main() {
  try {
    // the thread group
    auto threads(std::make_shared<boost::network::utils::thread_group>());

    // setup asio::io_service
    auto io_service(std::make_shared<boost::asio::io_service>());
    auto work(std::make_shared<boost::asio::io_service::work>(std::ref(*io_service)));

    // io_service threads
    {
      int n_threads = 5;
      while (0 < n_threads--) {
        threads->create_thread([=] () { io_service->run(); });
      }
    }

    // the shared work queue
    work_queue queue;

    // worker threads that will process the request; off the queue
    {
      int n_threads = 5;
      while (0 < n_threads--) {
        threads->create_thread([&queue] () { process_request(queue); });
      }
    }

    // setup the async server
    handler request_handler(queue);
    auto server(std::make_shared<server_data>(
        server::options(request_handler)
        .address("0.0.0.0")
        .port("8000")
        .io_service(io_service)
        .reuse_address(true)
        .thread_pool(std::make_shared<boost::network::utils::thread_pool>(
             2, io_service, threads))));

    // setup clean shutdown
    boost::asio::signal_set signals(*io_service, SIGINT, SIGTERM);
    signals.async_wait([=] (boost::system::error_code const &ec, int signal) {
        shut_me_down(ec, signal, server);
      });

    // run the async server
    server->run();

    work.reset();
    io_service->stop();

    threads->join_all();

    std::cout << "Terminated normally" << std::endl;
    exit(EXIT_SUCCESS);
  }
  catch (const std::exception& e) {
    std::cerr << "Abnormal termination - exception:" << e.what() << std::endl;
    exit(EXIT_FAILURE);
  }
}
示例#15
0
void swd::connection::handle_read(const boost::system::error_code& e,
 std::size_t bytes_transferred) {
    /**
     * If an error occurs then no new asynchronous operations are started. This
     * means that all shared_ptr references to the connection object will disappear
     * and the object will be destroyed automatically after this handler returns.
     * The connection class's destructor closes the socket.
     */
    if (e) {
        return;
    }

    /**
     * Since there was no error we can start parsing the input now. The parser
     * fills the object request_ with data.
     */
    boost::tribool result;
    boost::tie(result, boost::tuples::ignore) =
        request_parser_.parse(
            request_,
            buffer_.data(),
            buffer_.data() + bytes_transferred
        );

    /**
     * If result is true the complete request is parsed. If it is false there was
     * an error. If it is indeterminate then the parsing is not complete yet and
     * the program will read more input and append it to the old request_ object.
     */
    if (indeterminate(result)) {
        /* Not finished yet with this request, start reading again. */
        this->start_read();

        /* And don't process the input yet. */
        return;
    }

    /* The handler used to process the reply. */
    swd::reply_handler reply_handler(reply_);

    try {
        if (!result) {
            swd::log::i()->send(swd::warning, "Bad request from "
             + remote_address_.to_string());
            throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
        }

        /* Try to add a profile for the request. */
        try {
            swd::profile_ptr profile = database_->get_profile(
                remote_address_.to_string(),
                request_->get_profile_id()
            );

            request_->set_profile(profile);
        } catch (swd::exceptions::database_exception& e) {
            swd::log::i()->send(swd::uncritical_error, e.what());
            throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
        }

        /* The handler used to process the incoming request. */
        swd::request_handler request_handler(request_, cache_, storage_);

        /* Only continue processing the reply if it is signed correctly. */
        if (!request_handler.valid_signature()) {
            swd::log::i()->send(swd::warning, "Bad signature from "
             + remote_address_.to_string());
            throw swd::exceptions::connection_exception(STATUS_BAD_SIGNATURE);
        }

        /**
         * Before the request can be processed the input has to be transfered
         * from the encoded json string to a swd::parameters list.
         */
        if (!request_handler.decode()) {
            swd::log::i()->send(swd::warning, "Bad json from "
             + remote_address_.to_string());
            throw swd::exceptions::connection_exception(STATUS_BAD_JSON);
        }

        /* Check profile for outdated cache. */
        swd::profile_ptr profile = request_->get_profile();

        if (profile->is_cache_outdated()) {
            cache_->reset(profile->get_id());
        }

        /* Process the request. */
        std::vector<std::string> threats;

        try {
            swd::parameters parameters = request_->get_parameters();

            /**
             * Check security limitations first.
             */
            int max_params = swd::config::i()->get<int>("max-parameters");

            if ((max_params > -1) && (parameters.size() > max_params)) {
                swd::log::i()->send(swd::notice, "Too many parameters");
                throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
            }

            int max_length_path = swd::config::i()->get<int>("max-length-path");
            int max_length_value = swd::config::i()->get<int>("max-length-value");

            if ((max_length_path > -1) || (max_length_value > -1)) {
                for (swd::parameters::iterator it_parameter = parameters.begin();
                 it_parameter != parameters.end(); it_parameter++) {
                    swd::parameter_ptr parameter(*it_parameter);

                    if ((max_length_path > -1) && (parameter->get_path().length() > max_length_path)) {
                        swd::log::i()->send(swd::notice, "Too long parameter path");
                        throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
                    }

                    if ((max_length_value > -1) && (parameter->get_value().length() > max_length_value)) {
                        swd::log::i()->send(swd::notice, "Too long parameter value");
                        throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
                    }
                }
            }

            if (profile->is_flooding_enabled()) {
                if (database_->is_flooding(request_->get_client_ip(), profile->get_id())) {
                    swd::log::i()->send(swd::notice, "Too many requests");
                    throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
                }
            }

            /* Time to analyze the request. */
            request_handler.process();
        } catch (swd::exceptions::database_exception& e) {
            swd::log::i()->send(swd::uncritical_error, e.what());

            /**
             * Problems with the database result in a bad request. If protection
             * is enabled access to the site will not be granted.
             */
            throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST);
        }

        if (profile->get_mode() == MODE_ACTIVE) {
            if (request_->is_threat()) {
                reply_->set_status(STATUS_CRITICAL_ATTACK);
            } else if (request_->has_threats()) {
                reply_->set_threats(request_handler.get_threats());
                reply_->set_status(STATUS_ATTACK);
            } else {
                reply_->set_status(STATUS_OK);
            }
        } else {
            reply_->set_status(STATUS_OK);
        }
    } catch(swd::exceptions::connection_exception& e) {
        if (!request_->get_profile()) {
            reply_->set_status(STATUS_BAD_REQUEST);
        } else if (request_->get_profile()->get_mode() == MODE_ACTIVE) {
            reply_->set_status(e.code());
        } else {
            reply_->set_status(STATUS_OK);
        }
    }

    /* Encode the reply. */
    reply_handler.encode();

    /* Send the answer to the client. */
    if (ssl_) {
        boost::asio::async_write(
            ssl_socket_,
            reply_->to_buffers(),
            strand_.wrap(
                boost::bind(
                    &connection::handle_write,
                    shared_from_this(),
                    boost::asio::placeholders::error
                )
            )
        );
    } else {
        boost::asio::async_write(
            socket_,
            reply_->to_buffers(),
            strand_.wrap(
                boost::bind(
                    &connection::handle_write,
                    shared_from_this(),
                    boost::asio::placeholders::error
                )
            )
        );
    }
}