
/*---------------------------------------------------------------------------*/
/* http_options_handler.cpp                                                  */
/* copyright (c) innovaphone 2016                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

#include "platform/platform.h"

#include "common/os/iomux.h"

#include "common/ilib/hash.h"
#include "common/ilib/base64.h"
#include "common/lib/httplib.h"

#include "common/interface/time.h"
#include "common/interface/random.h"
#include "common/interface/socket.h"
#include "common/interface/websocket_client.h"
#include "common/interface/webserver_plugin.h"
#include "common/lib/appservice.h"

#include "common/service/webserver_shared/inno_error_pages.h"
#include "common/service/webserver_shared/webserver_internal.h"
#include "common/service/webserver_shared/http_auth_digest.h"
#include "common/service/webserver_shared/http_digest_host.h"

#include "types.h"
#include "apparguments.h"
#include "webserver.h"
#include "http_method_handler.h"
#include "http_connection.h"
#include "http_datasource.h"
#include "http_options_handler.h"


HTTPOptionsHandler::HTTPOptionsHandler(UHTTPMethodHandler * const user, class HTTPRegisteredPath * reqPathObj, HTTPDataSource * dataSource, ISocket * const remoteSocket, IInstanceLog * const log, connection_flags_t connFlags)
    : HTTPMethodHandler("HTTPOptionsHandler", user, reqPathObj, dataSource, remoteSocket, log, connFlags)
{
    this->respFieldValue = NULL;
}


HTTPOptionsHandler::~HTTPOptionsHandler()
{
    free(respFieldValue);
}


http_method_init_t HTTPOptionsHandler::OnHandlerInit(const HTTPParser * parser, byte * buffer, size_t size)
{
    ExtendedHeader extHeader(this->log, this->DataSource()->ProtocolVersion());
    extHeader.SetRequestPath(this->RequestPath(), this->RequestPathLen());
    extHeader.SetRegisteredPathForRequest(this->RegisteredPathForRequest(), this->RegisteredPathForRequestLen());
    extHeader.SetConnectionFlags(this->connFlags);
    extHeader.SetHeaderFields(parser);
    extHeader.SetRemoteAddress(this->Socket());
    extHeader.Encode(this->User()->GetConnectionID());

    DataSource()->SendMessage("HTTPOptionsHandler", this->User()->GetConnectionID(), WSM_OPTIONS_REQUEST, 0, extHeader.Buffer(), extHeader.BufferSize());

    return HTTP_INIT_DONE;
}


void HTTPOptionsHandler::OnSendMetaData(dword info, ExtendedHeader & extHeader)
{
    if (info != WSR_INT_UNDEFINED) {
        this->HandleCancel(info, extHeader);
//        this->User()->HandleControlMessage(ResultHeader(), info, &extHeader);
    }
}


void HTTPOptionsHandler::OnPrepareHeader()
{
	std::string response = this->GetStatusCodeStr(HTTPLib::HTTP_200);
    ResultHeader()->SetHTTPResult(response.c_str());
    ResultHeader()->SetContentSize(0);
    ResultHeader()->SetContentType("httpd/unix-directory");
    // The list of options allowed will be send from the IWebserverPlugin as a header field which will be added automatically 
    // by the underlying HTTPMessageHandler.
    this->ShutdownSocketOnClose();
}
