📄 httputil.cpp
字号:
if ( !pFileMap || !pMap )
{
HTTPCore_logError( 0, "HTTPUtil_sendFile: Could not memory \
map file with path '%s'.", pPath );
PIFMap_delete( pFileMap );
return PIAPI_ERROR;
}
else
{
if ( iLen )
{
pBuffer->Write( pMap, iLen, iBufferingFlags );
};
PIFMap_delete( pFileMap );
};
};
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int HTTPUtil_sendFileRange( PIIOBuffer *pBuffer, PIFInfo *pFInfo,
int iBufferingFlags, unsigned int uiFrom, unsigned int uiTo )
{
assert( pBuffer );
assert( pFInfo );
if ( !pBuffer || !pFInfo )
{
return PIAPI_ERROR;
};
/* --- get path --- */
const char *pPath = PIFInfo_getPath( pFInfo );
/* --- get the file map --- */
const char *pMap = 0;
int iSize = 0;
/* --- the range length --- */
int iLen = 1 + uiTo - uiFrom;
/* --- get filemap object --- */
if ( PIFInfo_getSize( pFInfo ) )
{
PIFMap *pFileMap = PIFMap_new( pFInfo );
if ( pFileMap )
{
pMap = (const char *)PIFMap_lock( pFileMap, &iSize );
};
if ( !pFileMap || !pMap )
{
HTTPCore_logError( 0, "HTTPUtil_sendFileRange: Could not memory \
map file with path '%s'.", pPath );
PIFMap_delete( pFileMap );
return PIAPI_ERROR;
}
else
{
// check for wrong range (too big, negative...)
if ( iLen < 1 || uiTo > iSize - 1 || iLen > iSize )
{
HTTPCore_logError( 0, "HTTPUtil_sendFileRange: Invalid Range \
(%d-%d) requested for file with path '%s' of size %d.", uiFrom, uiTo, pPath, iSize );
PIFMap_delete( pFileMap );
return PIAPI_ERROR;
}
// Is something to send?
if ( iLen )
{
pMap += uiFrom;
pBuffer->Write( pMap, iLen, iBufferingFlags );
}
PIFMap_delete( pFileMap );
};
};
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int HTTPUtil_recvFile( PIHTTP *pPIHTTP, PIIOBuffer *pBuffer, PIFInfo *pFInfo )
{
/* --- Open file from descriptor --- */
PIPLATFORM_FD tFD = 0;
tFD = PIFile_open( PIFInfo_getPath( pFInfo ), "w" );
if ( tFD == PIPLATFORM_FD_INVALID ) return PIAPI_ERROR;
/* --- get length to read --- */
long iRead = 0;
long iToRead = strtol((const char *)PIDB_lookup( pPIHTTP->pRequestDB,
PIDBTYPE_RFC822, KEY_HTTP_CONTENTLENGTH, 0 ), NULL, 10);
int iBufRead;
/* --- loop until no more bytes left --- */
do
{
/* --- no more data or client timeout --- */
if ( PIIOBuffer_pollBeforeRead( pBuffer ) < 1 ) break;
/* --- read the data --- */
char *szData = (char *)PIIOBuffer_read( pBuffer, &iBufRead );
iRead += iBufRead;
/* --- this is an error --- */
if ( ! iRead )
{
PIFile_close( tFD );
return PIAPI_ERROR;
};
/* --- write the data to the file --- */
if ( PIFile_write( tFD, iBufRead, szData ))
{
PIFile_close( tFD );
return PIAPI_ERROR;
};
}
while ( iRead < iToRead );
/* --- close the file --- */
if ( PIFile_close( tFD )) return PIAPI_ERROR;
return PIAPI_COMPLETED;
};
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
To split a HTTP Multipart Message (RFC1867) into it parts.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int HTTPUtil_recvMultipartMsg( PIHTTP *pPIHTTP, PIIOBuffer *pBuffer,
PFN_MUTLIPARTCB cb, void *pUser )
{
assert( cb );
// get length to read
long iRead = 0;
char *szContentLength = (char *)PIDB_lookup( pPIHTTP->pRequestDB,
PIDBTYPE_RFC822, KEY_HTTP_CONTENTLENGTH, 0 );
if ( !szContentLength ) return PIAPI_ERROR;
long iToRead = atol( szContentLength );
int iBufRead;
unsigned int i = 0;
enum { IDSIZE = 255 };
char Id[IDSIZE+1] = "";
char szName[IDSIZE+1] = "";
char *szTemp1;
char *szTemp2;
enum { BUF_SIZE=8192 };
char *szBuffer = (char *)PIUtil_malloc( BUF_SIZE );
if ( !szBuffer ) return PIAPI_ERROR;
char *szBufRead = szBuffer;
char *szBufWrite = szBuffer;
char *szBufEnd = szBuffer + BUF_SIZE;
int iPhase = MP_PART_NONE;
// get multipart Id from fist line of http message
iRead += PIIOBuffer_getLine( pBuffer, Id, IDSIZE );
iRead += strlen( HTTP_CRLF );
// an error occured during reading request data
if ( strlen( HTTP_CRLF ) == iRead || iRead >= iToRead ) goto error;
// loop until no more bytes left
do
{
// no more data or client timeout ?
if ( PIIOBuffer_pollBeforeRead( pBuffer ) < 1 ) break;
// read the data
iBufRead = PIIOBuffer_readToBuffer( pBuffer, szBufRead, szBufEnd - szBufRead );
if ( !strcmp( szName, "" ))
{
// Content Disposition
szTemp1 = strstr( szBufRead, "Content-Disposition: " );
// This is not a multipart message!
if ( !szTemp1 ) goto error;
// Name
szTemp1 = strstr( szTemp1, "name=" );
if ( !szTemp1 ) goto error;
szTemp1 += strlen("name=") + 1;
szTemp2 = strchr( szTemp1, '"' );
if ( !szTemp2 ) goto error;
strncpy( szName, szTemp1, szTemp2 - szTemp1 );
};
// this is a fatal error
if ( !iBufRead ) goto error;
// increase read count and pointer
iRead += iBufRead;
szBufRead += iBufRead;
// ring buffer is full
if ( szBufRead == szBufEnd )
{
for ( i = 0; i < BUF_SIZE - strlen( Id ); i++ )
{
// a new part was found
if ( !memcmp( szBuffer + i, Id, strlen( Id )))
{
// this is the end Id, exit loop
if ( i == BUF_SIZE - strlen( Id ) - 2 - strlen( HTTP_CRLF )) break;
iPhase = iPhase ? MP_PART_LAST : MP_PART_FIRST;
if ( cb( iPhase, szName, szBufWrite, i - (szBufWrite - szBuffer) - strlen( HTTP_CRLF ), pPIHTTP, pUser )) goto error;
szBufWrite += szBufWrite - szBuffer + i + strlen( Id ) + strlen( HTTP_CRLF );
// Content Disposition
szTemp1 = strstr( szBufWrite, "Content-Disposition: " );
// This is not a multipart message!
if ( !szTemp1 ) goto error;
// Name
szTemp1 = strstr( szTemp1, "name=" );
if ( !szTemp1 ) goto error;
szTemp1 += strlen("name=") + 1;
szTemp2 = strchr( szTemp1, '"' );
if ( !szTemp2 ) goto error;
strncpy( szName, szTemp1, szTemp2 - szTemp1 );
szName[szTemp2 - szTemp1] = 0;
iPhase = MP_PART_NONE;
};
};
// the whole rest of the buffer
iPhase = iPhase ? MP_PART_NEXT : MP_PART_FIRST;
if ( cb( iPhase, szName, szBufWrite, szBufEnd - szBufWrite - strlen( Id ), pPIHTTP, pUser )) goto error;
// move the untested margin to the start of the buffer
memcpy( szBuffer, szBufRead - strlen( Id ), strlen( Id ));
szBufRead = szBuffer + strlen( Id );
szBufWrite = szBuffer;
};
}
while ( iRead < iToRead );
// an error occured during reading request data
if ( iRead < iToRead ) goto error;
// rest of ring buffer
for ( i = 0; i < ( szBufRead - szBuffer ) - strlen( Id ); i++ )
{
// a new part was found
if ( !memcmp( szBuffer + i, Id, strlen( Id )))
{
// this is the end Id, exit loop
if ( i == ( szBufRead - szBuffer ) - strlen( Id ) - 2 - strlen( HTTP_CRLF )) break;
iPhase = iPhase ? MP_PART_NEXT | MP_PART_LAST : MP_PART_FIRST | MP_PART_LAST;
if ( cb( iPhase, szName, szBufWrite, i - ( szBufWrite - szBuffer ) - strlen( HTTP_CRLF ), pPIHTTP, pUser )) goto error;
szBufWrite += szBufWrite - szBuffer + i + strlen( Id ) + strlen( HTTP_CRLF );
// Content Disposition
szTemp1 = strstr( szBufWrite, "Content-Disposition: " );
// This is not a multipart message!
if ( !szTemp1 ) goto error;
// Name
szTemp1 = strstr( szTemp1, "name=" );
if ( !szTemp1 ) goto error;
szTemp1 += strlen("name=") + 1;
szTemp2 = strchr( szTemp1, '"' );
if ( !szTemp2 ) goto error;
strncpy( szName, szTemp1, szTemp2 - szTemp1 );
szName[szTemp2 - szTemp1] = 0;
iPhase = MP_PART_NONE;
};
};
// the whole rest of the buffer
iPhase = iPhase ? MP_PART_NEXT | MP_PART_LAST : MP_PART_FIRST | MP_PART_LAST;
if ( cb( iPhase, szName, szBufWrite, szBufRead - szBufWrite - strlen( HTTP_CRLF )
- strlen(Id) - 2 - strlen( HTTP_CRLF ), pPIHTTP, pUser )) goto error;
// Completion
PIUtil_free( szBuffer );
return PIAPI_COMPLETED;
error:
PIUtil_free( szBuffer );
return PIAPI_ERROR;
};
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
static const char *pMethodMap[] =
{
0,
MD_NAME_GET,
MD_NAME_POST,
MD_NAME_HEAD,
MD_NAME_PUT,
MD_NAME_DELETE,
MD_NAME_OPTIONS,
MD_NAME_TRACE,
MD_NAME_CONNECT,
0
};
static const char *pProtocolMap[] =
{
PR_NAME_UNKNOWN,
PR_NAME_HTTP09,
PR_NAME_HTTP10,
PR_NAME_HTTP11,
0
};
static const char *pConnectionMap[] =
{
"Close",
"Keep-Alive",
0
};
int HTTPUtil_doHTTPRequest( PIIOBuffer *pBuffer, PIDB *pQ )
{
/*
** Gather items for the HTTP request and validate them
*/
const char *pMethod = 0;
const char *pURI = 0;
const char *pQS = 0;
const char *pProtocol = 0;
const char *pConnection = 0;
int iMethod = (int)PIDB_lookup( pQ, PIDBTYPE_OPAQUE, KEY_HTTP_METHOD, 0 );
if ( iMethod<1 || iMethod>MD_LAST )
{ return PIAPI_EINVAL; };
pMethod = pMethodMap[iMethod];
int iProtocol = (int)PIDB_lookup( pQ, PIDBTYPE_OPAQUE, KEY_HTTP_PROTOCOL, 0 );
if ( iProtocol<1 || iProtocol>PR_HTTP11 )
{ return PIAPI_EINVAL; };
pProtocol = pProtocolMap[iProtocol];
int iKeepAlive = (int)PIDB_lookup( pQ, PIDBTYPE_OPAQUE, KEY_HTTP_CONNECTION, 0 );
if ( iKeepAlive<0 || iKeepAlive>1 )
{ return PIAPI_EINVAL; };
pConnection = pConnectionMap[iKeepAlive];
pURI = (const char *)PIDB_lookup( pQ, PIDBTYPE_STRING, KEY_HTTP_URI, 0 );
if ( !pURI )
{ return PIAPI_EINVAL; };
pQS = (const char *)PIDB_lookup( pQ, PIDBTYPE_STRING, KEY_HTTP_QUERYSTRING, 0 );
/* ---
Send the HTTP request line and standard headers
--- */
PIIOBuffer_write( pBuffer, pMethod, -1, PIIOBUF_NONE );
PIIOBuffer_write( pBuffer, " ", 1, PIIOBUF_NONE );
PIIOBuffer_write( pBuffer, pURI, -1, PIIOBUF_NONE );
if ( pQS && *pQS )
{
PIIOBuffer_write( pBuffer, "?", 1, PIIOBUF_NONE );
PIIOBuffer_write( pBuffer, pQS, -1, PIIOBUF_NONE );
};
PIIOBuffer_write( pBuffer, " ", 1, PIIOBUF_NONE );
PIIOBuffer_writeLn( pBuffer, pProtocol, -1, PIIOBUF_NONE );
if (( iKeepAlive && iProtocol == PR_HTTP10 )
|| ( !iKeepAlive && iProtocol == PR_HTTP11 ))
{
PIIOBuffer_write( pBuffer, "Connection", -1, PIIOBUF_NONE );
PIIOBuffer_write( pBuffer, ": ", 2, PIIOBUF_NONE );
PIIOBuffer_writeLn( pBuffer, pConnection, -1, PIIOBUF_NONE );
};
/* ---
Now send included headers
--- */
/* --- iterate over all headers, sending them to server --- */
PIDBIterator *pRIter = PIDB_getIterator( pQ, PIDBTYPE_RFC822, 0, 0 );
if ( pRIter )
{
for( ; PIDBIterator_atValidElement( pRIter );
PIDBIterator_next( pRIter ) )
{
const char *pKey;
const char *pValue = (const char *)
PIDBIterator_current( pRIter, &pKey );
if ( pKey && *pKey )
{
PIIOBuffer_write( pBuffer, pKey, -1, PIIOBUF_NONE );
PIIOBuffer_write( pBuffer, ": ", 2, PIIOBUF_NONE );
PIIOBuffer_writeLn( pBuffer, pValue, -1, PIIOBUF_NONE );
};
};
PIDBIterator_delete( pRIter );
};
PIIOBuffer_writeLn( pBuffer, "", 0, PIIOBUF_NONE );
/* ---
HTTP request has been started
--- */
return PIAPI_COMPLETED;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -