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

📄 miniserver.cpp

📁 UPnP的SDK源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////// Copyright (c) 2000 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./////////////////////////////////////////////////////////////////////////////// $Revision: 1.2 $// $Date: 2001/08/15 18:17:31 $#include "../../inc/tools/config.h"#if EXCLUDE_MINISERVER == 0#include <arpa/inet.h>#include <netinet/in.h>#include <pthread.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/wait.h>#include <unistd.h>#include <assert.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <genlib/util/utilall.h>#include <genlib/util/util.h>#include <genlib/miniserver/miniserver.h>#include <genlib/tpool/scheduler.h>#include <genlib/tpool/interrupts.h>#include "upnp.h"#include "tools/config.h"// read timeout#define TIMEOUT_SECS 30enum MiniServerState { MSERV_IDLE, MSERV_RUNNING, MSERV_STOPPING };CREATE_NEW_EXCEPTION_TYPE( MiniServerReadException, BasicException, "MiniServerReadException" )enum READ_EXCEPTION_CODE {        RCODE_SUCCESS               =  0,        RCODE_NETWORK_READ_ERROR    = -1,        RCODE_MALFORMED_LINE        = -2,        RCODE_LENGTH_NOT_SPECIFIED  = -3,        RCODE_METHOD_NOT_ALLOWED    = -4,        RCODE_INTERNAL_SERVER_ERROR = -5,        RCODE_METHOD_NOT_IMPLEMENTED = -6,        RCODE_TIMEDOUT              = -7,        };        enum HTTP_COMMAND_TYPE { CMD_HTTP_GET,        CMD_SOAP_POST, CMD_SOAP_MPOST,        CMD_GENA_SUBSCRIBE, CMD_GENA_UNSUBSCRIBE, CMD_GENA_NOTIFY,        CMD_HTTP_UNKNOWN,        CMD_HTTP_MALFORMED };// module varsstatic MiniServerCallback gGetCallback = NULL;static MiniServerCallback gSoapCallback = NULL;static MiniServerCallback gGenaCallback = NULL;static MiniServerState gMServState = MSERV_IDLE;static pthread_t gMServThread = 0;//////////////void SetHTTPGetCallback( MiniServerCallback callback ){    gGetCallback = callback;}MiniServerCallback GetHTTPGetCallback( void ){    return gGetCallback;}void SetSoapCallback( MiniServerCallback callback ){    gSoapCallback = callback;}MiniServerCallback GetSoapCallback( void ){    return gSoapCallback;}void SetGenaCallback( MiniServerCallback callback ){    gGenaCallback = callback;}MiniServerCallback GetGenaCallback( void ){    return gGenaCallback;}class NetReader1{public:    NetReader1( int socketfd );    virtual ~NetReader1();	// throws MiniServerReadException.RCODE_TIMEDOUT    int getChar( char& c );	// throws MiniServerReadException.RCODE_TIMEDOUT    int getLine( xstring& s, bool& newlineNotFound );	// throws MiniServerReadException.RCODE_TIMEDOUT    int readData( void* buf, size_t bufferLen );        int getMaxBufSize() const        { return maxbufsize; }    private:    bool bufferHasData() const    { return offset < buflen; } 	// throws MiniServerReadException.RCODE_TIMEDOUT    ssize_t refillBuffer();private:    enum { MAX_BUFFER_SIZE = 1024 * 2 };private:    int sockfd;    char data[MAX_BUFFER_SIZE + 1]; // extra byte for null terminator    int offset;    int buflen;    int maxbufsize;};NetReader1::NetReader1( int socketfd ){    sockfd = socketfd;    offset = 0;    maxbufsize = MAX_BUFFER_SIZE;    buflen = 0;    data[maxbufsize] = 0;}NetReader1::~NetReader1(){}int NetReader1::getChar( char& c ){    int status;        if ( !bufferHasData() )    {        status = refillBuffer();                if ( status <= 0 )            return status;                    if ( !bufferHasData() )            return 0;    }            c = data[offset];    offset++;        return 1;   // length of data returned}int NetReader1::getLine( xstring& s, bool& newlineNotFound ){    int startOffset;    char c;    int status;    bool crFound;            startOffset = offset;        s = "";        newlineNotFound = false;    crFound = false;    while ( true )    {        status = getChar( c );                if ( status == 0 )        {            // no more chars in stream            newlineNotFound = true;            return s.length();        }                if ( status < 0 )        {            // some kind of error            return status;        }                s += c;                if ( c == 0xA )        {            return s.length();        }        else if ( c == 0xD )            // CR        {            crFound = true;        }        else        {            // wanted to see LF after CR; error            if ( crFound )            {                newlineNotFound = true;                return s.length();            }        }    }        return 0;}// read dataint NetReader1::readData( void* buf, size_t bufferLen ){    int status;    int copyLen;    size_t dataLeft;    // size of data left in buffer        if ( bufferLen <= 0 )        return 0;        // refill empty buffer      if ( !bufferHasData() )    {        status = refillBuffer();                if ( status <= 0 )            return status;                    if ( !bufferHasData() )            return 0;                    dataLeft = buflen;    }    else    {        dataLeft = buflen - offset;    }        if ( bufferLen < dataLeft )    {        copyLen = bufferLen;    }    else    {        copyLen = dataLeft;    }        memcpy( buf, &data[offset], copyLen );        offset += copyLen;        return copyLen;}// throws MiniServerReadException.RCODE_TIMEDOUTstatic int SocketRead( int sockfd, char* buffer, size_t bufsize,    int timeoutSecs ){    int retCode;    fd_set readSet;    struct timeval timeout;    int numRead;    assert( sockfd > 0 );    assert( buffer != NULL );    assert( bufsize > 0 );    FD_ZERO( &readSet );    FD_SET( sockfd, &readSet );    timeout.tv_sec = timeoutSecs;    timeout.tv_usec = 0;    while ( true )    {        retCode = select( sockfd + 1, &readSet, NULL, NULL, &timeout );        if ( retCode == 0 )        {            // timed out            MiniServerReadException e( "SocketRead(): timed out" );            e.setErrorCode( RCODE_TIMEDOUT );            throw e;        }        if ( retCode == -1 )        {            if ( errno == EINTR )            {                continue; // ignore interrupts            }            return retCode;     // error        }        else        {            break;        }    }    // read data    numRead = read( sockfd, buffer, bufsize );    return numRead;}ssize_t NetReader1::refillBuffer(){    ssize_t numRead;    // old code    // numRead = read( sockfd, data, maxbufsize );    ///////    numRead = SocketRead( sockfd, data, maxbufsize, TIMEOUT_SECS );    if ( numRead >= 0 )    {        buflen = numRead;    }    else    {        buflen = 0;    }        offset = 0;            return numRead;}static void WriteNetData( const char* s, int sockfd ){    write( sockfd, s, strlen(s) );}    // determines type of UPNP command from request line, lnstatic HTTP_COMMAND_TYPE GetCommandType( const xstring& ln ){    // commands GET, POST, M-POST, SUBSCRIBE, UNSUBSCRIBE, NOTIFY        xstring line = ln;    int i;    char c;        char * getStr = "GET";    char * postStr = "POST";    char * mpostStr = "M-POST";    char * subscribeStr = "SUBSCRIBE";    char * unsubscribeStr = "UNSUBSCRIBE";    char * notifyStr = "NOTIFY";    char * pattern;    HTTP_COMMAND_TYPE retCode=CMD_HTTP_UNKNOWN;        try    {        line.toUppercase();            c = line[0];                switch (c)        {            case 'G':                pattern = getStr;                retCode = CMD_HTTP_GET;                break;                            case 'P':                pattern = postStr;                retCode = CMD_SOAP_POST;                break;                            case 'M':                pattern = mpostStr;                retCode = CMD_SOAP_MPOST;                break;                            case 'S':                pattern = subscribeStr;                retCode = CMD_GENA_SUBSCRIBE;                break;                            case 'U':                pattern = unsubscribeStr;                retCode = CMD_GENA_UNSUBSCRIBE;                break;                            case 'N':                pattern = notifyStr;                retCode = CMD_GENA_NOTIFY;                break;                        default:                // unknown method                throw -1;                        }                int patLength = strlen( pattern );                for ( i = 1; i < patLength; i++ )        {            if ( line[i] != pattern[i] )                throw -1;        }    }    catch ( OutOfBoundsException& e )    {        return CMD_HTTP_UNKNOWN;    }    catch ( int parseCode )    {        if ( parseCode == -1 )        {            return CMD_HTTP_UNKNOWN;        }    }        return retCode;}static int ParseContentLength( const xstring& textLine, bool& malformed ){    xstring line;    xstring asciiNum;    char *pattern = "CONTENT-LENGTH";    int patlen = strlen( pattern );    int i;    int contentLength;        malformed = false;        contentLength = -1;    line = textLine;    line.toUppercase();        if ( strncmp(line.c_str(), pattern, patlen) != 0 )    {        // unknown header        return -1;    }        i = patlen;        try    {        // skip whitespace        while ( line[i] == ' ' || line [i] == '\t' )        {            i++;        }                // ":"        if ( line[i] != ':' )        {            throw -1;        }        i++;                char* invalidChar = NULL;                contentLength = strtol( &line[i], &invalidChar, 10 );        // anything other than crlf or whitespace after number is invalid        if ( *invalidChar != '\0' )        {            // see if there is an invalid number            while ( *invalidChar )            {                char c;                                c = *invalidChar;                                if ( !(c == ' ' || c == '\t' || c == '\r' || c == '\n') )                {                    // invalid char in number                    throw -1;                }                                invalidChar++;            }        }    }    catch ( OutOfBoundsException& e )    {        malformed = true;        return -1;    }    catch ( int errCode )    {        if ( errCode == -1 )        {            malformed = true;            return -1;        }    }        return contentLength;   }

⌨️ 快捷键说明

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