📄 xpt-http.c
字号:
HttpRc_t rc = HTTP_RC_OK; p->pSession = pSession; /*****************************************************************/ /* Split the host URL name into a Host name part and an URI part */ /*****************************************************************/ if (settings != NULL) { const char *pszAsterisk = "*", *pszEmpty = ""; if ((settings->pszURL != NULL) && (settings->pszURL [0] != '\0')) p->pchURI = makeString (settings->pszURL); else p->pchURI = makeString (pszAsterisk); if (settings->pszHost != NULL) p->pchHost = makeString (settings->pszHost); else p->pchHost = makeString (pszEmpty); if (settings->pszProxy != NULL) p->pchProxy = makeString (settings->pszProxy); else p->pchProxy = makeString (pszEmpty); p->pchRequestType = makeString (settings->pszType); p->pchReferer = makeString (settings->pszReferer); p->pchFrom = makeString (settings->pszFrom); // %%%luz 2002-08-28: second argument p was missing here p->sXSyncmlHmac.pchHmac = makeHmacString(settings->pXSyncmlHmac,p); } p->cbDataLength = settings->cbLength; p->pchRequest = makeString (pszMode); p->fConnection = HTTP_DEFAULT_CONNECTION_TYPE; /*************************************/ /* Setup and Process the HTTP Header */ /*************************************/ if (!xppStrcmp (pszMode, "RECEIVE")) p->fOpenMode = MODE_HTTP_GET; else if (!xppStrcmp (pszMode, "EXCHANGE")) p->fOpenMode = MODE_HTTP_POST; else if (!xppStrcmp (pszMode, "SEND")) p->fOpenMode = MODE_HTTP_PUT; else rc = HTTP_RC_PARAMETER; if (rc == HTTP_RC_OK) writeRequestHeader (p, auth); /************************************/ /* Send the HTTP header to the host */ /************************************/ if (rc == HTTP_RC_OK) { p->iRc = tcpSendData (p->pSession, p->pbCache, p->cbCacheUsed); if (p->iRc != TCP_RC_OK) { /*****************************************************/ /* Probably, the TCP/IP connection is lost. */ /* Free all resources that have been allocated here. */ /* The caller can re-establish the TCP/IP connection */ /* and invoke the httpOpen() function again. */ /*****************************************************/ rc = HTTP_RC_COMMUNICATION; freeString (p->pchRequest); freeString (p->pchURI); freeString (p->pchHost); freeString (p->pchProxy); freeString (p->pchRequestType); freeString (p->pchReferer); freeString (p->pchFrom); freeString (p->sXSyncmlHmac.pchHmac); p->pchRequest = NULL; p->pchURI = NULL; p->pchHost = NULL; p->pchProxy = NULL; p->pchRequestType = NULL; p->pchReferer = NULL; p->pchFrom = NULL; p->sXSyncmlHmac.pchHmac = NULL; p->sXSyncmlHmac.hmacInfo.mac = NULL; p->sXSyncmlHmac.hmacInfo.username = NULL; p->sXSyncmlHmac.hmacInfo.algorithm = NULL; #ifdef STATIC_MEMORY_MANAGEMENT p->cbStringHeapUsed = 0; #endif } p->cbCacheUsed = 0; } return rc; }/**********************************************************************//* Function: Create an instance of a HTTP object for a HTTP server *//* Read the HTTP header information to find out what the client wants *//* Note that pSession must point to a connection socket, that means, *//* there is already a client that connected to the server! *//**********************************************************************/HttpRc_t openServer (HttpBufferPtr_t p, // i: allocated instance object SocketPtr_t pSession, // i:ptr to open connection socket HttpDocumentContextPtr_t settings, //o: document settings HttpAuthenticationPtr_t auth) // o: ptr to authorization info { HttpRc_t rc = HTTP_RC_OK; TcpRc_t iTcpRc; p->pSession = pSession; p->fOpenMode = MODE_HTTP_SERVER; p->fTransferCoding = CHUNKED; p->fConnection = HTTP_DEFAULT_CONNECTION_TYPE; /************************************/ /* Process the complete HTTP header */ /************************************/ iTcpRc = readHttpHeader (p, auth); if (iTcpRc == TCP_RC_EOF) rc = HTTP_RC_EOF; // client closed the TCP/IP connection else if (iTcpRc != TCP_RC_OK) rc = HTTP_RC_COMMUNICATION; // TCP/IP communication error /*********************************************************/ /* The HTTP header has been processed. Inform the caller */ /* about the client request. */ /*********************************************************/ if (rc == HTTP_RC_OK) { settings->pszURL = p->pchURI; settings->pszHost = p->pchHost; settings->pszType = p->pchResponseType; settings->cbLength = p->cbDataLength; settings->pszReferer = p->pchReferer; settings->pszFrom = p->pchFrom; settings->pszRequest = p->pchRequest ? p->pchRequest : "undefined"; settings->pXSyncmlHmac = &(p->sXSyncmlHmac.hmacInfo); } return rc; }/***********************************************************************//* *//* Special data chunking functions *//* *//***********************************************************************//**************************************************************************//* Function: send the last data chunk header to the communication partner *//* The function is called if a Transfer-Encoding mode is selected. *//* The document has been sent to the communication partner, now we must *//* send a terminating chunk header ("0" | CRLF | CRLF") to inform the *//* receiver that the transmission completed. *//* Returns: HTTP_RC_OK - transmission succeedded, *//* others - a data transmission error occurred. *//**************************************************************************/HttpRc_t writeLastDataChunk (HttpBufferPtr_t p) { HttpRc_t rc; const char *pszLastChunk = "0\r\n\r\n"; p->iRc = tcpSendData (p->pSession, (DataBuffer_t) pszLastChunk, (BufferSize_t) xppStrlen (pszLastChunk)); if (p->iRc != 0) rc = HTTP_RC_COMMUNICATION; else rc = HTTP_RC_OK; return rc; }/**********************************************************************//* Function: This is an extended atol () function. An additional base *//* parameter specifies the base of the ascii-long transformation *//**********************************************************************/unsigned long ascii2hex (const char *szAscii) { unsigned long rc = 0L; int iDigit; while ((szAscii [0] != '\0')) { if ((szAscii [0]>= '0')&&(szAscii [0]<= '9')) iDigit = (int)(szAscii [0] - '0'); else if ((szAscii [0]>= 'A')&&(szAscii [0]<= 'Z')) iDigit = (int)(szAscii [0] - 'A')+10; else if ((szAscii [0]>= 'a')&&(szAscii [0]<= 'z')) iDigit = (int)(szAscii [0] - 'a')+10; else break; rc = 16 * rc + iDigit; szAscii ++; } return rc; }/***************************************************************************//* Function: The function processed the data in the buffer cache that have *//* been received from the communication partner as a chunk header. *//* The chunk header has the format "<l> [parms] CRLF" (<l> denotes the size*//* the data chunk that follows), or "0 CRLF CRLF" (the last chunk has been *//* received). [parms] will be ignored. *//* The function parses the chunk size and sets the instance variable *//* cbDataToRead accordingly. *//* returns: 'false', if the chunk header has been parsed, and the variables*//* are updated, 'true' if the data in the cache is an incomplete chunk *//* header *//***************************************************************************/Bool_t parseChunkHeader (HttpBufferPtr_t p) { Bool_t rc = true; unsigned int n; int m = 0; /******************************************/ /* With the exception of the first chunk, */ /* we must skip leading CRLF characters */ /******************************************/ if ((p->pbCache [0] == '\r') && (p->pbCache [1] == '\n')) m = 2; /********************************/ /* Check for the CRLF character */ /********************************/ for (n = m; (n < (p->cbCacheUsed-1)); n ++) { if ((p->pbCache [n] == '\r') && (p->pbCache [n+1] == '\n')) { rc = false; break; } } if (rc == false) { /************************************************/ /* extract the first token of the chunk header: */ /* this is the length of the chunk that follows */ /************************************************/ char *szChunkLength = (char *)p->pbCache+m; char *ptr; char chSave; while (szChunkLength [0] == ' ') szChunkLength ++; ptr = szChunkLength; while ((ptr [0] != ' ') && (ptr [0] != '\0') && (ptr [0] != '\r') && (ptr [0] != ';')) ptr ++; chSave = *ptr; *ptr = '\0'; p->cbDataToRead = (BufferSize_t) ascii2hex (szChunkLength); /**************************************************************/ /* Special handling for the last chunk: after the last chunk, */ /* (A chunk header with a chunk size of '0') there must be a */ /* second CRLF character sequence */ /**************************************************************/ if (p->cbDataToRead == 0L) { if ((p->cbCacheUsed < n + 4) || (p->pbCache [n+2] != '\r') || (p->pbCache [n+3] != '\n')) { /***********************************************/ /* not complete: */ /* We wait for the last empty CRLF characters! */ /***********************************************/ *ptr = chSave; rc = true; } else n += 2; } /******************************************/ /* Remove the chunk header from the cache */ /******************************************/ if (rc == false) { p->cbCacheUsed -= (n+2); if (p->cbCacheUsed > 0) xppMemmove (p->pbCache, p->pbCache + n + 2, p->cbCacheUsed); } } return rc; }/**************************************************//* Data encoding/decoding functions *//**************************************************/BufferSize_t copyBlock (DataBuffer_t pbTarget, // o: target buffer BufferSize_t cbTargetSize, // i: target buffer size DataBuffer_t pbData, // i: Data buffer BufferSize_t *pcbDataLength) // i/o: non-processed Data size { BufferSize_t cbCopySize; cbCopySize = min (*pcbDataLength, cbTargetSize); xppMemcpy (pbTarget, pbData, cbCopySize); /********************************/ /* Save the non-processed data. */ /********************************/ if (*pcbDataLength > cbCopySize) xppMemmove (pbData, pbData + cbCopySize, (*pcbDataLength)-cbCopySize); (*pcbDataLength) -= cbCopySize; return cbCopySize; }BufferSize_t decodeBlock (DataBuffer_t pbTarget, // o: target buffer BufferSize_t cbTargetSize, // i: target buffer size DataBuffer_t pbData, // i: data buffer BufferSize_t *pcbDataLength) // i/o: Data buffer size { BufferSize_t cbCopySize; cbCopySize = min (*pcbDataLength, cbTargetSize); xppMemcpy (pbTarget, pbData, cbCopySize); if (*pcbDataLength > cbCopySize) xppMemmove (pbData, pbData + cbCopySize, (*pcbDataLength)-cbCopySize); (*pcbDataLength) -= cbCopySize; return cbCopySize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -