tufao  1.3.0
An asynchronous web framework for C++ built on top of Qt
websocket.h
1 /*
2  Copyright (c) 2012 Vinícius dos Santos Oliveira
3 
4  Permission is hereby granted, free of charge, to any person obtaining a copy
5  of this software and associated documentation files (the "Software"), to deal
6  in the Software without restriction, including without limitation the rights
7  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  copies of the Software, and to permit persons to whom the Software is
9  furnished to do so, subject to the following conditions:
10 
11  The above copyright notice and this permission notice shall be included in all
12  copies or substantial portions of the Software.
13 
14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  SOFTWARE.
21  */
22 
23 #ifndef TUFAO_WEBSOCKET_H
24 #define TUFAO_WEBSOCKET_H
25 
26 #include "abstractmessagesocket.h"
27 #include "headers.h"
28 
29 #include <QtNetwork/QAbstractSocket>
30 
31 #if defined(NO_ERROR) && defined(_WIN32)
32 # define TUFAO_WINERROR_WORKAROUND
33 # undef NO_ERROR
34 #endif
35 
36 class QSslError;
37 
38 namespace Tufao {
39 
40 class HttpServerRequest;
41 
56 enum class WebSocketError
57 {
61  NO_ERROR = 0,
124  PROXY_AUTHENTICATION_REQUIRED,
186 };
187 
195 {
199  TEXT_MESSAGE,
204 };
205 
235 class TUFAO_EXPORT WebSocket : public AbstractMessageSocket
236 {
237  Q_OBJECT
238 public:
244  explicit WebSocket(QObject *parent = 0);
245 
249  ~WebSocket();
250 
272  bool connectToHost(const QHostAddress &address, quint16 port,
273  const QByteArray &resource,
274  const Headers &headers = Headers());
275 
281  bool connectToHost(const QHostAddress &address, const QByteArray &resource,
282  const Headers &headers = Headers());
283 
290  bool connectToHost(const QString &hostname, quint16 port,
291  const QByteArray &resource,
292  const Headers &headers = Headers());
293 
302  bool connectToHost(const QString &hostname, const QByteArray &resource,
303  const Headers &headers = Headers());
304 
316  bool connectToHostEncrypted(const QString &hostname, quint16 port,
317  const QByteArray &resource,
318  const Headers &headers,
319  const QList<QSslError> &ignoredSslErrors);
320 
324  bool connectToHostEncrypted(const QString &hostname, quint16 port,
325  const QByteArray &resource,
326  const Headers &headers = Headers());
327 
333  bool connectToHostEncrypted(const QString &hostname,
334  const QByteArray &resource,
335  const Headers &headers = Headers());
336 
346  bool connectToHostEncrypted(const QHostAddress &address, quint16 port,
347  const QByteArray &resource,
348  const Headers &headers = Headers());
349 
358  bool connectToHostEncrypted(const QHostAddress &address,
359  const QByteArray &resource,
360  const Headers &headers = Headers());
361 
401  bool startServerHandshake(const HttpServerRequest &request,
402  const QByteArray &head,
403  const Headers &headers = Headers());
404 
413  bool startServerHandshake(HttpServerRequest &request,
414  const Headers &headers = Headers());
415 
426  void setMessagesType(WebSocketMessageType type);
427 
435  WebSocketMessageType messagesType() const;
436 
440  WebSocketError error() const;
441 
445  QString errorString() const;
446 
455  QHostAddress peerAddress() const;
456 
465  quint16 peerPort() const;
466 
471  static QList<QByteArray> supportedProtocols(const Headers &headers);
472 
473 signals:
485  void pong(QByteArray data);
486 
487 public slots:
488  void close() override;
489  bool sendMessage(const QByteArray &msg) override;
490 
498  bool sendBinaryMessage(const QByteArray &msg);
499 
507  bool sendUtf8Message(const QByteArray &msg);
508 
518  bool ping(const QByteArray &data);
519 
520 private slots:
521  void onSocketError(QAbstractSocket::SocketError error);
522  void onSslErrors(const QList<QSslError> &errors);
523  void onConnected();
524  void onReadyRead();
525  void onDisconnected();
526 
527 private:
528  void connectToHost(QAbstractSocket *socket, const QByteArray &resource,
529  const Headers &headers = Headers());
530 
531  bool isResponseOkay();
532  void onClientHandshakeError();
533 
534  void close(quint16 code);
535 
536  void readData(const QByteArray &data);
537  void parseBuffer();
538  bool parseFrame();
539  bool parseSize16();
540  bool parseSize64();
541  bool parseMaskingKey();
542  bool parsePayloadData();
543 
544  void decodeFragment(QByteArray &fragment);
545  void evaluateControlFrame();
546 
547  struct Priv;
548  Priv *priv;
549 };
550 
551 } // namespace Tufao
552 
553 #if defined(TUFAO_WINERROR_WORKAROUND)
554 # define NO_ERROR 0L
555 # undef TUFAO_WINERROR_WORKAROUND
556 #endif
557 
558 #endif // TUFAO_WEBSOCKET_H
This class represents a WebSocket connection.
Definition: websocket.h:235
See QAbstractSocket::HostNotFoundError.
See QAbstractSocket::RemoteHostClosedError.
WebSocketError
This enum describes the possible erros tha can occur.
Definition: websocket.h:56
See QAbstractSocket::ProxyConnectionRefusedError.
The Tufao::HttpServer represents a HTTP request received by Tufao::HttpServer.
Definition: httpserverrequest.h:54
See QAbstractSocket::ProxyConnectionClosedError.
See QAbstractSocket::SocketTimeoutError.
WebSocketMessageType
This enum represents the possible message's types that WebSocket supports.
Definition: websocket.h:194
See QAbstractSocket::SslHandshakeFailedError.
See QAbstractSocket::ConnectionRefusedError.
The Tufao::AbstractMessageSocket class represents a socket that sends and receives messages...
Definition: abstractmessagesocket.h:50
This is the namespace where all Tufão facilities are grouped.
Definition: abstracthttpserverrequesthandler.h:30
See QAbstractSocket::SocketAccessError.
See QAbstractSocket::ProxyProtocolError.
It occurs when the remote peer (or an intermediary) violates the WebSocket protocol.
See QAbstractSocket::SocketResourceError.
It occurs when the server doesn't support WebSocket for the resource asked for (or for any resource a...
See QAbstractSocket::ProxyConnectionTimeoutError.
See QAbstractSocket::ProxyNotFoundError.
This class provides a representation of HTTP headers.
Definition: headers.h:42
See QAbstractSocket::NetworkError.
See QAbstractSocket::UnsupportedSocketOperationError.