
/*---------------------------------------------------------------------------*/
/* http_websocket_handler.h                                                  */
/* copyright (c) innovaphone 2016                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

class HTTPWebsocketHandler: public HTTPMethodHandler, public UWebsocketClient, public UWebserverWebsocket, public ISocket, public ISocketProvider {
private:
    USocket * proxySocketUser;
    IWebsocketClient * websocketClient;
    char * websocketKey;
    bool ignoreSendResult;
    bool hasPendingPing;

protected:
    virtual void OnPrepareHeader() override { /* No need for HTTPWebsocketHandler */ };
    virtual void OnSendMetaData(dword info, class ExtendedHeader & extHeader) override { /* No need for HTTPWebsocketHandler */ };
    virtual http_method_init_t OnHandlerInit(const class HTTPParser * parser, byte * buffer, size_t size) override;
    virtual void Ping() override;

public:
    HTTPWebsocketHandler(UHTTPMethodHandler * const user, class HTTPRegisteredPath * reqPathObj, class HTTPDataSource * dataSource, ISocket * const remoteSocket, IInstanceLog * const log, connection_flags_t connFlags);
    virtual ~HTTPWebsocketHandler();
    virtual void SocketSendResult() override;
    virtual void SocketRecvResult(byte * buffer, size_t size) override;
    virtual void SocketShutdown(shutdownreason_t reason) override;
    virtual void AppResponse(dword id, dword data, byte * buffer, size_t size) override;

    void WebsocketAcceptCompleteMsg(bool accepted);

    // Websocekt Callbacks
    virtual void WebsocketConnectComplete(IWebsocketClient * const websocket) override;
    virtual void WebsocketCloseComplete(IWebsocketClient * const websocket, closereason_t reason) override;
    virtual void WebsocketSendResult(IWebsocketClient * const websocket) override;
    virtual void WebsocketRecvResult(IWebsocketClient * const websocket, void * buf, size_t len, bool text, bool isFragment) override;
    virtual void * WebsocketRecvBuffer(size_t len) override;
    virtual void WebsocketRecvCanceled(IWebsocketClient * const websocket, void * buf) override;
    virtual void WebsocketPongReceived(IWebsocketClient * const websocket) override;
    virtual void ShutdownHandler() override;

    // The HTTPWebsocketHandler is also a socket proxy
    ISocketContext * CreateSocketContext(class IInstanceLog * const log);
    virtual ISocket * CreateSocket(class IIoMux * const iomux, USocket * const user, class IInstanceLog * const log, bool useIPv6, class ISocketContext * socketContext = NULL);
    virtual ISocket * UpgradeToTLSSocket(class ISocket * fromTCPSocket, IIoMux * const iomux, USocket * const user, IInstanceLog * const log, class ISocketContext * socketContext = NULL) override    {
        return nullptr;
    }

    virtual void Connect(const char * address, const char * serverName = NULL) override {}
    virtual void Bind(const char * localAddr = NULL, word localPort = 0) override {}
    virtual void Listen() override {};
    virtual void Accept(class USocket * remoteUser) override {}
    virtual void Shutdown() override;
    virtual void Send(const void * buf, size_t len) override;
    virtual void Recv(void * buf, size_t len, bool recvPartial = false) override;
    virtual void SetUser(class USocket * const user, bool * isServer, const char ** remoteAddress, const char ** serverName) override {}
};