⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 miniserver.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 C
📖 第 1 页 / 共 3 页
字号:
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation 
// All rights reserved. 
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions are met: 
//
// * Redistributions of source code must retain the above copyright notice, 
// this list of conditions and the following disclaimer. 
// * Redistributions in binary form must reproduce the above copyright notice, 
// this list of conditions and the following disclaimer in the documentation 
// and/or other materials provided with the distribution. 
// * Neither name of Intel Corporation nor the names of its contributors 
// may be used to endorse or promote products derived from this software 
// without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////

/************************************************************************
* Purpose: This file implements the functionality and utility functions
* used by the Miniserver module.
************************************************************************/

#ifndef _WIN32
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#else
#include <winsock2.h>
#include <Ws2tcpip.h>
#endif
#include "unixutil.h"
#include "ithread.h"

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include "ssdplib.h"

#include "util.h"
#include "miniserver.h"
#include "ThreadPool.h"
#include "httpreadwrite.h"
#include "statcodes.h"
#include "upnp.h"
#include "upnpapi.h"
#include "gena_ctrlpt.h"

#define APPLICATION_LISTENING_PORT 0 //49152

struct mserv_request_t {
    int connfd;                 // connection handle
    struct in_addr foreign_ip_addr;
    unsigned short foreign_ip_port;
};

typedef enum { MSERV_IDLE, MSERV_RUNNING, MSERV_STOPPING } MiniServerState;

unsigned short miniStopSockPort;

////////////////////////////////////////////////////////////////////////////
// module vars
static MiniServerCallback gGetCallback = NULL;
static MiniServerCallback gSoapCallback = NULL;
static MiniServerCallback gGenaCallback = NULL;
static MiniServerState gMServState = MSERV_IDLE;

/************************************************************************
*	Function :	SetHTTPGetCallback
*
*	Parameters :
*		MiniServerCallback callback ; - HTTP Callback to be invoked 
*
*	Description :	Set HTTP Get Callback
*
*	Return :	void
*
*	Note :
************************************************************************/
void
SetHTTPGetCallback( MiniServerCallback callback )
{
    gGetCallback = callback;
}

/************************************************************************
*	Function :	SetSoapCallback
*
*	Parameters :
*		MiniServerCallback callback ; - SOAP Callback to be invoked 
*
*	Description :	Set SOAP Callback
*
*	Return :	void
*
*	Note :
************************************************************************/
void
SetSoapCallback( MiniServerCallback callback )
{
    gSoapCallback = callback;
}

/************************************************************************
*	Function :	SetGenaCallback
*
*	Parameters :
*		MiniServerCallback callback ; - GENA Callback to be invoked
*
*	Description :	Set GENA Callback
*
*	Return :	void
*
*	Note :
************************************************************************/
void
SetGenaCallback( MiniServerCallback callback )
{
    gGenaCallback = callback;
}

/************************************************************************
*	Function :	dispatch_request
*
*	Parameters :
*		IN SOCKINFO *info ;		 Socket Information object.
*		http_parser_t* hparser ; HTTP parser object.
*
*	Description :	Based on the type pf message, appropriate callback 
*		is issued
*
*	Return : int ;
*		0 - On Success
*		HTTP_INTERNAL_SERVER_ERROR - Callback is NULL
*
*	Note :
************************************************************************/
static int
dispatch_request( IN SOCKINFO * info,
                  http_parser_t * hparser )
{
    MiniServerCallback callback;

    switch ( hparser->msg.method ) {
            //Soap Call
        case SOAPMETHOD_POST:
        case HTTPMETHOD_MPOST:
            callback = gSoapCallback;
            break;

            //Gena Call
        case HTTPMETHOD_NOTIFY:
        case HTTPMETHOD_SUBSCRIBE:
        case HTTPMETHOD_UNSUBSCRIBE:
            DBGONLY( UpnpPrintf
                     ( UPNP_INFO, MSERV, __FILE__, __LINE__,
                       "miniserver %d: got GENA msg\n", info->socket );
                 )
                callback = gGenaCallback;
            break;

            //HTTP server call
        case HTTPMETHOD_GET:
        case HTTPMETHOD_POST:
        case HTTPMETHOD_HEAD:
        case HTTPMETHOD_SIMPLEGET:
            callback = gGetCallback;
            break;

        default:
            callback = NULL;
    }

    if( callback == NULL ) {
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    callback( hparser, &hparser->msg, info );
    return 0;
}

/************************************************************************
*	Function :	handle_error
*
*	Parameters :
*		
*		IN SOCKINFO *info ;		Socket Inforamtion Object
*		int http_error_code ;	HTTP Error Code
*		int major ;				Major Version Number
*		int minor ;				Minor Version Number
*
*	Description :	Send Error Message
*
*	Return : void;
*
*	Note :
************************************************************************/
static XINLINE void
handle_error( IN SOCKINFO * info,
              int http_error_code,
              int major,
              int minor )
{
    http_SendStatusResponse( info, http_error_code, major, minor );
}

/************************************************************************
*	Function :	free_handle_request_arg
*
*	Parameters :
*		void *args ; Request Message to be freed
*
*	Description :	Free memory assigned for handling request and unitial-
*	-ize socket functionality
*
*	Return :	void
*
*	Note :
************************************************************************/
static void
free_handle_request_arg( void *args )
{
    struct mserv_request_t *request = ( struct mserv_request_t * )args;

    shutdown( request->connfd, SD_BOTH );
    UpnpCloseSocket( request->connfd );
    free( request );
}

/************************************************************************
*	Function :	handle_request
*
*	Parameters :
*		void *args ;	Request Message to be handled
*
*	Description :	Receive the request and dispatch it for handling
*
*	Return :	void
*
*	Note :
************************************************************************/
static void
handle_request( void *args )
{
    SOCKINFO info;
    int http_error_code;
    int ret_code;
    int major = 1;
    int minor = 1;
    http_parser_t parser;
    http_message_t *hmsg = NULL;
    int timeout = HTTP_DEFAULT_TIMEOUT;
    struct mserv_request_t *request = ( struct mserv_request_t * )args;
    int connfd = request->connfd;

    DBGONLY( UpnpPrintf
             ( UPNP_INFO, MSERV, __FILE__, __LINE__,
               "miniserver %d: READING\n", connfd );
         )
        //parser_request_init( &parser ); ////LEAK_FIX_MK
        hmsg = &parser.msg;

    if( sock_init_with_ip( &info, connfd, request->foreign_ip_addr,
                           request->foreign_ip_port ) != UPNP_E_SUCCESS ) {
        free( request );
        httpmsg_destroy( hmsg );
        return;
    }
    // read
    ret_code = http_RecvMessage( &info, &parser, HTTPMETHOD_UNKNOWN,
                                 &timeout, &http_error_code );
    if( ret_code != 0 ) {
        goto error_handler;
    }

    DBGONLY( UpnpPrintf
             ( UPNP_INFO, MSERV, __FILE__, __LINE__,
               "miniserver %d: PROCESSING...\n", connfd );
         )
        // dispatch
        http_error_code = dispatch_request( &info, &parser );
    if( http_error_code != 0 ) {
        goto error_handler;
    }

    http_error_code = 0;

  error_handler:
    if( http_error_code > 0 ) {
        if( hmsg ) {
            major = hmsg->major_version;
            minor = hmsg->minor_version;
        }
        handle_error( &info, http_error_code, major, minor );
    }

    DBGONLY( UpnpPrintf
             ( UPNP_INFO, MSERV, __FILE__, __LINE__,
               "miniserver %d: COMPLETE\n", connfd );
         )
        sock_destroy( &info, SD_BOTH ); //should shutdown completely

    httpmsg_destroy( hmsg );
    free( request );
}

/************************************************************************
*	Function :	schedule_request_job
*
*	Parameters :
*		IN int connfd ;	Socket Descriptor on which connection is accepted
*		IN struct sockaddr_in* clientAddr ;	Clients Address information
*
*	Description :	Initilize the thread pool to handle a request.
*		Sets priority for the job and adds the job to the thread pool
*
*
*	Return :	void
*
*	Note :

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -