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

typedef struct {
    class HTTPDigestNonce * nonce;
    bool needStale;
} digest_nonce_t;


class HTTPAuthDigest : public istd::listElement<HTTPAuthDigest> {
private:
    class HTTPDigestHost * digestHost;
    bool serverNonceReused;
    class HTTPDigestNonce * serverNonce;
    char * rawString;
    HTTPLib::http_request_method_t reqMethod;

    char * dynUserName;
    char * dynPassword;

    const char * username;
    const char * realm;
    const char * nonce;
    const char * uri;
    const char * qop;
    const char * nc;
    const char * cnonce;
    const char * response;
    const char * opaque;

    byte * saveRequestBuffer;
    size_t saveRequestBufferSize;
    const class HTTPParser * saveParser;

public:
    HTTPAuthDigest();
    ~HTTPAuthDigest();

    void SetDigestHost(class HTTPDigestHost * dgHost);
    bool ParseAuthField(const HTTPParser * parser);
	bool ParseAuthField(const char * headerFieldData, HTTPLib::http_request_method_t reqMethod);
    bool VerifyAuthentication(const char * user, const char * password, const char * forURI);

    const char * GetUser() { return username; }
    class HTTPDigestHost * GetDigestHost();
    const char * GetServerOpaque();
    
    void ReadDigestNonce(digest_nonce_t & dn_out);
    HTTPDigestNonce * GetNonceObj() { return this->serverNonce; }

    void SaveParserAndBuffer(const class HTTPParser * parser, byte * buffer, size_t bufferSize)
    {
        this->saveParser = parser;
        this->saveRequestBuffer = buffer;
        this->saveRequestBufferSize = bufferSize;
    }

    void SetDynAuthData(const char * dynUser, const char * dynAuth);
    const char * DynUser() { return this->dynUserName; }
    const char * DynPassword() { return this->dynPassword; }

    const class HTTPParser * SaveParser() { return this->saveParser; }
    byte * SaveRequestBuffer() { return this->saveRequestBuffer; }
    size_t SaveRequestBufferSize() { return this->saveRequestBufferSize; }

    void ServerNonceInvalidated(class HTTPDigestNonce * nonce);
};
