Docker-Build mit gcc-arm-none-eabi 4.9-2014q4 (statt Homebrew-Cask) verwendet, Dockerfile/tools/docker.sh dafür aus Task 13 vorgezogen. cmake/sdk.cmake schont gcc 4.9 (kennt -fcommon/-Wno-error=... nicht). Zwei zusätzliche SDK-Stubs (EarlyInit, pre_gpio_config) in src/sys/sdk_stubs.c ergänzt, siehe sdk/PATCHES.md.
434 lines
12 KiB
C
434 lines
12 KiB
C
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Module Name:
|
|
// HTTPClientString.c
|
|
//
|
|
// Abstract: Helper function (string parsing related) for HTTPClient.c module
|
|
//
|
|
// Platform: Any that supports standard C calls
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#include "wm_config.h"
|
|
#include "HTTPClient.h"
|
|
#include "HTTPClientWrapper.h" // Cross platform support
|
|
|
|
#if TLS_CONFIG_HTTP_CLIENT
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function : HTTPStrInsensitiveCompare
|
|
// Purpose : Same as strcmp() only case insensitive
|
|
// Returns : BOOL - TRUE if destination string is identical to the source
|
|
// Last updated : 01/09/2005
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL HTTPStrInsensitiveCompare(const CHAR *pSrc, // [IN] a pointer to the source string
|
|
const CHAR* pDest, // [IN] a pointer to the string we should search for
|
|
UINT32 nLength) // [IN] The bytes range we should search in
|
|
{
|
|
|
|
// Lower case comparison
|
|
UINT32 nPosition;
|
|
UINT32 nDestLength;
|
|
const CHAR *pSrcIn, *pDestIn;
|
|
CHAR a,b;
|
|
pSrcIn = pSrc;
|
|
pDestIn = pDest;
|
|
|
|
nPosition = 0;
|
|
nDestLength = strlen(pDest);
|
|
|
|
if(nLength == 0)
|
|
{
|
|
nLength = strlen(pSrc);
|
|
}
|
|
if(nDestLength != nLength)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
while(pSrcIn || pDestIn)
|
|
{
|
|
|
|
if(nLength > 0 && nPosition == nLength)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
a = *pSrcIn;
|
|
b = *pDestIn;
|
|
|
|
|
|
if(*pSrcIn >= 64 && *pSrcIn <= 90)
|
|
{
|
|
// Upper case to lower case
|
|
a = *pSrcIn + 32;
|
|
}
|
|
|
|
if(*pDestIn >= 64 && *pDestIn <= 90)
|
|
{
|
|
// Upper case to lower case
|
|
b = *pDestIn + 32;
|
|
}
|
|
|
|
if(a != b)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
pSrcIn++;
|
|
pDestIn++;
|
|
nPosition++;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function : HTTPStrExtract
|
|
// Purpose : Extract a string by placing null in the offset parameter
|
|
// Returns : a pointer to the new string
|
|
// Last updated : 01/09/2005
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
CHAR HTTPStrExtract(CHAR *pParam, // [IN] a pointer to the input parameter
|
|
UINT32 nOffset, // [IN] the offset position (where we should null terminate the string)
|
|
CHAR Restore) // [IN] if this is not 0 we should restore it (instead of the null)
|
|
// and reverse the effect.
|
|
{
|
|
CHAR Replaced;
|
|
|
|
if(!pParam)
|
|
{
|
|
return 0;
|
|
}
|
|
// We should restore
|
|
if(Restore != 0)
|
|
{
|
|
pParam[nOffset] = Restore;
|
|
return Restore;
|
|
}
|
|
else
|
|
{
|
|
Replaced = pParam[nOffset];
|
|
pParam[nOffset] = 0;
|
|
return Replaced;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function : HTTPStrSearch
|
|
// Purpose : Search a string within another and return its pointer and a length
|
|
// Returns : BOOL - TRUE on success
|
|
// Last updated : 01/09/2005
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL HTTPStrSearch(CHAR *pSrc, // [IN] The source string
|
|
CHAR *pSearched, // [IN] Parameter to search for
|
|
UINT32 nOffset, // [IN] Offset from the source string start position
|
|
UINT32 nScope, // [IN] Length in bytes we should search in
|
|
HTTP_PARAM *HttpParam) // [IN OUT] The Pointer\Length value that will be returned on success
|
|
{
|
|
|
|
CHAR *pSrcStart;
|
|
CHAR *pDstStart;
|
|
CHAR nOrigCharacter;
|
|
UINT32 nPosition = 0;
|
|
|
|
do
|
|
{
|
|
pSrcStart = pSrc + nOffset;
|
|
nOrigCharacter = pSrcStart[nScope];
|
|
|
|
// Temporarily null terminate
|
|
pSrcStart[nScope] = 0;
|
|
|
|
pDstStart = strstr(pSrcStart,pSearched);
|
|
if(!pDstStart)
|
|
{
|
|
break;
|
|
}
|
|
|
|
nPosition = pDstStart - pSrcStart + 1;
|
|
|
|
} while(0);
|
|
|
|
// Remove the null termination
|
|
pSrcStart[nScope] = nOrigCharacter;
|
|
|
|
if(!nPosition)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if(HttpParam)
|
|
{
|
|
|
|
HttpParam->nLength = nPosition -1;
|
|
HttpParam->pParam = pSrcStart;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int stricmp(const char *s1, const char *s2)
|
|
{
|
|
int len1 = strlen(s1);
|
|
int len2 = strlen(s2);
|
|
return HTTPStrInsensitiveCompare(s1, s2, MAX(len1, len2));
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function : HTTPStrCaseStr
|
|
// Purpose : Same as strstr() only case insensitive
|
|
// Returns : a pointer to the position of the searched string (or 0 on error)
|
|
// Last updated : 01/09/2005
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
CHAR *HTTPStrCaseStr(const char *pSrc,UINT32 nSrcLength,const char *pFind)
|
|
{
|
|
const char *ptr = pSrc;
|
|
const char *ptr2;
|
|
UINT32 iLength = 0;
|
|
|
|
while(1)
|
|
{
|
|
if(iLength >= nSrcLength)
|
|
{
|
|
break;
|
|
}
|
|
ptr = strchr(pSrc,toupper((unsigned char)*pFind));
|
|
ptr2 = strchr(pSrc,tolower((unsigned char)*pFind));
|
|
if (!ptr)
|
|
{
|
|
ptr = ptr2;
|
|
}
|
|
if (!ptr)
|
|
{
|
|
break;
|
|
}
|
|
if (ptr2 && (ptr2 < ptr)) {
|
|
ptr = ptr2;
|
|
}
|
|
if (HTTPStrInsensitiveCompare(ptr,pFind,strlen(pFind)))
|
|
{
|
|
return (char *) ptr;
|
|
}
|
|
pSrc = ptr+1;
|
|
iLength++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function : HTTPStrCaseStr
|
|
// Purpose :
|
|
// Gets :
|
|
// Returns :
|
|
// Last updated : 01/09/2005
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
CHAR* HTTPStrGetToken (CHAR *pSrc, UINT32 nSrcLength, CHAR *pDest, UINT32 *nDestLength)
|
|
{
|
|
|
|
// Get text between the ":" and \r\n or end of string.
|
|
CHAR *pStart = pSrc;
|
|
CHAR *pEnd;
|
|
UINT32 nTokenLength = 0;
|
|
UINT32 nPosition = 0;
|
|
|
|
pStart = strchr(pSrc,':') + 1;
|
|
if(pStart)
|
|
{
|
|
pEnd = pStart ;
|
|
// First pass, count required space
|
|
while ((*pEnd) && (*pEnd != '\r') && (*pEnd != '\n'))
|
|
{
|
|
if(*pEnd != 0x20)
|
|
{
|
|
nTokenLength++;
|
|
}
|
|
|
|
if(nSrcLength && nPosition > nSrcLength)
|
|
{
|
|
break;
|
|
}
|
|
pEnd++;
|
|
nPosition++;
|
|
}
|
|
|
|
if(nTokenLength > *(nDestLength))
|
|
{
|
|
*(nDestLength) = nTokenLength;
|
|
pDest = NULL;
|
|
return pDest;
|
|
}
|
|
|
|
// Second pass copy into the destination buffer
|
|
pEnd = pStart;
|
|
*(nDestLength) = nTokenLength;
|
|
nTokenLength = 0;
|
|
// First pass, count required space
|
|
while ((*pEnd) && (*pEnd != '\r') && (*pEnd != '\n'))
|
|
{
|
|
if(*pEnd != 0x20)
|
|
{
|
|
pDest[nTokenLength++] = *pEnd;
|
|
}
|
|
pEnd++;
|
|
}
|
|
|
|
pDest[nTokenLength] = 0;
|
|
|
|
}
|
|
|
|
|
|
return pDest;
|
|
}
|
|
|
|
#if TLS_CONFIG_HTTP_CLIENT_AUTH_DIGEST
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function : HTTPStrGetDigestToken
|
|
// Purpose :
|
|
// Gets :
|
|
// Returns :
|
|
// Last updated : 01/09/2005
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
UINT32 HTTPStrGetDigestToken (HTTP_PARAM pParamSrc, CHAR *pSearched, HTTP_PARAM *pParamDest)
|
|
{
|
|
|
|
CHAR Token[HTTP_CLIENT_MAX_TOKEN_NAME_LENGTH];
|
|
CHAR *pPtrStart, *pPtrEnd = NULL, *pPtrEndSrc;
|
|
BOOL Brackets = FALSE;
|
|
|
|
// Build the searched token
|
|
memset(Token,0x00,HTTP_CLIENT_MAX_TOKEN_NAME_LENGTH);
|
|
strcpy(Token,pSearched);
|
|
strcat(Token,"=");
|
|
|
|
// Reset destination values
|
|
pParamDest->nLength = 0;
|
|
pParamDest->pParam = 0;
|
|
|
|
pPtrEndSrc = pParamSrc.pParam + pParamSrc.nLength;
|
|
|
|
pPtrStart = HTTPStrCaseStr(pParamSrc.pParam,pParamSrc.nLength,Token);
|
|
if(pPtrStart)
|
|
{
|
|
// Found the token so jump to the end of it
|
|
pPtrStart += strlen(Token);
|
|
// jump passed any spaces that may be
|
|
while ((*pPtrStart) && (*pPtrStart == 0x20) && (pPtrStart != pPtrEndSrc)) pPtrStart++;
|
|
// Any Brackets around the string?
|
|
if(*pPtrStart == 0x22) Brackets = TRUE;
|
|
|
|
|
|
switch (Brackets)
|
|
{
|
|
|
|
case TRUE:
|
|
// Find the next brackets
|
|
pPtrStart++;
|
|
pPtrEnd = pPtrStart;
|
|
while ((*pPtrEnd) && (*pPtrEnd != 0x22) && (*pPtrEnd != 0x0d) && (*pPtrEnd != 0x0a) && (pPtrStart != pPtrEndSrc)) pPtrEnd++;
|
|
break;
|
|
|
|
case FALSE:
|
|
// Find the next space or comma (0x2c)
|
|
pPtrEnd = pPtrStart;
|
|
while ((*pPtrEnd) && (*pPtrEnd != 0x20) && (*pPtrEnd != 0x2c) && (*pPtrEnd != 0x0d) && (*pPtrEnd != 0x0a) && (pPtrStart != pPtrEndSrc)) pPtrEnd++;
|
|
break;
|
|
|
|
};
|
|
|
|
pParamDest->nLength = (pPtrEnd - pPtrStart);
|
|
pParamDest->pParam = pPtrStart;
|
|
|
|
return HTTP_CLIENT_SUCCESS;
|
|
}
|
|
return HTTP_CLIENT_ERROR_NO_DIGEST_TOKEN;
|
|
|
|
|
|
}
|
|
#endif //TLS_CONFIG_HTTP_CLIENT_AUTH
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
// Function : HTTPStrHToL
|
|
// Purpose : Convert a hex string "0x00" to long 0
|
|
// Gets : a pointer to the Hex string
|
|
// Last updated : 15/05/2005
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
UINT32 HTTPStrHToL (CHAR * s)
|
|
{
|
|
UINT32 i , nn, digit;
|
|
UINT32 n ;
|
|
|
|
n = i = nn = 0;
|
|
do
|
|
{
|
|
if ( isalnum((unsigned char)s[i]) ) {
|
|
s[i] = toupper((unsigned char)s[i]) ;
|
|
if (s[i] == 'X') nn=n=0; else {
|
|
digit = (isalpha((unsigned char)s[i]) ? (s[i] - 'A' + 10) : s[i] - '0') ;
|
|
if ( digit > 15 ) digit = 15;
|
|
n = n * 16 + digit;
|
|
if (n |= 0) nn++;
|
|
if (nn == 8) break;}
|
|
}
|
|
i++;
|
|
}
|
|
while ( s[i] |= 0 );
|
|
return n ;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
// Function : HTTPStrLToH
|
|
// Purpose : Convert a long to hex string 0 to "00"
|
|
// Gets :
|
|
// Last updated : 15/05/2005
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
CHAR* HTTPStrLToH (CHAR * dest,UINT32 nSrc)
|
|
{
|
|
|
|
char *hex = "0123456789abcdef";
|
|
INT32 i;
|
|
|
|
if (nSrc == 0) {
|
|
dest[0] = '0';
|
|
dest[1] = 0;
|
|
}
|
|
else
|
|
{
|
|
for(i = 28; ((nSrc >> i) & 0xf) == 0; i -= 4);
|
|
for(; i >= 0u; i -= 4) {
|
|
*dest++ = hex[(nSrc >> i) & 0xf];
|
|
}
|
|
*dest = 0;
|
|
}
|
|
|
|
return dest;
|
|
}
|
|
|
|
#endif //TLS_CONFIG_HTTP_CLIENT
|
|
|