/* * This file is part of rasdaman community. * * Rasdaman community is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rasdaman community is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rasdaman community. If not, see . * * Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / rasdaman GmbH. * * For more information please see * or contact Peter Baumann via . */ /*------------------------------------------------------------------------*/ /* http.c - reworked HTTP communication main loop. */ /*------------------------------------------------------------------------*/ #include "defs.h" #include "protos.h" #include "server.h" #include "http-defs.h" #include "http.h" /* * Release ClientBase */ void releaseClientBase(struct ClientBase *cb) { // free Host free(cb->Host.Name); // free Socket // struct sockaddr_in Socket; // free TimeOut // struct timeval TimeOut; // free Request free(cb->Request.HeadBuff); free(cb->Request.BodyBuff); struct MsgHeader *dummy = NULL; while(cb->Request.First != NULL) { dummy = cb->Request.First->Next; //free(cb->Request.First->Content); free(cb->Request.First); cb->Request.First = dummy; } free(cb->Request.Body); free(cb->Request.Line.Vanilla); // free Response free(cb->Response.Head); free(cb->Response.Body); } /****** http/HandleRequest *************************************************** * * NAME * HandleRequest -- main function for communication processing. * * SYNOPSIS * void HandleRequest( struct ClientBase *Client, * SubServerPtr SubServerList ); * * FUNCTION * This is the main function which handles the HTTP communication. * It calls successivley the functions for handling the request from * the client, opening the sockets to the sub-servers and sending * the rewritten requests to them, handling the responses and finally * sending a response to the client. * * INPUTS * Client - Data structure which holds various informations about * the client. * SubServerList - The head to a list of all sub-server data structures. * * NOTES * "Client" and "SubServerList" must be valid - they will not be * checked. Since "Client" have to be valid in the previous call to * "Accept()" this shouldn't be much of a problem... * * This is "rewritten from scratch" version of "HandleRequest()" * since the old version seemed not suitable enough for expansion * to handle more error conditions in the communication, and for * integration of more features. * * BUGS * Various left. Especially the authorization mechanism doesn't work * (yet). Also, some aspects of the HTTP aren't handled gracefully * (HTTP/0.9 messages, handling of other methods than GET, HEAD and * POST, etc.). * ****************************************************************************** * */ void HandleRequest( struct ClientBase *Client ) { struct ToDoArgs ToDo; int RespState; ToDo.What = DO_NOTHING; ToDo.Which.Code = REALLY_NOTHING; Client->Comm.ConnStatus = CONN_OPEN; while( Client->Comm.ConnStatus == CONN_OPEN ) { //LogMsg( LG_SERVER, DEBUG, "DEBUG: HandleRequest(): Reading Request."); GetRequest( Client ); //LogMsg( LG_SERVER, DEBUG, "DEBUG: HandleRequest(): Parsing Request."); ParseReqHeader( &Client->Request ); //LogMsg( LG_SERVER, DEBUG, "DEBUG: HandleRequest(): Interpreting Request."); InterpreteRequest( Client, &ToDo ); switch( ToDo.What ) { case DO_SEND_RESPONSE: //LogMsg( LG_SERVER, DEBUG, "DEBUG: HandleRequest(): doing InterpreteRequest."); InterpretePOSTRequest( Client ); //LogMsg( LG_SERVER, DEBUG, "DEBUG: HandleRequest(): doing CreateRasResponse."); CreateRasResponse( &Client->Comm, Client ); /* LogMsg( LG_SERVER, DEBUG, "DEBUG: SendResponse() for Request: \"%s\".", Client->Request.Line.Vanilla ); */ SendHTTPMsg( Client->SockFD, &Client->Response ); WriteAccessLog( Client ); LogMsg( LG_SERVER, DEBUG, "DEBUG: HandleRequest(): SEND_RESPONSE done."); break; case DO_SEND_ERROR: LogMsg( LG_SERVER, DEBUG, "DEBUG: HandleRequest(): doing SEND_ERROR." ); Client->RespStatus = ToDo.Which.Code; LogMsg( LG_SERVER, DEBUG, "DEBUG: CreateHTTPError( %d, -, %p )...", Client->RespStatus, &Client->Response ); CreateHTTPError( Client->RespStatus, &Client->Comm, &Client->Response ); LogMsg( LG_SERVER, DEBUG, "DEBUG: CreateHTTPError() done." ); LogMsg( LG_SERVER, DEBUG, "DEBUG: SendResponse()..." ); SendResponse( Client ); LogMsg( LG_SERVER, DEBUG, "DEBUG: SendResponse() done." ); LogMsg( LG_SERVER, DEBUG, "DEBUG: Write*Log()..." ); WriteAccessLog( Client ); LogMsg( LG_SERVER, DEBUG, "DEBUG: WriteLog() done." ); LogMsg( LG_SERVER, DEBUG, "DEBUG: HandleRequest(): SEND_ERROR done."); break; case DO_SHUTDOWN: LogMsg( LG_SERVER, DEBUG, "DEBUG: HandleRequest(): doing SHUTDOWN."); close( Client->SockFD ); LogMsg( LG_SERVER, DEBUG, "DEBUG: HandleRequest(): SHUTDOWN done."); break; default: LogMsg( LG_SERVER, DEBUG, "DEBUG: HandleRequest(): doing UNDEFINED ACTION."); ErrorMsg( E_PRIV, ERROR, "ERROR: HandleRequest(): Undefined action!" ); Client->RespStatus = STATUS_Internal_Server_Error; CreateHTTPError( Client->RespStatus, &Client->Comm, &Client->Response ); SendResponse( Client ); WriteAccessLog( Client ); LogMsg( LG_SERVER, DEBUG, "DEBUG: HandleRequest(): UNDEFINED ACTION done."); break; } releaseClientBase(Client); } }