/* libzzinet
 *
 * This program is distributed under the GNU General Public License, version 2.
 * A copy of this license is included with this source.
 *
 * Copyright 2000-2006, Toni Thomsson <toni@tonjac.org> 
*/

#ifndef zz_http_server_h
#define zz_http_server_h

#include <zz_socket.h>
#include <zz_http_request.h>
#include <zz_log.h>
#include <zz_export.h>
#include <zz_access_log.h>
#include <zz_win_threadmutex.h>

// RFC1945, status koder
typedef enum
{
    ZZ_HTTP_STATUS_INFO,
    ZZ_HTTP_STATUS_OK,
    ZZ_HTTP_STATUS_BAD_REQUEST,
    ZZ_HTTP_STATUS_FORBIDDEN,
    ZZ_HTTP_STATUS_NOT_FOUND,
    ZZ_HTTP_STATUS_AUTHORIZATION,
    ZZ_HTTP_STATUS_INTERNAL_SERVER_ERROR,
    ZZ_HTTP_STATUS_INVALID

} ZZ_HTTP_STATUS;

// RFC1945 defined response codes
static char* zz_http_status[] = 
{ 
    "100 Info",
    "200 OK", 
    "400 Bad request",
    "403 Forbidden",
    "404 Not found",
    "401 Unauthorized",
    "500 Internal server error",
    "<not supported>"
}; 

// RFC1945, Innehållstyper
typedef enum
{
    ZZ_HTTP_CONTENT_TYPE_M3U,
    ZZ_HTTP_CONTENT_TYPE_MP3,
    ZZ_HTTP_CONTENT_TYPE_CSS,
    ZZ_HTTP_CONTENT_TYPE_TEXT,
    ZZ_HTTP_CONTENT_TYPE_HTML,
    ZZ_HTTP_CONTENT_TYPE_GIF,
    ZZ_HTTP_CONTENT_TYPE_BITMAP,
    ZZ_HTTP_CONTENT_TYPE_JPEG,
    ZZ_HTTP_CONTENT_TYPE_PJPEG,
    ZZ_HTTP_CONTENT_TYPE_ZIP,
    ZZ_HTTP_CONTENT_TYPE_ALL,
    ZZ_HTTP_CONTENT_TYPE_INVALID

} ZZ_HTTP_CONTENT_TYPE;

static char* zz_http_content_type[] =
{
    "audio/x-mpegurl",
    "audio/mpeg",
    "text/css",
    "text/plain",
    "text/html",
    "image/gif", 
    "image/x-xbitmap", 
    "image/jpeg", 
    "image/pjpeg",
    "zip/gzip",
    "*/*",
    "<not supported>"
};

/*
    Description:
    Easy HTTP server (HTTP/1.0) 
    
    Remarks:
    Ingen 100% komplett implementation

    Author: 
    Toni Thomsson, toni@tonjac.org

    Library:
    libzzinet.a (HPUX) libzzinet.lib (win32)

    Platform:
    HPUX, win32
*/
class ZZ_API CzzHTTPServer
{
public:

    CzzHTTPServer( CzzAccessLog* log );

    /*
        Description: Skapar ett HTTP-server objekt
    */
    CzzHTTPServer( const char* port,    // IN, port som servern lyssnar på
                    int que             // IN, antal anrop som kan köas upp 
                    );

    CzzHTTPServer( const char* port,    // IN, port som servern lyssnar på
                    int que,            // IN, antal anrop som kan köas upp 
                    CzzAccessLog* accesslog );

    // Description: Destruktor
    virtual ~CzzHTTPServer();


    /*
        Description: 
        Väntar på anrop från klienter

        Returns:
        Ett anropsobjekt

        Throws:
        CzzException
    */
    virtual CzzHTTPRequest* waitForRequest( void );

    /*
        Description: 
        Skicka svar till klient med "standard" headers

        Throws:
        CzzException
    */
    void reply( CzzHTTPRequest* req,
                ZZ_HTTP_STATUS status,              // IN, status
                ZZ_HTTP_CONTENT_TYPE content_type,  // IN, innehållstyp
                CzzBuffer& data,                    // IN, data som skall skickas
                const CzzString& err_msg = ""       // IN, ev felmeddelande
                );

    void reply( CzzHTTPRequest* req, 
            ZZ_HTTP_STATUS status, 
            const char* content_type, 
            CzzBuffer& data, const 
            CzzString& err_msg = "" );

    /*
        Description: 
        Skicka svar till klient med valfria headers

        Throws:
        CzzException
    */
    void reply( CzzHTTPRequest* req,
                ZZ_HTTP_STATUS status,              // IN, status
                CzzBuffer& data,                    // IN, data som skall skickas
                CzzHTTPHeaders& headers,            // IN, headers
                const CzzString& err_msg = ""       // IN, ev felmeddelande
                );

    

protected:
    
    CzzLog m_Log;
    CzzAccessLog* m_AccessLog;

private:

    int receiveHeaders( CzzBuffer* buff, int* read_bytes, CzzSocket* reqsock );
    CzzString getDate( void );

    CzzSocket* m_Socket;
    static CzzWinThreadMutex m_Mutex;
};

#endif // zz_http_server_h