📄 httputil.cpp
字号:
/*____________________________________________________________________________*\
*
Copyright (c) 1997-2003 John Roy, Holger Zimmermann. All rights reserved.
These sources, libraries and applications are
FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
as long as the following conditions are adhered to.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE AUTHORS OR ITS 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.
*____________________________________________________________________________*|
*
* $Source: /cvsroot/pi3web/Pi3Web_200/Source/Pi3API/HTTPUtil.cpp,v $
* $Date: 2004/07/04 19:42:42 $
*
Description:
HTTP utilities which require no content other than thier parameters.
\*____________________________________________________________________________*/
//$SourceTop:$
#include <assert.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include "PIString.h"
#include "HTTPDefs.h"
#include "HTTPCore.h"
#include "HTTPUtil.h"
#include "PIStrStr.h"
/*____________________________________________________________________________*\
*
Description:
\*____________________________________________________________________________*/
/*
#define D { cerr << __FILE__ << ", " << __LINE__ << ": " << endl; }
*/
#define D
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
Returns 0 on success.
\*____________________________________________________________________________*/
int HTTPUtil_rFC822Time( struct tm *pT, Pi3String *pResult )
{
assert( pT );
assert( pResult );
if ( !pT || !pResult )
{ return -1; };
/* --- RFC822 is strftime "%a, %d %b %Y %T GMT" --- */
enum { SMALL_BUFFER=255 };
char szBuf[SMALL_BUFFER+1];
szBuf[SMALL_BUFFER] = '\0';
int iRet = strftime(szBuf, SMALL_BUFFER, "%a, %d %b %Y %H:%M:%S GMT", pT);
*pResult = szBuf;
return iRet>0 ? 0 : -1;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
Contract a path containing './' and '../' sequences
Change any '\' characters to '/'. Returns the number of
directories above this one that the path should be contracted.
\*____________________________________________________________________________*/
int HTTPUtil_contractPath( char *pPath )
{
int iNumDots=0;
int i;
for( i=0; pPath[i]; i++ )
{
if ( pPath[i]=='.' && iNumDots>=0 )
{ iNumDots++; }
else
{
if ( pPath[i]=='\\' )
{ pPath[i]='/'; break; }
else if ( pPath[i]=='/' )
{ break; };
iNumDots=-1; /* --- file or dir. starting with '.' --- */
};
};
/* ---
iNumDots is the number of directories to ignore, starting with
this one.
--- */
if ( iNumDots==-1 ) { iNumDots=0; };
if ( pPath[i] )
{ iNumDots+=HTTPUtil_contractPath( &(pPath[i+1]) ); };
if ( iNumDots>0 )
{
/* --- skip this directory --- */
/*
** modified this 3/31/97 JR, to handle 'xxx/..' like 'xxx/../'
** memmove( pPath, &(pPath[i+1]), strlen( &(pPath[i]) ) );
*/
memmove( pPath, &(pPath[i]), strlen( &(pPath[i]) )+1 );
iNumDots--;
};
return iNumDots;
}
#define RCNAME_UNKNOWN "UNKNOWN"
#define RCNAME_COMPLETED "COMPLETED"
#define RCNAME_CONTINUE "CONTINUE"
#define RCNAME_ERROR "ERROR"
#define RCNAME_ABORT "ABORT"
#define RCNAME_REDIRECT "REDIRECT"
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
const char *HTTPUtil_rcNumberToName( int iRC )
{
switch( iRC )
{
case PIAPI_COMPLETED: return RCNAME_COMPLETED;
case PIAPI_CONTINUE: return RCNAME_CONTINUE;
case PIAPI_ERROR: return RCNAME_ERROR;
case PIAPI_ABORT: return RCNAME_ABORT;
case INT_REDIRECT: return RCNAME_REDIRECT;
default:
return RCNAME_UNKNOWN;
};
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int HTTPUtil_rcNameToNumber( const char *pName )
{
if ( !pName ) { return PIAPI_ABORT; };
if ( !PIUtil_stricmp( RCNAME_ABORT, pName ) )
{ return PIAPI_ABORT; }
else if ( !PIUtil_stricmp( RCNAME_CONTINUE, pName ) )
{ return PIAPI_CONTINUE; }
else if ( !PIUtil_stricmp( RCNAME_COMPLETED, pName ) )
{ return PIAPI_COMPLETED; }
else if ( !PIUtil_stricmp( RCNAME_ERROR, pName ) )
{ return PIAPI_ERROR; }
else if ( !PIUtil_stricmp( RCNAME_REDIRECT, pName ) )
{ return INT_REDIRECT; }
else
{ return PIAPI_ABORT; };
}
#define PHNAME_INVALID "INVALID"
#define PHNAME_INIT "INIT"
#define PHNAME_HEADERS "HEADERS"
#define PHNAME_HOSTMAP "HOSTMAP"
#define PHNAME_MAPPING "MAPPING"
#define PHNAME_CHECKPATH "CHECKPATH"
#define PHNAME_CHECKAUTH "CHECKAUTH"
#define PHNAME_CHECKACCESS "CHECKACCESS"
#define PHNAME_CHECKTYPE "CHECKTYPE"
#define PHNAME_HANDLE "HANDLE"
#define PHNAME_LOG "LOG"
#define PHNAME_DESTROY "DESTROY"
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
const char *HTTPUtil_phaseNumberToName( int iPhaseNumber )
{
switch( iPhaseNumber )
{
case PH_INVALID: return PHNAME_INVALID;
case PH_INIT: return PHNAME_INIT;
case PH_HEADERS: return PHNAME_HEADERS;
case PH_HOSTMAP: return PHNAME_HOSTMAP;
case PH_MAPPING: return PHNAME_MAPPING;
case PH_CHECKPATH: return PHNAME_CHECKPATH;
case PH_CHECKAUTH: return PHNAME_CHECKAUTH;
case PH_CHECKACCESS: return PHNAME_CHECKACCESS;
case PH_CHECKTYPE: return PHNAME_CHECKTYPE;
case PH_HANDLE: return PHNAME_HANDLE;
case PH_LOG: return PHNAME_LOG;
case PH_DESTROY: return PHNAME_DESTROY;
default:
return PHNAME_INVALID;
};
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int HTTPUtil_phaseNameToNumber( const char *pName )
{
if ( !pName ) { return PH_INVALID; };
if ( !PIUtil_stricmp( PHNAME_INVALID, pName ) )
{ return PH_INVALID; }
else if ( !PIUtil_stricmp( PHNAME_INIT, pName ) )
{ return PH_INIT; }
else if ( !PIUtil_stricmp( PHNAME_HEADERS, pName ) )
{ return PH_HEADERS; }
else if ( !PIUtil_stricmp( PHNAME_HOSTMAP, pName ) )
{ return PH_HOSTMAP; }
else if ( !PIUtil_stricmp( PHNAME_MAPPING, pName ) )
{ return PH_MAPPING; }
else if ( !PIUtil_stricmp( PHNAME_CHECKPATH, pName ) )
{ return PH_CHECKPATH; }
else if ( !PIUtil_stricmp( PHNAME_CHECKAUTH, pName ) )
{ return PH_CHECKAUTH; }
else if ( !PIUtil_stricmp( PHNAME_CHECKACCESS, pName ) )
{ return PH_CHECKACCESS; }
else if ( !PIUtil_stricmp( PHNAME_CHECKTYPE, pName ) )
{ return PH_CHECKTYPE; }
else if ( !PIUtil_stricmp( PHNAME_HANDLE, pName ) )
{ return PH_HANDLE; }
else if ( !PIUtil_stricmp( PHNAME_LOG, pName ) )
{ return PH_LOG; }
else if ( !PIUtil_stricmp( PHNAME_DESTROY, pName ) )
{ return PH_DESTROY; }
else
{ return PH_INVALID; };
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
const char *HTTPUtil_getHostName( PIHTTP *pPIHTTP )
{
return (const char *)PIDB_lookup( pPIHTTP->GetHostDB(),
PIDBTYPE_RFC822, KEY_INT_HOSTNAME, 0 );
}
static const char *http_default_port = "80";
static const char *https_default_port = "443";
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
const char *HTTPUtil_getHostPort( PIHTTP *pPIHTTP )
{
const char *pValue = (const char *)PIDB_lookup( pPIHTTP->GetHostDB(),
PIDBTYPE_RFC822, KEY_INT_SERVERPORT, 0 );
if (pValue) return pValue;
pValue = (const char *)PIDB_lookup( pPIHTTP->GetConnectionDB(),
PIDBTYPE_STRING, KEY_HTTPS_KEYSIZE, 0 );
return pValue ? https_default_port : http_default_port;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
const char *HTTPUtil_protocolNumberToName( int iProtocol )
{
switch( iProtocol )
{
case PR_HTTP09:
return PR_NAME_HTTP09;
case PR_HTTP10:
return PR_NAME_HTTP10;
case PR_HTTP11:
return PR_NAME_HTTP11;
default:;
return PR_NAME_UNKNOWN;
};
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
State machine based resolution of weekday name to number
First letter must be upper case, rest lower, no error checking.
0-6 on success
-1 on error
\*____________________________________________________________________________*/
int Internal_weekdayNumber( const char *pWeekday )
{
assert( pWeekday );
int iState = 0;
for( int i=0; pWeekday[i]; i++ )
{
char c = pWeekday[i];
switch( iState )
{
case 0:
switch( c )
{
case 'S': iState=1; break;
case 'M': return 1; /* Monday */
case 'T': iState=2; break;
case 'W': return 3; /* Wednesday */
case 'F': return 5; /* Friday */
default:
return -1;
};
break;
case 1:
return c=='u' ? 0 : 6; /* Sunday, Saturday */
case 2:
return c=='u' ? 2 : 4; /* Tuesday, Thursday */
default:
return -1;
};
};
return -1;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
State machine based resolution of month name to number
First letter must be upper case, rest lower, no error checking.
0-11 on success
-1 on error
\*____________________________________________________________________________*/
int Internal_monthNumber( const char *pMonth )
{
assert( pMonth );
int iState = 0;
for( int i=0; pMonth[i]; i++ )
{
char c = pMonth[i];
switch( iState )
{
case 0:
switch( c )
{
case 'J': iState=1; break;
case 'F': return 1; /* February */
case 'M': iState=2; break;
case 'A': iState=3; break;
case 'S': return 8; /* September */
case 'O': return 9; /* October */
case 'N': return 10; /* November */
case 'D': return 11; /* December */
default:
return -1;
};
break;
case 1:
/* January, June, July */
if ( c=='a' ) { return 0; };
iState = 4;
break;
case 2:
/* March, May */
iState = 5;
break;
case 3:
/* April, August */
if ( c=='p' ) { return 3; } /* April */
else { return 7; }; /* August */
case 4:
/* June, July */
if ( c=='n' ) { return 5; } /* June */
else { return 6; }; /* July */
case 5:
if ( c=='r' ) { return 2; } /* March */
else { return 4; }; /* May */
default:
return -1;
};
};
return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -