void server::handle_forbidden_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const std::string& error_msg) { static const std::string FORBIDDEN_HTML_START = "<html><head>\n" "<title>403 Forbidden</title>\n" "</head><body>\n" "<h1>Forbidden</h1>\n" "<p>User not authorized to access the requested URL "; static const std::string FORBIDDEN_HTML_MIDDLE = "</p><p><strong>\n"; static const std::string FORBIDDEN_HTML_FINISH = "</strong></p>\n" "</body></html>\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, std::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_FORBIDDEN); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_FORBIDDEN); writer->write_no_copy(FORBIDDEN_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_resource()); writer->write_no_copy(FORBIDDEN_HTML_MIDDLE); writer << error_msg; writer->write_no_copy(FORBIDDEN_HTML_FINISH); writer->send(); }
bool cookie_auth::handle_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { if (process_login(http_request_ptr,tcp_conn)) { return false; // we processed login/logout request, no future processing for this request permitted } if (!need_authentication(http_request_ptr)) { return true; // this request does not require authentication } // check if it is redirection page.. If yes, then do not test its credentials ( as used for login) if (!m_redirect.empty() && m_redirect==http_request_ptr->get_resource()) { return true; // this request does not require authentication } // check cache for expiration boost::posix_time::ptime time_now(boost::posix_time::second_clock::universal_time()); expire_cache(time_now); // if we are here, we need to check if access authorized... const std::string auth_cookie(http_request_ptr->get_cookie(AUTH_COOKIE_NAME)); if (! auth_cookie.empty()) { // check if this cookie is in user cache boost::mutex::scoped_lock cache_lock(m_cache_mutex); user_cache_type::iterator user_cache_itr=m_user_cache.find(auth_cookie); if (user_cache_itr != m_user_cache.end()) { // we find those credential in our cache... // we can approve authorization now! http_request_ptr->set_user(user_cache_itr->second.second); // and update cache timeout user_cache_itr->second.first = time_now; return true; } } // user not found handle_unauthorized(http_request_ptr,tcp_conn); return false; }
void forum_server::handle_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const boost::system::error_code& ec) { std::string path = http_request_ptr->get_resource(); boost::asio::ip::address ip = tcp_conn->get_remote_ip(); log("Received new request from '" + ip.to_string() + "' who is trying to access '" + path + "'"); std::string route; // Is this conditional really needed..? if (path.size() > 1) { std::string::iterator it; for (it = path.begin() + 1; it != path.end(); ++it) { if (*it == '/') break; } if (it != path.end()) { try { int index = std::distance(path.begin() + 1, it); routes[path.substr(1, index)](path.substr(index + 2), http_request_ptr, tcp_conn); } catch (std::exception& e) { ferror(e.what()); http::response_writer_ptr writer( http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); http::response res = writer->get_response(); res.set_content_type(http::types::CONTENT_TYPE_HTML); res.set_status_code(500); res.set_status_message("Internal Server Error"); // Push the custom error page.. writer->write("Invalid route"); writer->send(); } } else routes["home"](path.substr(1), http_request_ptr, tcp_conn); } // Home is the default route.. else routes["home"]("", http_request_ptr, tcp_conn); }
void server::handle_not_found_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { static const std::string NOT_FOUND_HTML_START = "<html><head>\n" "<title>404 Not Found</title>\n" "</head><body>\n" "<h1>Not Found</h1>\n" "<p>The requested URL "; static const std::string NOT_FOUND_HTML_FINISH = " was not found on this server.</p>\n" "</body></html>\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, std::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_NOT_FOUND); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_NOT_FOUND); writer->write_no_copy(NOT_FOUND_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_resource()); writer->write_no_copy(NOT_FOUND_HTML_FINISH); writer->send(); }
void server::handle_method_not_allowed(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const std::string& allowed_methods) { static const std::string NOT_ALLOWED_HTML_START = "<html><head>\n" "<title>405 Method Not Allowed</title>\n" "</head><body>\n" "<h1>Not Allowed</h1>\n" "<p>The requested method "; static const std::string NOT_ALLOWED_HTML_FINISH = " is not allowed on this server.</p>\n" "</body></html>\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, std::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_METHOD_NOT_ALLOWED); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_METHOD_NOT_ALLOWED); if (! allowed_methods.empty()) writer->get_response().add_header("Allow", allowed_methods); writer->write_no_copy(NOT_ALLOWED_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_method()); writer->write_no_copy(NOT_ALLOWED_HTML_FINISH); writer->send(); }
bool cookie_auth::process_login(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { // strip off trailing slash if the request has one std::string resource(http::server::strip_trailing_slash(http_request_ptr->get_resource())); if (resource != m_login && resource != m_logout) { return false; // no login processing done } std::string redirect_url = http_request_ptr->get_query("url"); std::string new_cookie; bool delete_cookie = false; if (resource == m_login) { // process login // check username std::string username = http_request_ptr->get_query("user"); std::string password = http_request_ptr->get_query("pass"); // match username/password user_ptr user=m_user_manager->get_user(username,password); if (!user) { // authentication failed, process as in case of failed authentication... handle_unauthorized(http_request_ptr,tcp_conn); return true; } // ok we have a new user session, create a new cookie, add to cache // create random cookie std::string rand_binary; rand_binary.reserve(RANDOM_COOKIE_BYTES); for (unsigned int i=0; i<RANDOM_COOKIE_BYTES ; i++) { rand_binary += static_cast<unsigned char>(m_random_die()); } algorithm::base64_encode(rand_binary, new_cookie); // add new session to cache boost::posix_time::ptime time_now(boost::posix_time::second_clock::universal_time()); boost::mutex::scoped_lock cache_lock(m_cache_mutex); m_user_cache.insert(std::make_pair(new_cookie,std::make_pair(time_now,user))); } else { // process logout sequence // if auth cookie presented - clean cache out const std::string auth_cookie(http_request_ptr->get_cookie(AUTH_COOKIE_NAME)); if (! auth_cookie.empty()) { boost::mutex::scoped_lock cache_lock(m_cache_mutex); user_cache_type::iterator user_cache_itr=m_user_cache.find(auth_cookie); if (user_cache_itr!=m_user_cache.end()) { m_user_cache.erase(user_cache_itr); } } // and remove cookie from browser delete_cookie = true; } // if redirect defined - send redirect if (! redirect_url.empty()) { handle_redirection(http_request_ptr,tcp_conn,redirect_url,new_cookie,delete_cookie); } else { // otherwise - OK handle_ok(http_request_ptr,tcp_conn,new_cookie,delete_cookie); } // yes, we processed login/logout somehow return true; }