
/*---------------------------------------------------------------------------*/
/* http_connection.h                                                         */
/* copyright (c) innovaphone 2015                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

#define CONNECTION_DEFAULT_RECV_SIZE           8192

class HTTPConnection : public USocket, public UHTTPMethodHandler, public UHTTPParser, public btree, public istd::listElement<HTTPConnection> {
private:
    class Webserver * const webserver;
    class IInstanceLog * const log;
    class ISocket * remoteSocket;
    class SocketProxy * wsSocket;
    class IWebsocketClient * websocketClient;
    dword connectionID;

    class HTTPParser * parser;
    class HTTPMethodHandler * curMethodHandler;
    class HTTPDataSource * curDataSource;
    class HTTPRegisteredPath * curRegisteredPathObject;
    bool connectionRegisteredToDataSource;

    class HTTPHeader * resultHeader;
    bool isClosing;
    bool datasourceLost;
    char * buffer;

    HTTPAuthDigest * authObject;

    char * postBoundary;
    size_t postBoundaryLen;
    wsr_type_t postDataType;
    byte * postDataBuffer;
    byte * postNextPartStart;
    char * postTarget;

    connection_flags_t connectionFlags;
    connection_flags_t connectionFlagsBase; // The base flags for each new connection.

    void RedirectRequestToTLS();
    void RedirectRequestToDefaultPath();
    bool RootRequest(const char * target);

    void ShutDownWithError(const HTTPLib::http_result_t * httpError);
    bool CheckConnectionParameters();

    HTTPMethodHandler * CreateMethodHandlerForRequest(byte * buffer, size_t len);
    void HandleSysclientAuthentication(byte * buffer, size_t len);

    virtual int btree_compare(void * key) override;
    virtual int btree_compare(class btree * b) override;

public:
    HTTPConnection(class Webserver * const webserver, class IInstanceLog * const log, dword connectionID, bool isTLS, bool redirectToTLS, bool localHost);
    virtual ~HTTPConnection();

    void DataSourceClosed();
    HTTPMethodHandler * GetCurrentMethodHandler() { return curMethodHandler; }

    void Shutdown();
    void ShutdownTimeout();

    virtual dword GetConnectionID() override { return connectionID; }
    virtual void HTTPHandlerShutdown(HTTPDataSource * const dataSource, bool closeConnection, const HTTPLib::http_result_t* resultMsg = nullptr) override;
    virtual bool HandleControlMessage(HTTPHeader * resultHeader, dword reason, class ExtendedHeader * extHeader = nullptr) override;
    virtual class HTTPDigestHostManager * GetDigestHostManager() override;
    virtual class HTTPAuthDigest * GetAuthenticationObject() override;
    virtual void SetAuthenticationObject(HTTPAuthDigest * authObj) override;
    virtual void RegisterWebsocketForPing(class UWebserverWebsocket * websocket) override;
    virtual void UnregisterWebsocketForPing(class UWebserverWebsocket * websocket) override;

    virtual void SocketAcceptComplete(class ISocket * const socket) override;
    virtual void SocketShutdown(class ISocket * const socket, shutdownreason_t reason) override;
    virtual void SocketSendResult(class ISocket * const socket) override;
    virtual void SocketRecvResult(class ISocket * const socket, void * buf, size_t len) override;
    virtual void SocketRecvCanceled(ISocket * const socket, void * buf) override;

    virtual bool HTTPParserValidateRequest(class HTTPParser * httpParser) override;
};
