📄 httpcore.cpp
字号:
/* ---
Done!
--- */
return INT_CONTINUE;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int HTTPCore_sendGeneralHeaders( PIHTTP *pPIHTTP )
{
assert( pPIHTTP );
PIHTTP &tPIHTTP = *pPIHTTP;
/* ---
Don't do anything for subrequests
--- */
if ( tPIHTTP.IsSubRequest() )
{ return PIAPI_COMPLETED; };
PIIOBuffer &tB = tPIHTTP.GetIOBuffer();
PIDB *pQ = tPIHTTP.GetRequestDB();
PIDB *pR = tPIHTTP.GetResponseDB();
/* --- get status line and headers --- */
int iStatus = tPIHTTP.iStatus;
if ( !iStatus )
{
/* ---
If the status is 0 then silently change it to 200 OK
--- */
tPIHTTP.iStatus = ST_OK;
iStatus = ST_OK;
};
int iProtocol = (int)PIDB_lookup( pQ, PIDBTYPE_OPAQUE, pFKProtocolNumber,
PIDBFLAG_FASTKEY );
/* --- send status line and headers if this is not HTTP/0.9 --- */
if ( iProtocol!=PR_HTTP09 )
{
switch( iProtocol )
{
case PR_UNKNOWN:
case PR_HTTP10:
tB.Write( PR_NAME_HTTP10, sizeof( PR_NAME_HTTP10 )-1 ); break;
case PR_HTTP11:
tB.Write( PR_NAME_HTTP11, sizeof( PR_NAME_HTTP11 )-1 ); break;
default:
assert( 0 );
return PIAPI_ERROR;
};
switch( iStatus )
{
#define TMP( pattern ) { \
tB.WriteLn( (pattern), sizeof( pattern )-1 ); break; }
/* ---
HTTP 1.0
--- */
case ST_OK: TMP( " 200 OK" );
case ST_PERMANENTREDIRECT: TMP( " 301 Permanent Redirect" );
case ST_FOUND: if (iProtocol == PR_HTTP11) {
TMP( " 302 Found" );
} else {
TMP( " 302 Temporary Redirect" );
};
case ST_NOTMODIFIED: TMP( " 304 Not Modified" );
case ST_BADREQUEST: TMP( " 400 Bad Request" );
case ST_UNAUTHORIZED: TMP( " 401 Unauthorized" );
case ST_FORBIDDEN: TMP( " 403 Forbidden" );
case ST_NOTFOUND: TMP( " 404 Not Found" );
case ST_INTERNALERROR: TMP( " 500 Internal Error" );
case ST_NOTIMPLEMENTED: TMP( " 501 Not Implemented" );
case ST_BADGATEWAY: TMP( " 502 Bad Gateway" );
case ST_SERVICEUNAVAILABLE: TMP( " 503 Service Unavailable" );
case ST_CREATED: TMP( " 201 Created" );
case ST_ACCEPTED: TMP( " 202 Accepted" );
case ST_NOCONTENT: TMP( " 204 No Content" );
/* ---
HTTP 1.1
--- */
case ST_CONTINUE: TMP( " 100 Continue" );
case ST_SWITCHINGPROTOCOLS: TMP( " 101" );
case ST_NONAUTHORITATIVEINFO: TMP( " 203 None-Authoritative Information" );
case ST_RESETCONTENT: TMP( " 205 Reset Content" );
case ST_PARTIALCONTENT: TMP( " 206 Partial Content" );
case ST_MULTIPLECHOICES: TMP( " 300 Multiple Choices" );
case ST_SEEOTHER: TMP( " 303 See Other" );
case ST_USEPROXY: TMP( " 305 Use Proxy" );
case ST_UNUSED: TMP( " 306 (Unused)" );
case ST_TEMPORARYREDIRECT: TMP( " 307 Temporary Redirect" );
case ST_PAYMENTREQUIRED: TMP( " 402 Payment Required" );
case ST_METHODNOTALLOWED: TMP( " 405 Method Not Allowed" );
case ST_NOTACCEPTABLE: TMP( " 406 Not Acceptable" );
case ST_PROXYAUTHREQUIRED: TMP( " 407 Proxy Authentication Required" );
case ST_REQUESTTIMEOUT: TMP( " 408 Request Timeout" );
case ST_CONFLICT: TMP( " 409 Conflict" );
case ST_GONE: TMP( " 410 Gone" );
case ST_LENGTHREQUIRED: TMP( " 411 Length Required" );
case ST_PRECONDITIONFAILED: TMP( " 412 Precondition Failed" );
case ST_REQUESTENTITYTOOLARGE: TMP( " 413 Request Entity Too Large" );
case ST_REQUESTURITOOLONG: TMP( " 414 Request-URI Too Long" );
case ST_UNSUPPORTEDMEDIATYPE: TMP( " 415 Unsupported Media Type" );
case ST_RANGENOTSATISFIABLE: TMP( " 416 Request Range Not Satisfiable" );
case ST_EXPECTATIONFAILED: TMP( " 417 Expectation Failed" );
case ST_GATEWAYTIMEOUT: TMP( " 504 Gateway Timeout" );
case ST_UNSUPPORTEDVERSION: TMP( " 505 HTTP Version Not supported" );
default:
#undef TMP
#if !defined(NDEBUG)
cerr << iStatus << endl;
#endif
assert( 0 );
return PIAPI_ERROR;
};
/* ---
Send general header fields
--- */
/* --- server --- */
if ( pSG->sServerStamp!=PIString::Empty() )
{
#define TMP "Server: "
tB.Write( TMP, sizeof( TMP )-1 );
tB.WriteLn( pSG->sServerStamp, -1 );
};
#undef TMP
/* --- date --- */
Internal_SendHeader_Date( tB );
/* --- Connection --- */
Internal_SendHeader_Connection( tPIHTTP );
/* --- TransferEncoding --- */
#define TMP "Transfer-Encoding: "
if (const char *pTE = (const char *)PIDB_lookup( pR, PIDBTYPE_RFC822,
pFKTransferEnc, PIDBFLAG_FASTKEY ))
{
tB.Write( TMP, sizeof( TMP )-1 );
tB.WriteLn( pTE, -1 );
};
#undef TMP
};
/* ---
Done!
--- */
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int HTTPCore_sendEntityHeaders( PIHTTP *pPIHTTP, PIDB *pR )
{
assert( pPIHTTP );
PIHTTP &tPIHTTP = *pPIHTTP;
/* ---
Don't do anything for subrequests
--- */
if ( tPIHTTP.IsSubRequest() )
{ return PIAPI_COMPLETED; };
PIDB *pQ = tPIHTTP.GetRequestDB();
PIIOBuffer &tB = tPIHTTP.GetIOBuffer();
int iProtocol = (int)PIDB_lookup( pQ, PIDBTYPE_OPAQUE, pFKProtocolNumber,
PIDBFLAG_FASTKEY );
if ( iProtocol==PR_HTTP09 ) /* --- no header for HTTP/0.9 --- */
{ return PIAPI_COMPLETED; };
/* ----
Do RFC822 response headers
--- */
PIDBIterator *pIter = PIDB_getIterator( pR, PIDBTYPE_RFC822, 0, 0 );
if ( pIter )
{
for(;
PIDBIterator_atValidElement( pIter );
PIDBIterator_next( pIter ) )
{
const char *pKey;
const char *pValue = (const char *)
PIDBIterator_current( pIter, &pKey );
if (!PIUtil_stricmp(pKey, KEY_HTTP_SERVER)) { continue; };
if (!PIUtil_stricmp(pKey, KEY_HTTP_DATE)) { continue; };
if (!PIUtil_stricmp(pKey, KEY_HTTP_CONNECTION)) { continue; };
if (!PIUtil_stricmp(pKey, KEY_HTTP_TRANSFERENCODING)) { continue; };
if (!pValue || !*pValue) { continue; };
tB.Write( pKey, -1 );
tB.Write( ": ", 2 );
tB.WriteLn( pValue, -1 );
};
PIDBIterator_delete( pIter );
};
tB.WriteLn( "", 0 );
/* ---
Done!
--- */
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int HTTPCore_loadMIMEFile( PIObject *pObject, PIDB *pMIMEDB,
const char *pMIMEFile )
{
assert( pMIMEFile );
if ( !pMIMEFile )
{ return 0; };
ifstream ifs( pMIMEFile );
enum { MIME_LINE_MAX=2047 };
char szMIMEBuf[MIME_LINE_MAX+1];
szMIMEBuf[MIME_LINE_MAX]='\0';
if ( !ifs.good() || ifs.eof() )
{
enum { TMP_BUF=2048 };
char szTmpBuf[TMP_BUF];
sprintf( szTmpBuf, "HTTP1_0: mime file '%s' \
is empty or does not exist.", pMIMEFile );
CONFIG_ERR( pObject, szTmpBuf );
return 0;
};
while( ifs.good() )
{
ifs.getline( szMIMEBuf, MIME_LINE_MAX );
char *pszMIMEBuf = szMIMEBuf;
if ( ifs.eof() )
{ break; };
int i=0;
/*
** Scan to first non-space
*/
for(; pszMIMEBuf[i] && (isspace(pszMIMEBuf[i])); i++);
/*
** Is this line empty
*/
if ( !pszMIMEBuf[i] || pszMIMEBuf[i]=='#' )
{ continue; /* comment line */ };
/*
** Make pMIMEType point to start of media definition
*/
const char *pMIMEType=&( pszMIMEBuf[i] );
/*
** Scan to end of media definition (first whitespace)
*/
for(; pszMIMEBuf[i] && !(isspace(pszMIMEBuf[i])); i++);
int bMoreExtns = 0;
if ( pszMIMEBuf[i] )
{
bMoreExtns = 1;
pszMIMEBuf[i++] = '\0';
};
for(; bMoreExtns;)
{
/*
** Scan past whitespace before extension
*/
for(; pszMIMEBuf[i] && (isspace(pszMIMEBuf[i])); i++);
/* if line is empty, skip it */
if ( !pszMIMEBuf[i] || pszMIMEBuf[i]=='#' )
{ break; /* line is empty or comment line */ };
/*
** Mark start of extension
*/
pszMIMEBuf = &( pszMIMEBuf[i] ); i=0;
/*
** Skip to end of extension
*/
for(; pszMIMEBuf[i] && !(isspace(pszMIMEBuf[i])); i++);
if ( pszMIMEBuf[i] )
{
bMoreExtns = 1;
pszMIMEBuf[i++] = '\0';
};
PIString sExtn( pszMIMEBuf );
#if WIN32
/*
** Silently convert to upper case
*/
sExtn.ConvertToUpperCase();
#endif
const char *pExtn = sExtn;
const char *pPreviousMIMEType = (const char *)PIDB_lookup(
pMIMEDB, PIDBTYPE_STRING, pExtn, 0 );
if ( pPreviousMIMEType )
{
enum { TMP_BUF=2048 };
char szTmpBuf[TMP_BUF];
sprintf( szTmpBuf, "HTTP1_0: reading mime file '%s' \
extension '%s' is already mapped to MIME type '%s'.", pMIMEFile, pExtn,
pPreviousMIMEType );
CONFIG_ERR( pObject, szTmpBuf );
return 0;
};
if (PIDB_add( pMIMEDB, PIDBTYPE_STRING, pExtn,
(void *)pMIMEType, 0 ))
{
CONFIG_ERR( pObject, "HTTP1_0: internal error \
dding MIME-type." );
return 0;
};
};
};
return 1;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
PIFInfo *HTTPCore_getCachedFile( const char *pPath )
{
return PIFInfo_new( pPath );
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
void HTTPCore_releaseCachedFile( PIFInfo *pFInfo )
{
PIFInfo_delete( pFInfo );
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int HTTPCore_relativeToAbsolutePath( PIDB *pDB,
const char *pRelativePath, Pi3String *pResult )
{
assert( pRelativePath );
assert( pResult );
assert( pSG );
/*
** Get the server or Host root from the DB
*/
const char *pRoot = 0;
if ( pDB )
{
pRoot = (const char *)PIDB_lookup( pDB, PIDBTYPE_STRING,
pFKHostRoot, PIDBFLAG_FASTKEY | PIDBFLAG_PROPAGATEUP );
};
if ( !pRoot )
{
pRoot = pSG->sServerRoot;
};
return Internal_RelativeToAbsolutePath( pRoot, pRelativePath, *pResult );
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
const char *HTTPCore_getServerStamp()
{
assert( pSG );
return pSG->sServerStamp;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
Returns the MIME type for a file extension
\*____________________________________________________________________________*/
const char *HTTPCore_getMIMETypeFromExtension( const char *pExtn )
{
assert( pSG );
const char *pMIME = 0;
#if WIN32
/*
** Everything is upper case
*/
PIString sExtn( pExtn );
sExtn.ConvertToUpperCase();
const char *pExtension = sExtn;
#else
const char *pExtension = pExtn;
#endif
if ( !pExtension ||
!( pMIME = (const char *)PIDB_lookup( pSG->pMIMEDB, PIDBTYPE_STRING,
pExtension, 0 ) ) )
{ return pSG->sDefaultMIMEType; };
return pMIME;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
Returns 0 on success.
\*____________________________________________________________________________*/
int HTTPCore_logError( PIHTTP *pPIHTTP, const char *pFormat, ... )
{
assert( pSG );
#if TEMP
PIPLATFORM_FD tError = pSG->tErrorLog;
#else
FILE *pError = pSG->pErrorLog;
#endif
va_list tvList;
/* --- get time stamp --- */
enum { BUF_SIZE=255 };
char szBuf[BUF_SIZE+1];
time_t tT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -