websocket_request_handler.cpp
Go to the documentation of this file.
00001 #include <boost/regex.hpp>
00002 #include <openssl/sha.h>
00003 #include <openssl/hmac.h>
00004 #include <openssl/evp.h>
00005 #include <openssl/bio.h>
00006 #include <openssl/buffer.h>
00007 #include "async_web_server_cpp/websocket_request_handler.hpp"
00008 #include "async_web_server_cpp/websocket_connection.hpp"
00009 #include "async_web_server_cpp/http_reply.hpp"
00010 
00011 namespace async_web_server_cpp
00012 {
00013 
00014 const std::string WebsocketHttpRequestHandler::KEY_MAGIC_STRING = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
00015 
00016 WebsocketHttpRequestHandler::WebsocketHttpRequestHandler(WebsocketRequestHandler handler)
00017   : handler_(handler) {}
00018 
00019 
00020 void WebsocketHttpRequestHandler::operator()(const HttpRequest &request, boost::shared_ptr<HttpConnection> connection, const char* begin, const char* end)
00021 {
00022   std::string connection_header = request.get_header_value_or_default("Connection", "");
00023   std::string upgrade_header = request.get_header_value_or_default("Upgrade", "");
00024   std::string websocket_key = request.get_header_value_or_default("Sec-WebSocket-Key", "");
00025 
00026   if (connection_header.find("Upgrade") != std::string::npos && upgrade_header.compare("websocket") == 0
00027       && websocket_key.size() > 0)
00028   {
00029     std::string concat_key = websocket_key + KEY_MAGIC_STRING;
00030 
00031     // compute the sha1 hash of the concatonated key
00032     unsigned char sha1_buf[20];
00033     SHA1((const unsigned char*)concat_key.data(), concat_key.size(), sha1_buf);
00034 
00035     // base64 encode the hash
00036     BIO* b64 = BIO_new(BIO_f_base64());
00037     BIO* bmem = BIO_new(BIO_s_mem());
00038     b64 = BIO_push(b64, bmem);
00039     BIO_write(b64, sha1_buf, 20);
00040     BIO_flush(b64);
00041     BUF_MEM *bptr;
00042     BIO_get_mem_ptr(b64, &bptr);
00043     std::string base64_key(bptr->data, bptr->length - 1);
00044     BIO_free_all(b64);
00045 
00046 
00047     async_web_server_cpp::HttpReply::builder(async_web_server_cpp::HttpReply::switching_protocols)
00048     .header("Upgrade", "websocket")
00049     .header("Connection", "Upgrade")
00050     .header("Sec-WebSocket-Version", "13")
00051     .header("Sec-WebSocket-Accept", base64_key)
00052     .write(connection);
00053 
00054     WebsocketConnectionPtr websocket_connection(new WebsocketConnection(connection));
00055     WebsocketConnection::MessageHandler message_handler = handler_(request, websocket_connection);
00056     websocket_connection->set_message_handler(message_handler);
00057     websocket_connection->handle_read(begin, end);
00058   }
00059   else
00060   {
00061     async_web_server_cpp::HttpReply::stock_reply(async_web_server_cpp::HttpReply::bad_request)(request, connection, begin, end);
00062   }
00063 }
00064 
00065 }


async_web_server_cpp
Author(s): Mitchell Wills
autogenerated on Thu Aug 27 2015 12:27:39