Samchon Framework for CPP  1.0.0
IWebServer.cpp
1 #include <samchon/protocol/IWebServer.hpp>
2 
3 #include <thread>
4 #include <boost/asio.hpp>
5 #include <boost/uuid/sha1.hpp>
6 
7 #include <samchon/ByteArray.hpp>
8 #include <samchon/WeakString.hpp>
9 #include <samchon/library/Base64.hpp>
10 #include <samchon/library/StringUtil.hpp>
11 
12 using namespace std;
13 
14 using namespace samchon;
15 using namespace samchon::library;
16 using namespace samchon::protocol;
17 
18 /* -----------------------------------------------------------------------
19  CONSTRUCTORS
20 ----------------------------------------------------------------------- */
21 IWebServer::IWebServer()
22  : super()
23 {
24 }
26 {
27  if (acceptor != nullptr && acceptor->is_open() == true)
28  return;
29 
30  boost::system::error_code error;
31  boost::asio::io_service ioService;
32  unique_ptr<boost::asio::ip::tcp::endpoint> endPoint;
33 
34  if (acceptor == nullptr)
35  {
36  string &myIP = MY_IP();
37 
38  if (myIP.empty() == true)
39  {
40  endPoint.reset( new boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), PORT()) );
41  }
42  else
43  {
44  endPoint.reset( new boost::asio::ip::tcp::endpoint( boost::asio::ip::address::from_string(myIP), PORT() ) );
45  }
46  acceptor = new boost::asio::ip::tcp::acceptor(ioService, *endPoint);
47  }
48 
49  while (true)
50  {
51  Socket *socket = new Socket(ioService);
52  acceptor->accept(*socket, error);
53 
54  if (error)
55  {
56  delete socket;
57  break;
58  }
59 
60  thread
61  (
62  [this, socket]
63  {
64  if (handshake(socket) == true)
65  addClient(socket);
66  }
67  ).detach();
68  }
69  delete acceptor;
70  acceptor = nullptr;
71 }
72 
73 /* -----------------------------------------------------------------------
74  HANDSHAKE OF WEB-SOCKET
75 ----------------------------------------------------------------------- */
76 auto IWebServer::handshake(Socket *socket) const -> bool
77 {
78  ByteArray byteArray;
79  boost::system::error_code error;
80 
81  byteArray.assign(1000, NULL);
82 
83  socket->read_some(boost::asio::buffer(byteArray), error);
84  if (error)
85  return false;
86 
87  string &header = byteArray.read<string>();
88 
89  WeakString wstr = header;
90  wstr = wstr.between("Sec-WebSocket-Key:", "\n").trim();
91  if(wstr.find("\r") != string::npos)
92  wstr = wstr.between("", "\r");
93 
94  string &handshake =
95  StringUtil::substitute
96  (
97  string("") +
98  "HTTP/1.1 101 Switching Protocols\r\n" +
99  "Upgrade: websocket\r\n" +
100  "Connection: Upgrade\r\n" +
101  "Sec-WebSocket-Accept: {1}\r\n" +
102  "\r\n",
103 
104  calculateCertificationKey(wstr.str())
105  );
106 
107  socket->write_some(boost::asio::buffer(handshake), error);
108  if (error)
109  return false;
110  else
111  return true;
112 }
113 auto IWebServer::calculateCertificationKey(const string &key64) const -> string
114 {
115  string acceptKey = key64 + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
116 
117  boost::uuids::detail::sha1 hash;
118  hash.process_bytes(acceptKey.c_str(), acceptKey.size());
119 
120  ByteArray bytes;
121  unsigned int digest[5];
122  hash.get_digest(digest);
123 
124  for (size_t index = 0; index < 5; index++)
125  bytes.writeReversely //ENDIAN REVERSING
126  (
127  digest[index]
128  );
129 
130  return Base64::encode(bytes);
131 }
An interface of a physical server.
Definition: IServer.hpp:43
Definition: RWMutex.hpp:4
virtual void open() override
Open the web-socket server.
Definition: IWebServer.cpp:25
Package of libraries.
Definition: library.hpp:84
virtual auto PORT() const -> int=NULL
Port number of the server.
auto read() const -> T
Read data.
Definition: ByteArray.hpp:121
void writeReversely(const T &val)
Write a data.
Definition: ByteArray.hpp:193
virtual auto MY_IP() const -> std::string
(optional) Server&#39;s IP
Definition: IServer.cpp:16
Package of network protocol and libraries.
Definition: protocol.hpp:185
Binary data class.
Definition: ByteArray.hpp:30
virtual void addClient(Socket *)=0
Handling connection of a physical client.
auto between(const WeakString &start={}, const WeakString &end={}) const -> WeakString
Generates a substring.
Definition: WeakString.cpp:194
Top level namespace of products built from samchon.
Definition: ByteArray.hpp:7
A string class only references characeters, reference only.
Definition: WeakString.hpp:32
Acceptor * acceptor
An acceptor for clients.
Definition: IServer.hpp:49