NAP
websocketserverendpoint.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4 
5 #pragma once
6 
7 // Local Includes
8 #include "iwebsocketserverendpoint.h"
9 #include "websocketmessage.h"
10 #include "websocketserver.h"
11 
12 // External Includes
13 #include <memory.h>
14 #include <future>
15 #include <mutex>
16 #include <unordered_set>
17 #include <mathutils.h>
18 #include <rapidjson/document.h>
19 #include <rapidjson/istreamwrapper.h>
20 #include <rapidjson/prettywriter.h>
21 #include <rapidjson/error/en.h>
22 #include <nap/logger.h>
23 
24 namespace nap
25 {
71  template<typename config>
72  class WebSocketServerEndPointSetup : public IWebSocketServerEndPoint
73  {
74  RTTI_ENABLE(IWebSocketServerEndPoint)
75  public:
76  // Stop endpoint on destruction
78 
84  bool init(utility::ErrorState& errorState) override;
85 
92  bool start(nap::utility::ErrorState& error) override;
93 
97  bool isOpen() const override;
98 
102  void stop() override;
103 
112  bool send(const WebSocketConnection& connection, const std::string& message, EWebSocketOPCode code, nap::utility::ErrorState& error) override;
113 
123  bool send(const WebSocketConnection& connection, void const* payload, int length, EWebSocketOPCode code, nap::utility::ErrorState& error) override;
124 
131  bool broadcast(const std::string& message, EWebSocketOPCode code, nap::utility::ErrorState& error) override;
132 
141  bool broadcast(void const* payload, int length, EWebSocketOPCode code, nap::utility::ErrorState& error) override;
142 
146  std::string getHostName(const WebSocketConnection& connection) override;
147 
152  void getHostNames(std::vector<std::string>& outHosts) override;
153 
157  int getConnectionCount() override;
158 
162  bool acceptsNewConnections() override;
163 
164  protected:
169  void registerListener(IWebSocketServer& server) override;
170 
175  void unregisterListener(IWebSocketServer& server) override;
176 
180  void run();
181 
186 
191 
196 
201 
206  void onHTTP(wspp::ConnectionHandle con);
207 
212 
216  bool onPing(wspp::ConnectionHandle con, std::string msg);
217 
222 
223  bool mRunning = false;
224  std::mutex mConnectionMutex;
225  std::unordered_set<WebSocketTicketHash> mClientHashes;
226  websocketpp::server<config> mEndPoint;
229  std::future<void> mServerTask;
230  std::vector<wspp::ConnectionHandle> mConnections;
231  std::mutex mListenerMutex;
232  std::vector<IWebSocketServer*> mListeners;
233  };
234 
235 
236  // Not secured web-socket server end point
238 
239 
244  class NAPAPI SecureWebSocketServerEndPoint : public WebSocketServerEndPointSetup<wspp::ConfigTLS>
245  {
247  public:
252  enum class ETLSMode : nap::uint8
253  {
254  Intermediate = 0,
255  Modern
256  };
257 
258  ETLSMode mMode = ETLSMode::Intermediate;
259  std::string mCertificateFile;
260  std::string mPrivateKeyFile;
261  std::string mPassphrase;
262 
268  bool init(utility::ErrorState& errorState) override;
269 
276  bool start(nap::utility::ErrorState &error) override;
277 
278  private:
284  std::shared_ptr<asio::ssl::context> onTLSInit(wspp::ConnectionHandle con);
285  };
286 
287 
289  // Template Definitions
291 
292  template<typename config>
294  {
295  // Run until stopped
296  assert(!mRunning);
297 
298  // Listen to messages on this specific port and ip address (if given)
299  std::error_code stdec;
300  if (mIPAddress.empty())
301  {
302  mEndPoint.listen(static_cast<uint16>(mPort), stdec);
303  }
304  else
305  {
306  mEndPoint.listen(mIPAddress, utility::stringFormat("%d", static_cast<uint16>(mPort)), stdec);
307  }
308 
309  // Contains the error when opening port fails.
310  if (stdec)
311  {
312  error.fail(stdec.message());
313  return false;
314  }
315 
316  // Queues a connection accept operation
317  mEndPoint.start_accept(stdec);
318  if (stdec)
319  {
320  error.fail(stdec.message());
321  return false;
322  }
323 
324  // Run until stopped
325  mServerTask = std::async(std::launch::async, std::bind(&WebSocketServerEndPointSetup<config>::run, this));
326  mRunning = true;
327 
328  return true;
329  }
330 
331 
332  template<typename config>
334  {
335  return mRunning;
336  }
337 
338 
339  template<typename config>
340  bool WebSocketServerEndPointSetup<config>::send(const WebSocketConnection& connection, const std::string& message, EWebSocketOPCode code, nap::utility::ErrorState& error)
341  {
342  std::error_code stdec;
343  mEndPoint.send(connection.mConnection, message, static_cast<wspp::OpCode>(code), stdec);
344  if (stdec)
345  {
346  error.fail(stdec.message());
347  return false;
348  }
349  return true;
350  }
351 
352 
353  template<typename config>
354  bool WebSocketServerEndPointSetup<config>::send(const WebSocketConnection& connection, void const* payload, int length, EWebSocketOPCode code, nap::utility::ErrorState& error)
355  {
356  std::error_code stdec;
357  mEndPoint.send(connection.mConnection, payload, length, static_cast<wspp::OpCode>(code), stdec);
358  if (stdec)
359  {
360  error.fail(stdec.message());
361  return false;
362  }
363  return true;
364  }
365 
366 
367  template<typename config>
369  {
370  bool success(true);
371  std::lock_guard<std::mutex> lock(mConnectionMutex);
372  for (auto& connection : mConnections)
373  {
374  if (!send(connection, message, code, error))
375  success = false;
376  }
377  return success;
378  }
379 
380 
381  template<typename config>
383  {
384  bool success(true);
385  std::lock_guard<std::mutex> lock(mConnectionMutex);
386  for (auto& connection : mConnections)
387  {
388  if (!send(connection, payload, length, code, error))
389  success = false;
390  }
391  return success;
392  }
393 
394 
395  template<typename config>
397  {
398  std::error_code stdec;
399  auto cptr = mEndPoint.get_con_from_hdl(connection.mConnection, stdec);
400  return stdec ? "" : cptr->get_host();
401  }
402 
403  template<typename config>
404  void WebSocketServerEndPointSetup<config>::getHostNames(std::vector<std::string>& outHosts)
405  {
406  outHosts.clear();
407  std::error_code stdec;
408  std::lock_guard<std::mutex> lock(mConnectionMutex);
409  outHosts.reserve(mConnections.size());
410  for (auto& connection : mConnections)
411  {
412  auto cptr = mEndPoint.get_con_from_hdl(connection, stdec);
413  if (!stdec)
414  outHosts.emplace_back(cptr->get_host());
415  }
416  }
417 
418 
419  template<typename config>
421  {
422  std::lock_guard<std::mutex> lock(mConnectionMutex);
423  return mConnections.size();
424  }
425 
426  template<typename config>
428  {
429  if (mConnectionLimit < 0)
430  return true;
431 
432  std::lock_guard<std::mutex> lock(mConnectionMutex);
433  return mConnections.size() < mConnectionLimit;
434  }
435 
436 
437  template<typename config>
439  {
440  // Start running until stopped
441  mEndPoint.run();
442  }
443 
444 
445  template<typename config>
447  {
448  if (mRunning)
449  {
450  // Stop listening for new connections
451  std::error_code stdec;
452  mEndPoint.stop_listening(stdec);
453  if (stdec)
454  {
455  assert(false);
456  nap::Logger::error("%s: %s", mID.c_str(), stdec.message().c_str());
457  }
458 
459  // Close all client connections
460  utility::ErrorState napec;
461  if (!disconnect(napec))
462  {
463  assert(false);
464  nap::Logger::error("%s: %s", mID.c_str(), napec.toString().c_str());
465  }
466 
467  // Explicitly stop
468  mEndPoint.stop();
469 
470  // Wait for thread to finish
471  assert(mServerTask.valid());
472  mServerTask.wait();
473  mRunning = false;
474  }
475  }
476 
477 
478  template<typename config>
480  {
481  stop();
482  }
483 
484 
485  template<typename config>
487  {
488  // Convert log levels
489  mLogLevel = computeWebSocketLogLevel(mLibraryLogLevel);
490  mAccessLogLevel = mLogConnectionUpdates ? websocketpp::log::alevel::all ^ websocketpp::log::alevel::frame_payload
491  : websocketpp::log::alevel::fail;
492 
493  // Initiate logging
494  mEndPoint.clear_error_channels(websocketpp::log::elevel::all);
495  mEndPoint.set_error_channels(mLogLevel);
496 
497  mEndPoint.clear_access_channels(websocketpp::log::alevel::all);
498  mEndPoint.set_access_channels(mAccessLogLevel);
499 
500  // If the endpoint can be re-used by other processes
501  mEndPoint.set_reuse_addr(mAllowPortReuse);
502 
503  // Init asio
504  std::error_code stdec;
505  mEndPoint.init_asio(stdec);
506  if (stdec)
507  {
508  errorState.fail(stdec.message());
509  return false;
510  }
511 
512  // Install connection open / closed handlers
513  mEndPoint.set_http_handler(std::bind(&WebSocketServerEndPointSetup<config>::onHTTP, this, std::placeholders::_1));
514  mEndPoint.set_open_handler(std::bind(&WebSocketServerEndPointSetup<config>::onConnectionOpened, this, std::placeholders::_1));
515  mEndPoint.set_close_handler(std::bind(&WebSocketServerEndPointSetup<config>::onConnectionClosed, this, std::placeholders::_1));
516  mEndPoint.set_fail_handler(std::bind(&WebSocketServerEndPointSetup<config>::onConnectionFailed, this, std::placeholders::_1));
517  mEndPoint.set_validate_handler(std::bind(&WebSocketServerEndPointSetup<config>::onValidate, this, std::placeholders::_1));
518  mEndPoint.set_ping_handler(std::bind(&WebSocketServerEndPointSetup<config>::onPing, this, std::placeholders::_1, std::placeholders::_2));
519 
520  // Install message handler
521  mEndPoint.set_message_handler(std::bind(
523  std::placeholders::_1, std::placeholders::_2
524  ));
525 
526  // Create unique hashes out of tickets
527  // Server side tickets are required to have a password and username
528  for (const auto& ticket : mClients)
529  mClientHashes.emplace(ticket->toHash());
530  return true;
531  }
532 
533 
534  template<typename config>
536  {
537  std::error_code stdec;
538  auto cptr = mEndPoint.get_con_from_hdl(connection, stdec);
539  if (stdec)
540  {
541  nap::Logger::error(stdec.message());
542  return;
543  }
544 
545  // Add to list of actively managed connections
546  {
547  std::lock_guard<std::mutex> lock(mConnectionMutex);
548  mConnections.emplace_back(cptr);
549  }
550 
551  for (IWebSocketServer* listener : mListeners)
552  listener->onConnectionOpened(WebSocketConnection(connection));
553  }
554 
555 
556  template<typename config>
558  {
559  std::error_code stdec;
560  auto cptr = mEndPoint.get_con_from_hdl(connection, stdec);
561  if (stdec)
562  {
563  nap::Logger::error(stdec.message());
564  return;
565  }
566 
567  // Signal that it closed
568  for (IWebSocketServer* listener : mListeners)
569  listener->onConnectionClosed(WebSocketConnection(connection), cptr->get_ec().value(), cptr->get_ec().message());
570 
571  // Remove from internal list of connections
572  {
573  std::lock_guard<std::mutex> lock(mConnectionMutex);
574  auto found_it = std::find_if(mConnections.begin(), mConnections.end(), [&](const auto& it)
575  {
576  auto client_ptr = mEndPoint.get_con_from_hdl(it, stdec);
577  if (stdec)
578  {
579  nap::Logger::error(stdec.message());
580  return false;
581  }
582  return cptr == client_ptr;
583  });
584 
585  // Having no connection to remove is a serious error and should never occur.
586  if (found_it == mConnections.end())
587  {
588  assert(false);
589  return;
590  }
591  mConnections.erase(found_it);
592  }
593  }
594 
595 
596  template<typename config>
598  {
599  std::error_code stdec;
600  auto cptr = mEndPoint.get_con_from_hdl(connection, stdec);
601  if (stdec)
602  {
603  nap::Logger::error(stdec.message());
604  return;
605  }
606 
607  for (IWebSocketServer* listener : mListeners)
608  listener->onConnectionFailed(WebSocketConnection(connection), cptr->get_ec().value(), cptr->get_ec().message());
609  }
610 
611 
612  template<typename config>
614  {
615  WebSocketMessage message(msg);
616  for (IWebSocketServer* listener : mListeners)
617  listener->onMessageReceived(WebSocketConnection(con), message);
618  }
619 
620 
621  template<typename config>
623  {
624  // Get handle to connection
625  std::error_code stdec;
626  auto conp = mEndPoint.get_con_from_hdl(con, stdec);
627  if (stdec)
628  {
629  nap::Logger::error(stdec.message());
630  conp->set_status(websocketpp::http::status_code::internal_server_error);
631  return;
632  }
633 
634  // Set whether the response can be shared with requesting code from the given origin.
635  conp->append_header("Access-Control-Allow-Origin", mAccessAllowControlOrigin);
636 
637  // Get request method
638  std::string method = conp->get_request().get_method();
639 
640  // Handle CORS preflight request
641  if (method.compare("OPTIONS") == 0)
642  {
643  conp->set_status(websocketpp::http::status_code::no_content);
644  conp->append_header("Access-Control-Allow-Methods", "OPTIONS, POST");
645  conp->append_header("Access-Control-Allow-Headers", "Content-Type");
646  return;
647  }
648 
649  // Reject methods other than OPTIONS and POST
650  if (method.compare("POST") != 0)
651  {
652  conp->set_status(websocketpp::http::status_code::method_not_allowed,
653  "only OPTIONS and POST requests are allowed");
654  return;
655  }
656 
657  // When there is no access policy the server doesn't generate tickets
658  if (mMode == EAccessMode::EveryOne)
659  {
660  conp->set_status(websocketpp::http::status_code::conflict,
661  "unable to generate ticket, no access policy set");
662  return;
663  }
664 
665  // Get request body
666  std::string body = conp->get_request_body();
667 
668  // Try to parse as JSON
669  rapidjson::Document document;
670  rapidjson::ParseResult parse_result = document.Parse(body.c_str());
671  if (!parse_result || !document.IsObject())
672  {
673  conp->set_status(websocketpp::http::status_code::bad_request,
674  "unable to parse as JSON");
675  return;
676  }
677 
678  // Extract user information, this field is required
679  if (!document.HasMember("user"))
680  {
681  conp->append_header("WWW-Authenticate", "NAPUserPass");
682  conp->set_status(websocketpp::http::status_code::unauthorized,
683  "missing required member: 'user");
684  return;
685  }
686 
687  // Extract pass information, this field is required
688  if (!document.HasMember("pass"))
689  {
690  conp->append_header("WWW-Authenticate", "NAPUserPass");
691  conp->set_status(websocketpp::http::status_code::unauthorized,
692  "missing required member: 'pass");
693  return;
694  }
695 
696  // Create ticket
697  nap::WebSocketTicket ticket;
698 
699  // Populate and initialize
700  ticket.mID = math::generateUUID();
701  ticket.mUsername = document["user"].GetString();
702  ticket.mPassword = document["pass"].GetString();
703  utility::ErrorState error;
704  if (!ticket.init(error))
705  {
706  conp->append_header("WWW-Authenticate", "NAPUserPass");
707  conp->set_status(websocketpp::http::status_code::unauthorized,
708  utility::stringFormat("invalid username or password: %s", error.toString().c_str()));
709  return;
710  }
711 
712  // If we only allow specific clients we extract the password here.
713  // The pass is used in combination with the username to create a validation hash.
714  if (mMode == EAccessMode::Reserved)
715  {
716  // Locate ticket, if there is no tick that matches the request
717  // The username or password is wrong and the request invalid
718  if (mClientHashes.find(ticket.toHash()) == mClientHashes.end())
719  {
720  conp->append_header("WWW-Authenticate", "NAPUserPass");
721  conp->set_status(websocketpp::http::status_code::unauthorized,
722  "invalid username or password");
723  return;
724  }
725  }
726 
727  // Convert ticket to binary blob
728  // This ticket can now be used to validate the request
729  std::string ticket_str;
730  if (!ticket.toBinaryString(ticket_str, error))
731  {
732  nap::Logger::error(error.toString());
733  conp->set_status(websocketpp::http::status_code::internal_server_error);
734  return;
735  }
736 
737  // Set ticket as body
738  conp->set_body(ticket_str);
739  conp->set_status(websocketpp::http::status_code::ok);
740  }
741 
742 
743  template<typename config>
745  {
746  // Get connection handle
747  std::error_code stdec;
748  auto conp = mEndPoint.get_con_from_hdl(con, stdec);
749  if (stdec)
750  {
751  nap::Logger::error(stdec.message());
752  conp->set_status(websocketpp::http::status_code::internal_server_error);
753  return false;
754  }
755 
756  // Make sure we accept new connections
757  if (!acceptsNewConnections())
758  {
759  conp->set_status(websocketpp::http::status_code::forbidden,
760  "client connection count exceeded");
761  return false;
762  }
763 
764  // Get sub-protocol field
765  const std::vector<std::string>& sub_protocol = conp->get_requested_subprotocols();
766 
767  // When every client connection is allowed no sub-protocol field must be defined.
768  if (mMode == EAccessMode::EveryOne)
769  {
770  if (sub_protocol.empty())
771  return true;
772 
773  // Sub-protocol requested but can't authenticate.
774  conp->set_status(websocketpp::http::status_code::not_found, "invalid sub-protocol");
775  return false;
776  }
777 
778  // We have tickets and therefore specific clients we accept.
779  // Use the sub_protocol to extract client information
780  if (sub_protocol.empty())
781  {
782  conp->set_status(websocketpp::http::status_code::forbidden,
783  "unable to extract ticket");
784  return false;
785  }
786 
787  // Extract ticket
788  conp->select_subprotocol(sub_protocol[0]);
789 
790  // Convert from binary into string
791  utility::ErrorState error;
793  WebSocketTicket* client_ticket = WebSocketTicket::fromBinaryString(sub_protocol[0], result, error);
794  if (client_ticket == nullptr)
795  {
796  conp->set_status(websocketpp::http::status_code::forbidden,
797  "first sub-protocol argument is not a valid ticket object");
798  return false;
799  }
800 
801  // Valid ticket was extracted, allowed access
802  if (mMode == EAccessMode::Ticket)
803  return true;
804 
805  // Locate ticket
806  if (mClientHashes.find(client_ticket->toHash()) == mClientHashes.end())
807  {
808  conp->set_status(websocketpp::http::status_code::forbidden,
809  "not a valid ticket");
810  return false;
811  }
812 
813  // Welcome!
814  return true;
815  }
816 
817 
818  template<typename config>
820  {
821  return true;
822  }
823 
824 
825  template<typename config>
827  {
828  std::lock_guard<std::mutex> lock(mConnectionMutex);
829  bool success = true;
830  for (auto& connection : mConnections)
831  {
832  std::error_code stdec;
833  mEndPoint.close(connection, websocketpp::close::status::going_away, "disconnected", stdec);
834  if (stdec)
835  {
836  error.fail(stdec.message());
837  success = false;
838  }
839  }
840  mConnections.clear();
841  return success;
842  }
843 
844 
845  template<typename config>
847  {
848  std::unique_lock<std::mutex> lock(mListenerMutex);
849  mListeners.push_back(&server);
850  }
851 
852 
853  template<typename config>
855  {
856  std::unique_lock<std::mutex> lock(mListenerMutex);
857  mListeners.erase(std::remove(mListeners.begin(), mListeners.end(), &server), mListeners.end());
858  }
859 
860 
861 }
nap::rtti::Object::mID
std::string mID
Property: 'mID' unique name of the object. Used as an identifier by the system.
Definition: object.h:82
nap::WebSocketConnection
Definition: websocketconnection.h:27
nap::WebSocketServerEndPointSetup::mAccessLogLevel
uint32 mAccessLogLevel
Log client / server connection data.
Definition: websocketserverendpoint.h:228
nap::WebSocketTicket::mUsername
std::string mUsername
Property: 'UserName'.
Definition: websocketticket.h:56
nap::WebSocketServerEndPointSetup::onPing
bool onPing(wspp::ConnectionHandle con, std::string msg)
Definition: websocketserverendpoint.h:819
nap::WebSocketServerEndPointSetup::mEndPoint
websocketpp::server< config > mEndPoint
The websocketpp server end-point.
Definition: websocketserverendpoint.h:226
nap::wspp::OpCode
websocketpp::frame::opcode::value OpCode
web-socket op codes
Definition: wspp.h:20
nap::WebSocketServerEndPointSetup::onValidate
bool onValidate(wspp::ConnectionHandle con)
Definition: websocketserverendpoint.h:744
nap::WebSocketServerEndPointSetup::~WebSocketServerEndPointSetup
~WebSocketServerEndPointSetup() override
Definition: websocketserverendpoint.h:479
nap::WebSocketTicket
Definition: websocketticket.h:20
nap::WebSocketServerEndPointSetup::start
bool start(nap::utility::ErrorState &error) override
Definition: websocketserverendpoint.h:293
nap::WebSocketServerEndPointSetup::mListenerMutex
std::mutex mListenerMutex
Ensures registration is thread safe.
Definition: websocketserverendpoint.h:231
nap::WebSocketServerEndPointSetup::mRunning
bool mRunning
If the server is accepting and managing client connections.
Definition: websocketserverendpoint.h:223
nap::WebSocketServerEndPointSetup::onConnectionClosed
void onConnectionClosed(wspp::ConnectionHandle connection)
Definition: websocketserverendpoint.h:557
nap::uint8
uint8_t uint8
Definition: numeric.h:16
nap::WebSocketServerEndPointSetup::mServerTask
std::future< void > mServerTask
The background server thread.
Definition: websocketserverendpoint.h:229
nap::SecureWebSocketServerEndPoint::mPassphrase
std::string mPassphrase
Property: "Passphrase" password for the private key, only required when key is generated with one.
Definition: websocketserverendpoint.h:261
nap::WebSocketServerEndPointSetup::acceptsNewConnections
bool acceptsNewConnections() override
Definition: websocketserverendpoint.h:427
nap::WebSocketServerEndPointSetup::stop
void stop() override
Definition: websocketserverendpoint.h:446
nap::WebSocketServerEndPointSetup::getHostName
std::string getHostName(const WebSocketConnection &connection) override
Definition: websocketserverendpoint.h:396
nap::WebSocketTicket::toHash
WebSocketTicketHash toHash() const
nap::utility::ErrorState
Definition: errorstate.h:19
nap::WebSocketServerEndPointSetup::mListeners
std::vector< IWebSocketServer * > mListeners
All registered web socket servers.
Definition: websocketserverendpoint.h:232
nap::WebSocketServerEndPointSetup::mConnectionMutex
std::mutex mConnectionMutex
Ensures connections are added / removed safely.
Definition: websocketserverendpoint.h:224
nap::uint32
uint32_t uint32
Definition: numeric.h:20
nap::WebSocketServerEndPointSetup
Definition: websocketconnection.h:16
nap::WebSocketServerEndPointSetup::init
bool init(utility::ErrorState &errorState) override
Definition: websocketserverendpoint.h:486
nap::SecureWebSocketServerEndPoint::mPrivateKeyFile
std::string mPrivateKeyFile
Property: "PrivateKeyFile" TLS private key file (.key)
Definition: websocketserverendpoint.h:260
nap::WebSocketServerEndPointSetup::getHostNames
void getHostNames(std::vector< std::string > &outHosts) override
Definition: websocketserverendpoint.h:404
nap::utility::ErrorState::fail
void fail(T &&errorMessage)
Definition: errorstate.h:73
nap::wspp::ConnectionHandle
std::weak_ptr< void > ConnectionHandle
server / client connection
Definition: wspp.h:18
nap::WebSocketServerEndPointSetup::onHTTP
void onHTTP(wspp::ConnectionHandle con)
Definition: websocketserverendpoint.h:622
nap::WebSocketMessage
Definition: websocketmessage.h:29
nap::utility::ErrorState::toString
const std::string toString() const
nap::WebSocketServerEndPointSetup::onConnectionFailed
void onConnectionFailed(wspp::ConnectionHandle connection)
Definition: websocketserverendpoint.h:597
nap::computeWebSocketLogLevel
NAPAPI uint32 computeWebSocketLogLevel(EWebSocketLogLevel level)
nap::WebSocketServerEndPointSetup::broadcast
bool broadcast(const std::string &message, EWebSocketOPCode code, nap::utility::ErrorState &error) override
Definition: websocketserverendpoint.h:368
nap::WebSocketServerEndPointSetup::mLogLevel
uint32 mLogLevel
Converted library log level.
Definition: websocketserverendpoint.h:227
nap::rtti::DeserializeResult
Definition: deserializeresult.h:40
nap::WebSocketTicket::toBinaryString
bool toBinaryString(std::string &outString, utility::ErrorState &error)
nap::WebSocketServerEndPointSetup::disconnect
bool disconnect(nap::utility::ErrorState &error)
Definition: websocketserverendpoint.h:826
nap::WebSocketServerEndPointSetup::send
bool send(const WebSocketConnection &connection, const std::string &message, EWebSocketOPCode code, nap::utility::ErrorState &error) override
Definition: websocketserverendpoint.h:340
nap::WebSocketServerEndPointSetup::mClientHashes
std::unordered_set< WebSocketTicketHash > mClientHashes
Accepted client ticket hashes.
Definition: websocketserverendpoint.h:225
nap::WebSocketServerEndPointSetup::registerListener
void registerListener(IWebSocketServer &server) override
Definition: websocketserverendpoint.h:846
nap::wspp::MessagePtr
Config::message_type::ptr MessagePtr
internal message format
Definition: wspp.h:19
nap::SecureWebSocketServerEndPoint::mCertificateFile
std::string mCertificateFile
Property: "CertificateFile" TLS certificate file (.pem)
Definition: websocketserverendpoint.h:259
nap::WebSocketServerEndPointSetup::unregisterListener
void unregisterListener(IWebSocketServer &server) override
Definition: websocketserverendpoint.h:854
nap::WebSocketTicket::mPassword
std::string mPassword
Property: 'Password'.
Definition: websocketticket.h:57
nap::WebSocketServerEndPointSetup::isOpen
bool isOpen() const override
Definition: websocketserverendpoint.h:333
nap::SecureWebSocketServerEndPoint::ETLSMode
ETLSMode
Definition: websocketserverendpoint.h:252
nap
Definition: templateapp.h:17
nap::uint16
uint16_t uint16
Definition: numeric.h:18
nap::WebSocketServerEndPointSetup::run
void run()
Definition: websocketserverendpoint.h:438
nap::SecureWebSocketServerEndPoint
Definition: websocketserverendpoint.h:244
nap::IWebSocketServer
Definition: websocketserver.h:22
nap::WebSocketServerEndPointSetup::onMessageReceived
void onMessageReceived(wspp::ConnectionHandle con, wspp::MessagePtr msg)
Definition: websocketserverendpoint.h:613
nap::WebSocketTicket::init
virtual bool init(utility::ErrorState &errorState) override
nap::EWebSocketOPCode
EWebSocketOPCode
Definition: websocketutils.h:29
nap::WebSocketServerEndPointSetup::onConnectionOpened
void onConnectionOpened(wspp::ConnectionHandle connection)
Definition: websocketserverendpoint.h:535
nap::WebSocketServerEndPointSetup::getConnectionCount
int getConnectionCount() override
Definition: websocketserverendpoint.h:420
nap::WebSocketServerEndPointSetup::mConnections
std::vector< wspp::ConnectionHandle > mConnections
List of all low level connections.
Definition: websocketserverendpoint.h:230