build: W600-SDK importiert, Firmware-Build und Hello am EVK

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.
This commit is contained in:
Michael Sauer
2026-09-11 12:52:26 +02:00
parent 4e7ff78fc6
commit 1b0501179d
610 changed files with 224089 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
# THE VERSION NUMBER
SET(CMAKE_SYSTEM_NAME Generic)
CMAKE_MINIMUM_REQUIRED (VERSION 3.10)
PROJECT(WMHTTPCLIENT)
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
SET(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "")
set(CMAKE_VERBOSE_MAKEFILE OFF)
# ENABLE ASM
ENABLE_LANGUAGE(ASM)
SET(CMAKE_STATIC_LIBRARY_PREFIX)
SET(CMAKE_STATIC_LIBRARY_SUFFIX)
SET(CMAKE_EXECUTABLE_LIBRARY_PREFIX)
SET(CMAKE_EXECUTABLE_LIBRARY_SUFFIX)
# C FLAGS
SET(CMAKE_C_FLAGS " -mthumb --function-sections --data-sections -mcpu=cortex-m3 -std=gnu99 -mabi=aapcs -march=armv7-m -fno-builtin ")
STRING(APPEND CMAKE_C_FLAGS "-DGCC_COMPILE=1 -DWOLFSSL_USER_SETTINGS -D_IN_ADDR_T_DECLARED -D__MACHINE_ENDIAN_H__ -D_TIMEVAL_DEFINED -D__INSIDE_CYGWIN_NET__ ")
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -gdwarf-2 -Wall -DDEBUG ")
SET(CMAKE_C_FLAGS_RELEASE "-Os -Wall")
# DEBUG ASM FLAGS
SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -O0 -g3 -gdwarf-2 -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin -DDEBUG ")
SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE} -Os -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin ")
# Library sources
SET(LIBRARY_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/HTTPClient.c"
"${CMAKE_CURRENT_SOURCE_DIR}/HTTPClientAuth.c"
"${CMAKE_CURRENT_SOURCE_DIR}/HTTPClientString.c"
"${CMAKE_CURRENT_SOURCE_DIR}/HTTPClientWrapper.c"
"${CMAKE_CURRENT_SOURCE_DIR}/wm_httpclient_task.c"
)
function(ADD_LIB_TARGET LIBTARGET)
add_library(${LIBTARGET} OBJECT ${LIBRARY_SOURCES})
# ADD_CUSTOM_COMMAND(TARGET ${LIBTARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EXECUTABLE_OUTPUT_PATH}/${LIBTARGET} ${CMAKE_CURRENT_SOURCE_DIR}/../../../Lib/GNU/${LIBTARGET})
endfunction()
ADD_LIB_TARGET(wmhttpclient.a)
File diff suppressed because it is too large Load Diff
+318
View File
@@ -0,0 +1,318 @@
#ifndef _HTTP_CLIENT
#define _HTTP_CLIENT
#include "wm_config.h"
#include "HTTPClientWrapper.h"
#include "HTTPClientCommon.h"
#include "wm_http_client.h"
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Section : HTTP API global definitions
// Last updated : 01/09/2005
//
///////////////////////////////////////////////////////////////////////////////
#ifdef _HTTP_BUILD_AMT
#define CMSI_HTTPCLIENT_PROTOCOL_GUID {0x471b2c0e, 0x6137, 0x4d55, 0x92, 0x36, 0xdd, 0x0f, 0xdb, 0xc2, 0x52, 0xfb}
#endif
// Debug hook
// #define _HTTP_DEBUGGING_ // Simply dumps more debugging data to the console
// API Version
#define HTTP_CLIENT_VERSION_MINOR 0
#define HTTP_CLIENT_VERSION_MAJOR 1
// Global default sizes
#define HTTP_CLIENT_MAX_SEND_RECV_HEADERS 1024 // Maximum Send and receive buffers size
#define HTTP_CLIENT_INIT_SEND_RECV_HEADERS 2048 // If we can resize the buffers this would be the initial size
#define HTTP_CLIENT_MAX_USERNAME_LENGTH 16 // Maximum length the user name (host and proxy authentication)
#define HTTP_CLIENT_MAX_PASSWORD_LENGTH 16 // Maximum length for the password
// Maximum length for the base 64 encoded credentials (twice the size of the user name and password max parameters)
#define HTTP_CLIENT_MAX_64_ENCODED_CRED ((HTTP_CLIENT_MAX_USERNAME_LENGTH + HTTP_CLIENT_MAX_PASSWORD_LENGTH) * 2) + 4
#define HTTP_CLIENT_MAX_CHUNK_HEADER 64 // Maximum length for the received chunk header (hex - string) size
#define HTTP_CLIENT_MAX_PROXY_HOST_LENGTH 64 // Maximum length for the proxy host name
#define HTTP_CLIENT_MAX_TOKEN_LENGTH 512 // Maximum length for an HTTP token data (authentication header elements)
#define HTTP_CLIENT_MAX_TOKEN_NAME_LENGTH 32 // Maximum length for an HTTP authorization token name ("qop")
#define HTTP_CLIENT_MAX_HEADER_SEARCH_CLUE 1024 // Maximum length for a search clue string (Headers searching)
#define HTTP_CLIENT_ALLOW_HEAD_VERB 0 // Can we use the HTTP HEAD verb in our outgoing requests?
#define HTTP_CLIENT_MEMORY_RESIZABLE FALSE // Permission to dynamically resize the headers buffer
#define HTTP_CLIENT_MEMORY_RESIZE_FACTOR 16 // Factor for memory resizing operation
#define HTTP_CLIENT_DEFAULT_PORT 80 // Default HTTP port
#define HTTP_CLIENT_DEFAULT_SSL_PORT 443 // Default HTTPS port
#define HTTP_CLIENT_DEFAULT_VERB 0 // GET
#define HTTP_CLIENT_DEFAULT_VER "HTTP/1.1" // We will send this in the outgoing header
#define HTTP_CLIENT_DEFAULT_PROXY_VER "HTTP/1.0" // We will send this in the outgoing header (proxy)
#define HTTP_CLIENT_DEFAULT_AGENT "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)"
#define HTTP_CLIENT_DEFAULT_TIMEOUT 30 // Default timeout in seconds
#define HTTP_CLIENT_DEFAULT_KEEP_ALIVE 30 // Default Keep-alive value in seconds
#define HTTP_CLIENT_DEFAULT_DIGEST_AUTH "MD5" // This is for bypassing a known bug in AMT05..
#define HTTP_CLIENT_DEFAULT_PROXY_AUTH AuthSchemaBasic // Basic
#define HTTP_CLIENT_CRLF "\r\n" // End of line macro
#define HTTP_CLIENT_CRLFX2 "\r\n\r\n" // Double End of line macro
// HTTP Session internal API flags
// Note: Not intended to be set the by the API user
#define HTTP_CLIENT_FLAG_SECURE 0x00000010 // The session is secured using TLS
#define HTTP_CLIENT_FLAG_URLANDPORT 0x00000020 // Url has a port within
#define HTTP_CLIENT_FLAG_URLHTTPS 0x00000040 // Url has a https prefix
#define HTTP_CLIENT_FLAG_USINGPROXY 0x00000080 // Operation will be performed using a proxy server
#define HTTP_CLIENT_FLAG_CHUNKED 0x00000100 // The incoming data is chunked
// HTTP Status codes
#define HTTP_STATUS_OK 200 // The request has succeeded
#define HTTP_STATUS_UNAUTHORIZED 401 // The request requires user authentic
#define HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED 407 // The client must first authenticate itself with the proxy
// Redirection (Note: there are more 30x codes, those are the most popular)
#define HTTP_STATUS_OBJECT_MOVED 302 // Page redirection notification
#define HTTP_STATUS_OBJECT_MOVED_PERMANENTLY 301 // Page redirection notification
#define HTTP_STATUS_CONTINUE 100 // Page continue message
// MIN AMX macro
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
// HTTP timeout macro for selecting the default value if the caller passed 0 (no timeout) to the function
#define HTTP_TIMEOUT(nTimeout) (((nTimeout) > (0)) ? (nTimeout * HZ) : (HTTP_CLIENT_DEFAULT_TIMEOUT * HZ))
// 32 bit alignment macro
#define ALIGN(size) ((size & 0xfffffffc) + ((size & 3) ? 4 : 0))
#ifdef _HTTP_DEBUGGING_
typedef VOID _stdcall E_HTTPDebug(const char *,const char*,UINT32,char *,...); // HTTPDebug hook function
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Section : HTTP API internals structures
// Last updated : 01/09/2005
//
///////////////////////////////////////////////////////////////////////////////
// Generic parameter structure contains a pointer to the buffer and its length
typedef struct _HTTP_PARAM
{
CHAR *pParam;
UINT32 nLength;
} HTTP_PARAM;
// HTTP socket events
typedef struct _HTTP_CONNECTION
{
fd_set FDRead; // socket read event
fd_set FDWrite; // socket write event
fd_set FDError; // socket error event
INT32 HttpSocket; // The underling socket
UINT32 HttpStartTime; // Time stamp for the session
UINT32 HttpClientPort; // For client side binding
BOOL TlsNego; // TLS negotiation flag
} HTTP_CONNECTION;
// Request URL
typedef struct _HTTP_URL
{
HTTP_PARAM UrlBsee; // a pointer and length to the "http" section of the URL
HTTP_PARAM UrlHost; // a pointer and length to the host section of the URL
HTTP_PARAM UrlPort; // a pointer and length to the PORT (if was specified section)
HTTP_PARAM UrlRequest; // a pointer and length of the request section of the URL
UINT16 nPort; // the PORT that we should use (could be default or the one found within the URL)
CHAR* Url; // a buffer for the URL
}HTTP_URL;
// HTTP headers (incoming and outgoing)
typedef struct _HTTP_HEADERS
{
HTTP_PARAM HeadersBuffer; // a pointer and length of the complete Headers (in\out) buffer
HTTP_PARAM HeadersOut; // a pointer and length of the outgoing HTTP headers
HTTP_PARAM HeadersIn; // a pointer and length of the incoming headers
HTTP_PARAM HeaderSearch; // Index and pointer for the header search functions
HTTP_VERB HttpVerb; // the HTTP verb that was used in the session
HTTP_VERB HttpLastVerb; // the HTTP verb that was last transmited to the server
CHAR *SearchClue;
CHAR Verb[16]; // the actual string buffer of the HTTP verb
}HTTP_HEADERS;
// HTTP headers (parsed headers information)
typedef struct _HTTP_HEADERS_INFO
{
HTTP_PARAM HttpRedirectURL; // Stores the redirection URL if we got a 301 or 303 return code
UINT32 nHTTPStatus; // the HTTP status code (200 401 407 act')
UINT32 nHTTPContentLength; // the Content length if specified of the returned data
UINT32 nHTTPPostContentLength;// the Content-Length of the POSTed data (if known)
BOOL Connection; // True = Keep alive or undefined, False = Closed
BOOL ValidHeaders; // a flag that indicates if the incoming header ware parsed OK and found to be valid
BOOL HaveCredentials; // a flag that indicates if we have credentials for the session
CHAR HTTPVersion[16]; // HTTP version string buffer (for example: "HTTP 1.1")
}HTTP_HEADERS_INFO;
// Authentication parameters that ware extracted from the incoming headers
typedef struct _HTTP_AUTH_HEADER
{
HTTP_PARAM AuthHeader; // the pointer and length of the authentication header
UINT32 HTTP_AUTH_SCHEMA; // Its schema (could be any of the supported)
}HTTP_AUTH_HEADER;
// Proxy related data
typedef struct _HTTP_PROXY
{
CHAR* ProxyHost;
CHAR* ProxtUser;
CHAR* ProxyPassword;
UINT16 nProxyPort;
CHAR AuthSchemaName[16]; // The authentication schema name (for string comperission)
HTTP_AUTH_SCHEMA ProxyAuthSchema;
}HTTP_PROXY;
// HTTP User credentials
typedef struct _HTTP_CREDENTIALS
{
CHAR* CredUser;
CHAR* CredPassword;
CHAR AuthSchemaName[16]; // The authentication schema name (for string comperission)
HTTP_AUTH_SCHEMA CredAuthSchema; // The schema that calle has selected for the session
BOOL Authentication; // a flag that indicates that this session has requested a user authentication
}HTTP_CREDENTIALS;
// HTTP Counters
typedef struct _HTTP_COUNTERS
{
UINT32 nRecivedHeaderLength; // Bytes count of the incoming header
UINT32 nRecivedBodyLength; // Bytes count of the incoming body length
UINT32 nRecivedChunkLength; // The next chunk length in bytes
UINT32 nBytesToNextChunk; // How many bytes we have to read until we can expect the next chunk
UINT32 nActionStartTime; // Operation start time
UINT32 nActionTimeout; // Timeout for the session
UINT32 nSentChunks; // Count of sent chunks
UINT32 nSentBodyBytes; // Count of body bytes that ware sent
UINT32 nSentHeaderBytes; // Count of header bytes thhat ware sent
}HTTP_COUNTERS;
// HTTP Client Session data
typedef struct _HTTP_REQUEST
{
HTTP_URL HttpUrl;
HTTP_HEADERS HttpHeaders;
HTTP_HEADERS_INFO HttpHeadersInfo;
HTTP_AUTH_HEADER HttpAuthHeader;
HTTP_PROXY HttpProxy;
HTTP_CREDENTIALS HttpCredentials;
HTTP_CONNECTION HttpConnection;
HTTP_COUNTERS HttpCounters;
UINT32 HttpState;
UINT32 HttpFlags;
#ifdef _HTTP_DEBUGGING_
E_HTTPDebug *pDebug;
#endif
#if TLS_CONFIG_HTTP_CLIENT_SECURE
tls_ssl_t *ssl;
int ssl_more_data;
#endif
} HTTP_SESSION, *P_HTTP_SESSION;
/***********move to wm_http_client.h**************
// HTTP Type Definitions
typedef UINT32 HTTP_SESSION_HANDLE;
typedef UINT32 HTTP_CLIENT_SESSION_FLAGS;
*/
typedef tls_http_session_handle_t HTTP_SESSION_HANDLE;
typedef tls_http_session_flags_t HTTP_CLIENT_SESSION_FLAGS;
///////////////////////////////////////////////////////////////////////////////
//
// Section : HTTP API public interface
// Last updated : 01/09/2005
//
///////////////////////////////////////////////////////////////////////////////
/***********move to wm_http_client.h**************
HTTP_SESSION_HANDLE HTTPClientOpenRequest (HTTP_CLIENT_SESSION_FLAGS Flags);
UINT32 HTTPClientCloseRequest (HTTP_SESSION_HANDLE *pSession);
UINT32 HTTPClientSetAuth (HTTP_SESSION_HANDLE pSession, HTTP_AUTH_SCHEMA AuthSchema, void *pReserved);
UINT32 HTTPClientSetCredentials (HTTP_SESSION_HANDLE pSession, CHAR *pUserName, CHAR *pPassword);
UINT32 HTTPClientSetProxy (HTTP_SESSION_HANDLE pSession, CHAR *pProxyName, UINT16 nPort, CHAR *pUserName, CHAR *pPassword);
UINT32 HTTPClientSetVerb (HTTP_SESSION_HANDLE pSession, HTTP_VERB HttpVerb);
UINT32 HTTPClientAddRequestHeaders (HTTP_SESSION_HANDLE pSession, CHAR *pHeaderName, CHAR *pHeaderData, BOOL nInsert);
UINT32 HTTPClientSendRequest (HTTP_SESSION_HANDLE pSession, CHAR *pUrl, VOID *pData, UINT32 nDataLength, BOOL TotalLength, UINT32 nTimeout,UINT32 nClientPort);
UINT32 HTTPClientWriteData (HTTP_SESSION_HANDLE pSession, VOID *pBuffer, UINT32 nBufferLength, UINT32 nTimeout);
UINT32 HTTPClientRecvResponse (HTTP_SESSION_HANDLE pSession, UINT32 nTimeout);
UINT32 HTTPClientReadData (HTTP_SESSION_HANDLE pSession, VOID *pBuffer, UINT32 nBytesToRead, UINT32 nTimeout, UINT32 *nBytesRecived);
UINT32 HTTPClientGetInfo (HTTP_SESSION_HANDLE pSession, HTTP_CLIENT *HTTPClient);
UINT32 HTTPClientFindFirstHeader (HTTP_SESSION_HANDLE pSession, CHAR *pSearchClue,CHAR *pHeaderBuffer, UINT32 *nLength);
UINT32 HTTPClientGetNextHeader (HTTP_SESSION_HANDLE pSession, CHAR *pHeaderBuffer, UINT32 *nLength);
UINT32 HTTPClientFindCloseHeader (HTTP_SESSION_HANDLE pSession);
*/
UINT32 HTTPClientSetLocalConnection (HTTP_SESSION_HANDLE pSession, UINT32 nPort);
#ifdef _HTTP_DEBUGGING_
UINT32 HTTPClientSetDebugHook (HTTP_SESSION_HANDLE pSession,E_HTTPDebug *pDebug);
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Section : HTTP API private function
// Last updated : 01/09/2005
//
///////////////////////////////////////////////////////////////////////////////
static UINT32 HTTPIntrnResizeBuffer (P_HTTP_SESSION pHTTPSession, UINT32 nNewSize);
static UINT32 HTTPIntrnSetURL (P_HTTP_SESSION pHTTPSession, CHAR *pUrl,UINT32 nUrlLength);
static UINT32 HTTPIntrnConnectionClose (P_HTTP_SESSION pHTTPSession);
static UINT32 HTTPIntrnConnectionOpen (P_HTTP_SESSION pHTTPSession);
static UINT32 HTTPIntrnGetRemoteHeaders (P_HTTP_SESSION pHTTPSession);
static UINT32 HTTPIntrnGetRemoteChunkLength (P_HTTP_SESSION pHTTPSession);
static UINT32 HTTPIntrnSend (P_HTTP_SESSION pHTTPSession, CHAR *pData,UINT32 *nLength);
static UINT32 HTTPIntrnRecv (P_HTTP_SESSION pHTTPSession, CHAR *pData,UINT32 *nLength,BOOL PeekOnly);
static UINT32 HTTPIntrnParseAuthHeader (P_HTTP_SESSION pHTTPSession);
static UINT32 HTTPIntrnAuthHandler (P_HTTP_SESSION pHTTPSession);
static UINT32 HTTPIntrnAuthSendDigest (P_HTTP_SESSION pHTTPSession);
static UINT32 HTTPIntrnAuthSendBasic (P_HTTP_SESSION pHTTPSession);
static UINT32 HTTPIntrnAuthenticate (P_HTTP_SESSION pHTTPSession);
static UINT32 HTTPIntrnHeadersAdd (P_HTTP_SESSION pHTTPSession, CHAR *pHeaderName, UINT32 nNameLength, CHAR *pHeaderData, UINT32 nDataLength);
static UINT32 HTTPIntrnHeadersRemove (P_HTTP_SESSION pHTTPSession, CHAR *pHeaderName);
static UINT32 HTTPIntrnHeadersReceive (P_HTTP_SESSION pHTTPSession, UINT32 nTimeout);
static UINT32 HTTPIntrnHeadersSend (P_HTTP_SESSION pHTTPSession, HTTP_VERB HttpVerb);
static UINT32 HTTPIntrnHeadersParse (P_HTTP_SESSION pHTTPSession);
static UINT32 HTTPIntrnHeadersFind (P_HTTP_SESSION pHTTPSession, CHAR *pHeaderName, HTTP_PARAM *pParam,BOOL IncommingHeaders,UINT32 nOffset);
static UINT32 HTTPIntrnSessionReset (P_HTTP_SESSION pHTTPSession, BOOL EntireSession);
static UINT32 HTTPIntrnSessionGetUpTime (VOID);
static BOOL HTTPIntrnSessionEvalTimeout (P_HTTP_SESSION pHTTPSession);
#ifdef __cplusplus
}
#endif
#endif //_HTTP_CLIENT
+673
View File
@@ -0,0 +1,673 @@
///////////////////////////////////////////////////////////////////////////////
// Module Name:
// HTTPClientAuth.c
//
// Abstract: Handle Digest, MD5 and 64 Bit Encoding
//
// Platform: Any that supports standard C calls
///////////////////////////////////////////////////////////////////////////////
#include "wm_config.h"
#include "wm_mem.h"
#include "HTTPClientAuth.h"
#if TLS_CONFIG_HTTP_CLIENT
#if TLS_CONFIG_HTTP_CLIENT_AUTH_BASIC
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : HTTPBase64Encoder
// Purpose : Converts a given string into a base64 encoded buffer.
// Last updated : 01/09/200515/05/2005
// Author Name : Eitan Michaelson
// Notes :
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void HTTPBase64Encoder(unsigned char *out, const unsigned char *in, int inlen)
// [OUT] out A pointer to a char to hold the converted string
// [IN] in String to convert
// [IN] inlen Length of the string to be converted
{
for (; inlen >= 3; inlen -= 3)
{
*out++ = base64digits[in[0] >> 2];
*out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
*out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
*out++ = base64digits[in[2] & 0x3f];
in += 3;
}
if (inlen > 0)
{
unsigned char fragment;
*out++ = base64digits[in[0] >> 2];
fragment = (in[0] << 4) & 0x30;
if (inlen > 1)
fragment |= in[1] >> 4;
*out++ = base64digits[fragment];
*out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
*out++ = '=';
}
*out = '\0';
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : HTTPBase64Decoder
// Purpose : Converts a given base64 string into a bytes buffer.
// Last updated : 01/09/200515/05/2005
// Author Name : Eitan Michaelson
// Notes :
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int HTTPBase64Decoder(char *out, const char *in)
{ // [OUT] out Where to save the converted string
// [IN] in String to convert
int len = 0;
register unsigned char digit1, digit2, digit3, digit4;
if (in[0] == '+' && in[1] == ' ')
in += 2;
if (*in == '\r')
return(0);
do {
digit1 = in[0];
if (DECODE64(digit1) == BAD)
return(-1);
digit2 = in[1];
if (DECODE64(digit2) == BAD)
return(-1);
digit3 = in[2];
if (digit3 != '=' && DECODE64(digit3) == BAD)
return(-1);
digit4 = in[3];
if (digit4 != '=' && DECODE64(digit4) == BAD)
return(-1);
in += 4;
*out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);
++len;
if (digit3 != '=')
{
*out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2);
++len;
if (digit4 != '=')
{
*out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4);
++len;
}
}
} while (*in && *in != '\r' && digit4 != '=');
return (len);
}
#endif //TLS_CONFIG_HTTP_CLIENT_AUTH_BASIC
#if TLS_CONFIG_HTTP_CLIENT_AUTH_DIGEST
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Purpose : The following code implements the calculations of H(A1), H(A2),
// request-digest and response-digest
// Last updated : 01/09/200515/05/2005
// Author Name : Public Domain\RFC2617
// Notes : Digest Access Authentication
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : GenerateCNonce
// Purpose : Generates a 32 byte random hexadecimal string such as "4f6ba982..."
// Last updated : 15/05/2005
// Author Name : Eitan Michaelson
// Notes :
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void HTTPDigestGenerateCNonce(char *outbuff)
{
int i,num;
InitRandomeNumber();
for(i = 0; i < 32; i++) {
num = GetRandomeNumber();
switch(num) {
case 0: case 1: case 2: case 3: case 4: case 5:
case 6: case 7: case 8: case 9:
outbuff[i] = '0' + num;
break;
case 10: case 11: case 12: case 13: case 14: case 15:
outbuff[i] = 'a' + (num-10);
break;
default:
outbuff[i] = 'f';
}
}
outbuff[32] = 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : DigestCvtHex
// Purpose : CConvert to HEX
// Last updated : 15/05/2005
// Author Name : Public Domain\RFC2617
// Notes :
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void HTTPDigestCvtHex(IN HASH Bin,OUT HASHHEX Hex)
{
unsigned short i;
unsigned char j;
for (i = 0; i < HASHLEN; i++) {
j = (Bin[i] >> 4) & 0xf;
if (j <= 9)
Hex[i*2] = (j + '0');
else
Hex[i*2] = (j + 'a' - 10);
j = Bin[i] & 0xf;
if (j <= 9)
Hex[i*2+1] = (j + '0');
else
Hex[i*2+1] = (j + 'a' - 10);
};
Hex[HASHHEXLEN] = '\0';
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : DigestCalcHA1
// Purpose : Calculate H(A1) as per spec
// Last updated : 15/05/2005
// Author Name : Public Domain\RFC2617
// Notes :
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void HTTPDigestCalcHA1(
IN int nAlg, /* 0 = MD5, 1 = MD5-Sess */
IN char * pszUserName,
IN char * pszRealm,
IN int nRealmLength,
IN char * pszPassword,
IN char * pszNonce,
IN int nNonceLength,
IN char * pszCNonce,
OUT HASHHEX SessionKey
)
{
MD5_CTX Md5Ctx;
HASH HA1;
HASHHEX HASess;
HASH HAll;
HTTPMD5Init(&Md5Ctx);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszUserName, strlen(pszUserName)); //Daniel casting
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszRealm, nRealmLength); //Daniel
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszPassword, strlen(pszPassword)); //Daniel
HTTPMD5Final((unsigned char *)HA1, &Md5Ctx);
if (nAlg == 1) /* MD5-Sess */
{
HTTPDigestCvtHex(HA1, HASess);
HTTPMD5Init(&Md5Ctx);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)HASess, HASHHEXLEN);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszNonce, nNonceLength);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszCNonce, strlen(pszCNonce));
HTTPMD5Final((unsigned char *)HAll, &Md5Ctx);
HTTPDigestCvtHex(HAll, SessionKey);
return;
}
HTTPDigestCvtHex(HA1, SessionKey);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : DigestCalcResponse
// Purpose : Calculate request-digest/response-digest as per HTTP Digest spec
// Last updated : 15/05/2005
// Author Name : Public Domain\RFC2617
// Notes :
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void HTTPDigestCalcResponse(
IN HASHHEX HA1, // H(A1)
IN char * pszNonce, // nonce from server
IN int nNonceLength, // Length of nonce
IN char * pszNonceCount, // 8 hex digits
IN char * pszCNonce, // client nonce */
IN char * pszQop, // qop-value: "", "auth", "auth-int"
IN int nQopLength, // qop param length
IN char * pszMethod, // method from the request
IN char * pszDigestUri, // requested URL
IN int nDigestUriLebgth, // Uri Length
IN HASHHEX HEntity, // H(entity body) if qop="auth-int"
OUT HASHHEX Response // request-digest or response-digest
)
{
MD5_CTX Md5Ctx;
HASH HA2;
HASH RespHash;
HASHHEX HA2Hex;
// Calculate H(A2)
HTTPMD5Init(&Md5Ctx);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszMethod, strlen(pszMethod));
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszDigestUri, nDigestUriLebgth);
if (stricmp(pszQop, "auth-int") == 0)
{
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)HEntity, HASHHEXLEN);
};
HTTPMD5Final((unsigned char *)HA2, &Md5Ctx);
HTTPDigestCvtHex(HA2, HA2Hex);
// Calculate response
HTTPMD5Init(&Md5Ctx);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)HA1, HASHHEXLEN);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszNonce, nNonceLength);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
if (*pszQop)
{
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszNonceCount, strlen(pszNonceCount));
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszCNonce, strlen(pszCNonce));
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszQop, nQopLength);
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
};
HTTPMD5Update(&Md5Ctx, (const unsigned char *)HA2Hex, HASHHEXLEN);
HTTPMD5Final((unsigned char *)RespHash, &Md5Ctx);
HTTPDigestCvtHex(RespHash, Response);
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Purpose : This code implements the MD5 message-digest algorithm.
// The algorithm is due to Ron Rivest. This code was
// written by Colin Plumb in 1993, no copyright is claimed.
// This code is in the public domain; do with it what you wish.
// Equivalent code is available from RSA Data Security, Inc.
// This code has been tested against that, and is equivalent,
// except that you don't need to include two pages of legalese
// with every copy.
// Usage : To compute the message digest of a chunk of bytes, declare an
// MD5Context structure, pass it to MD5Init, call MD5Update as
// needed on buffers full of bytes, and then call MD5Final, which
// will fill a supplied 16-byte array with the digest.
// Last updated : 15/05/2005
// Author Name : Public Domain
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef HIGHFIRST
#define HTTPMD5ByteReverse(buf, len) /* Nothing */
#else
void HTTPMD5ByteReverse(unsigned char *buf, unsigned longs);
#ifndef ASM_MD5
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : ByteReverse
// Purpose : Little\Big Endian support
// Gets :
// Returns :
// Last updated : 15/05/2005
// Author Name : Public Domain
// Notes : this code is harmless on little-endian machines.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void HTTPMD5ByteReverse(unsigned char *buf, unsigned longs)
{
UINT32 t;
do {
t = (UINT32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
((unsigned) buf[1] << 8 | buf[0]);
*(UINT32 *) buf = t;
buf += 4;
} while (--longs);
}
#endif
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : MD5Init
// Purpose : Initialize the MD5Context structure
// Gets : MD5Context structure
// Returns :
// Last updated : 15/05/2005
// Author Name : Public Domain
// Notes : Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
// initialization constants.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void HTTPMD5Init(struct MD5Context *ctx)
{
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
ctx->buf[3] = 0x10325476;
ctx->bits[0] = 0;
ctx->bits[1] = 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : MD5Update
// Purpose : Update the MD5Context structure with the target byte array
// Gets : MD5Context structure, buffer and length
// Returns :
// Last updated : 15/05/2005
// Author Name : Public Domain
// Notes : Update context to reflect the concatenation of another buffer full of bytes.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void HTTPMD5Update(struct MD5Context *ctx, UCHAR const *buf, unsigned len)
{
UINT32 t;
// Update bitcount
t = ctx->bits[0];
if ((ctx->bits[0] = t + ((UINT32) len << 3)) < t)
ctx->bits[1]++; // Carry from low to high
ctx->bits[1] += len >> 29;
t = (t >> 3) & 0x3f; // Bytes already in shsInfo->data
// Handle any leading odd-sized chunks
if (t) {
unsigned char *p = (unsigned char *) ctx->in + t;
t = 64 - t;
if (len < t) {
MEMCPY(p, buf, len);
return;
}
MEMCPY(p, buf, t);
HTTPMD5ByteReverse(ctx->in, 16);
HTTPMD5Transform(ctx->buf, (UINT32 *) ctx->in);
buf += t;
len -= t;
}
// Process data in 64-byte chunks
while (len >= 64) {
MEMCPY(ctx->in, buf, 64);
HTTPMD5ByteReverse(ctx->in, 16);
HTTPMD5Transform(ctx->buf, (UINT32 *) ctx->in);
buf += 64;
len -= 64;
}
// Handle any remaining bytes of data.
MEMCPY(ctx->in, buf, len);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : MD5Final
// Purpose : Finalize.
// Gets : Output digest structure, MD5Context structure
// Returns :
// Last updated : 15/05/2005
// Author Name : Public Domain
// Notes : Final wrapup - pad to 64-byte boundary with the bit pattern
// 1 0* (64-bit count of bits processed, MSB-first).
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
void HTTPMD5Final(unsigned char digest[16], struct MD5Context *ctx)
{
unsigned count;
unsigned char *p;
// Compute number of bytes mod 64
count = (ctx->bits[0] >> 3) & 0x3F;
// Set the first char of padding to 0x80. This is safe since there is
// always at least one byte free
p = ctx->in + count;
*p++ = 0x80;
// Bytes of padding needed to make 64 bytes
count = 64 - 1 - count;
// Pad out to 56 mod 64 */
if (count < 8) {
// Two lots of padding: Pad the first block to 64 bytes
memset(p, 0, count);
HTTPMD5ByteReverse(ctx->in, 16);
HTTPMD5Transform(ctx->buf, (UINT32 *) ctx->in);
// Now fill the next block with 56 bytes
memset(ctx->in, 0, 56);
} else {
// Pad block to 56 bytes
memset(p, 0, count - 8);
}
HTTPMD5ByteReverse(ctx->in, 14);
// Append length in bits and transform
((UINT32 *) ctx->in)[14] = ctx->bits[0];
((UINT32 *) ctx->in)[15] = ctx->bits[1];
HTTPMD5Transform(ctx->buf, (UINT32 *) ctx->in);
HTTPMD5ByteReverse((unsigned char *) ctx->buf, 4);
MEMCPY(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(ctx)); // In case it's sensitive
}
#ifndef ASM_MD5
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function :
// Purpose : The four core functions - F1 is optimized somewhat
// Last updated : 15/05/2005
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
// This is the central step in the MD5 algorithm.
#ifdef __PUREC__
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f /*(x, y, z)*/ + data, w = w<<s | w>>(32-s), w += x )
#else
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Function : MD5Transform
// Purpose : The core of the MD5 algorithm, this alters an existing MD5 hash to
// reflect the addition of 16 longwords of new data. MD5Update blocks
// the data and converts bytes into longwords for this routine.
// Last updated : 15/05/2005
// Author Name : Public Domain
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void HTTPMD5Transform(UINT32 buf[4], UINT32 const in[16])
{
register UINT32 a, b, c, d;
a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
#ifdef __PUREC__ // PureC Weirdness... (GG)
MD5STEP(F1(b,c,d), a, b, c, d, in[0] + 0xd76aa478L, 7);
MD5STEP(F1(a,b,c), d, a, b, c, in[1] + 0xe8c7b756L, 12);
MD5STEP(F1(d,a,b), c, d, a, b, in[2] + 0x242070dbL, 17);
MD5STEP(F1(c,d,a), b, c, d, a, in[3] + 0xc1bdceeeL, 22);
MD5STEP(F1(b,c,d), a, b, c, d, in[4] + 0xf57c0fafL, 7);
MD5STEP(F1(a,b,c), d, a, b, c, in[5] + 0x4787c62aL, 12);
MD5STEP(F1(d,a,b), c, d, a, b, in[6] + 0xa8304613L, 17);
MD5STEP(F1(c,d,a), b, c, d, a, in[7] + 0xfd469501L, 22);
MD5STEP(F1(b,c,d), a, b, c, d, in[8] + 0x698098d8L, 7);
MD5STEP(F1(a,b,c), d, a, b, c, in[9] + 0x8b44f7afL, 12);
MD5STEP(F1(d,a,b), c, d, a, b, in[10] + 0xffff5bb1L, 17);
MD5STEP(F1(c,d,a), b, c, d, a, in[11] + 0x895cd7beL, 22);
MD5STEP(F1(b,c,d), a, b, c, d, in[12] + 0x6b901122L, 7);
MD5STEP(F1(a,b,c), d, a, b, c, in[13] + 0xfd987193L, 12);
MD5STEP(F1(d,a,b), c, d, a, b, in[14] + 0xa679438eL, 17);
MD5STEP(F1(c,d,a), b, c, d, a, in[15] + 0x49b40821L, 22);
MD5STEP(F2(b,c,d), a, b, c, d, in[1] + 0xf61e2562L, 5);
MD5STEP(F2(a,b,c), d, a, b, c, in[6] + 0xc040b340L, 9);
MD5STEP(F2(d,a,b), c, d, a, b, in[11] + 0x265e5a51L, 14);
MD5STEP(F2(c,d,a), b, c, d, a, in[0] + 0xe9b6c7aaL, 20);
MD5STEP(F2(b,c,d), a, b, c, d, in[5] + 0xd62f105dL, 5);
MD5STEP(F2(a,b,c), d, a, b, c, in[10] + 0x02441453L, 9);
MD5STEP(F2(d,a,b), c, d, a, b, in[15] + 0xd8a1e681L, 14);
MD5STEP(F2(c,d,a), b, c, d, a, in[4] + 0xe7d3fbc8L, 20);
MD5STEP(F2(b,c,d), a, b, c, d, in[9] + 0x21e1cde6L, 5);
MD5STEP(F2(a,b,c), d, a, b, c, in[14] + 0xc33707d6L, 9);
MD5STEP(F2(d,a,b), c, d, a, b, in[3] + 0xf4d50d87L, 14);
MD5STEP(F2(c,d,a), b, c, d, a, in[8] + 0x455a14edL, 20);
MD5STEP(F2(b,c,d), a, b, c, d, in[13] + 0xa9e3e905L, 5);
MD5STEP(F2(a,b,c), d, a, b, c, in[2] + 0xfcefa3f8L, 9);
MD5STEP(F2(d,a,b), c, d, a, b, in[7] + 0x676f02d9L, 14);
MD5STEP(F2(c,d,a), b, c, d, a, in[12] + 0x8d2a4c8aL, 20);
MD5STEP(F3(b,c,d), a, b, c, d, in[5] + 0xfffa3942L, 4);
MD5STEP(F3(a,b,c), d, a, b, c, in[8] + 0x8771f681L, 11);
MD5STEP(F3(d,a,b), c, d, a, b, in[11] + 0x6d9d6122L, 16);
MD5STEP(F3(c,d,a), b, c, d, a, in[14] + 0xfde5380cL, 23);
MD5STEP(F3(b,c,d), a, b, c, d, in[1] + 0xa4beea44L, 4);
MD5STEP(F3(a,b,c), d, a, b, c, in[4] + 0x4bdecfa9L, 11);
MD5STEP(F3(d,a,b), c, d, a, b, in[7] + 0xf6bb4b60L, 16);
MD5STEP(F3(c,d,a), b, c, d, a, in[10] + 0xbebfbc70L, 23);
MD5STEP(F3(b,c,d), a, b, c, d, in[13] + 0x289b7ec6L, 4);
MD5STEP(F3(a,b,c), d, a, b, c, in[0] + 0xeaa127faL, 11);
MD5STEP(F3(d,a,b), c, d, a, b, in[3] + 0xd4ef3085L, 16);
MD5STEP(F3(c,d,a), b, c, d, a, in[6] + 0x04881d05L, 23);
MD5STEP(F3(b,c,d), a, b, c, d, in[9] + 0xd9d4d039L, 4);
MD5STEP(F3(a,b,c), d, a, b, c, in[12] + 0xe6db99e5L, 11);
MD5STEP(F3(d,a,b), c, d, a, b, in[15] + 0x1fa27cf8L, 16);
MD5STEP(F3(c,d,a), b, c, d, a, in[2] + 0xc4ac5665L, 23);
MD5STEP(F4(b,c,d), a, b, c, d, in[0] + 0xf4292244L, 6);
MD5STEP(F4(a,b,c), d, a, b, c, in[7] + 0x432aff97L, 10);
MD5STEP(F4(d,a,b), c, d, a, b, in[14] + 0xab9423a7L, 15);
MD5STEP(F4(c,d,a), b, c, d, a, in[5] + 0xfc93a039L, 21);
MD5STEP(F4(b,c,d), a, b, c, d, in[12] + 0x655b59c3L, 6);
MD5STEP(F4(a,b,c), d, a, b, c, in[3] + 0x8f0ccc92L, 10);
MD5STEP(F4(d,a,b), c, d, a, b, in[10] + 0xffeff47dL, 15);
MD5STEP(F4(c,d,a), b, c, d, a, in[1] + 0x85845dd1L, 21);
MD5STEP(F4(b,c,d), a, b, c, d, in[8] + 0x6fa87e4fL, 6);
MD5STEP(F4(a,b,c), d, a, b, c, in[15] + 0xfe2ce6e0L, 10);
MD5STEP(F4(d,a,b), c, d, a, b, in[6] + 0xa3014314L, 15);
MD5STEP(F4(c,d,a), b, c, d, a, in[13] + 0x4e0811a1L, 21);
MD5STEP(F4(b,c,d), a, b, c, d, in[4] + 0xf7537e82L, 6);
MD5STEP(F4(a,b,c), d, a, b, c, in[11] + 0xbd3af235L, 10);
MD5STEP(F4(d,a,b), c, d, a, b, in[2] + 0x2ad7d2bbL, 15);
MD5STEP(F4(c,d,a), b, c, d, a, in[9] + 0xeb86d391L, 21);
#else
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
#endif
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
#endif
#endif //TLS_CONFIG_HTTP_CLIENT_AUTH_DIGEST
#endif //TLS_CONFIG_HTTP_CLIENT
+93
View File
@@ -0,0 +1,93 @@
#ifndef HTTP_CLIENT_AUTH_H
#define HTTP_CLIENT_AUTH_H
#include "HTTPClientString.h" // Cross platform support
#if TLS_CONFIG_HTTP_CLIENT_AUTH
#include "md5.h"
#endif
#define HASHLEN 16
#define HASHHEXLEN 32
#define IN
#define OUT
typedef char HASH[HASHLEN];
typedef char HASHHEX[HASHHEXLEN+1];
//typedef unsigned long uint32;
#undef isascii
#define isascii(_Char) ( (unsigned)(_Char) < 0x80 )
// Base 64 Related
#define DECODE64(c) (isascii(c) ? base64val[c] : BAD)
#define BAD 0xFF //-1
static const char base64digits[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char base64val[] = {
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,BAD,BAD, BAD,BAD,BAD,BAD,
BAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,BAD, BAD,BAD,BAD,BAD,
BAD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,BAD, BAD,BAD,BAD,BAD
};
void HTTPBase64Encoder(unsigned char *out, const unsigned char *in, int inlen);
int HTTPBase64Decoder(char *out, const char *in);
// Digest Related
// Generates a 32 byte random hexadecimal string such as "4f6ba982..."
void HTTPDigestGenerateCNonce(char *outbuff);
// Calculate H(A1) as per HTTP Digest spec
void HTTPDigestCalcHA1(
IN int nAlg, /* 0 = MD5, 1 = MD5-Sess */
IN char * pszUserName,
IN char * pszRealm,
IN int nRealmLength,
IN char * pszPassword,
IN char * pszNonce,
IN int nNonceLength,
IN char * pszCNonce,
OUT HASHHEX SessionKey
);
// Calculate request-digest/response-digest as per HTTP Digest spec
void HTTPDigestCalcResponse(
IN HASHHEX HA1, // H(A1)
IN char * pszNonce, // nonce from server
IN int nNonceLength, // Length of nonce
IN char * pszNonceCount, // 8 hex digits
IN char * pszCNonce, // client nonce
IN char * pszQop, // qop-value: "", "auth", "auth-int"
IN int nQopLength, // qop param length
IN char * pszMethod, // method from the request
IN char * pszDigestUri, // requested URL
IN int nDigestUriLebgth, // Uri Length
IN HASHHEX HEntity, // H(entity body) if qop="auth-int"
OUT HASHHEX Response // request-digest or response-digest
);
// MD5 structures and functions
/*struct MD5Context
{
u32 buf[4];
u32 bits[2];
unsigned char in[64];
};
*/
#if TLS_CONFIG_HTTP_CLIENT_AUTH_DIGEST
void HTTPMD5Init (struct MD5Context *context);
void HTTPMD5Update (struct MD5Context *context, unsigned char const *buf,unsigned len);
void HTTPMD5Final (unsigned char digest[16], struct MD5Context *context);
void HTTPMD5Transform (u32 buf[4], u32 const in[16]);
#endif
// This is needed to make RSAREF happy on some MS-DOS compilers.
typedef struct MD5Context MD5_CTX;
#endif
+42
View File
@@ -0,0 +1,42 @@
///////////////////////////////////////////////////////////////////////////////
//
// Module Name:
// CmsiHTTPClientCommon.h
//
// Abstract: Coomon structs and types for the HTTP protocol API
// Author: Eitan Michaelso
// Version: 1.0
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _HTTPCLIENT_PROTOCOL_H_
#define _HTTPCLIENT_PROTOCOL_H_
#include "wm_type_def.h"
#ifdef __cplusplus
extern "C" {
#endif
// Global default sizes
#define HTTP_CLIENT_MAX_URL_LENGTH 512 // Maximum length for an HTTP Url parameter
// HTTP Session flags (Public flags)
#define HTTP_CLIENT_FLAG_KEEP_ALIVE 0x00000001 // Set the keep alive header
#define HTTP_CLIENT_FLAG_SEND_CHUNKED 0x00000002 // The outgoing should chunked
#define HTTP_CLIENT_FLAG_NO_CACHE 0x00000004 // Set the no cache header
#define HTTP_CLIENT_FLAG_ASYNC 0x00000008 // Currently not implemented
// HTTP status internal flags
#define HTTP_CLIENT_STATE_PRE_INIT 0x00000000 // Starting stage
#define HTTP_CLIENT_STATE_INIT 0x00000001 // API was initialized (memory was allocated)
#define HTTP_CLIENT_STATE_URL_PARSED 0x00000002 // Url was parsed
#define HTTP_CLIENT_STATE_HOST_CONNECTED 0x00000004 // HEAD verb was sent
#define HTTP_CLIENT_STATE_HEAD_SENT 0x00000008 // Post verb was sent
#define HTTP_CLIENT_STATE_POST_SENT 0x00000010 // HTTP requet was sent
#define HTTP_CLIENT_STATE_REQUEST_SENT 0x00000020 // HTTP request was sent
#define HTTP_CLIENT_STATE_HEADERS_RECIVED 0x00000040 // Headers ware recived from the server
#define HTTP_CLIENT_STATE_HEADERS_PARSED 0x00000080 // HTTP headers ware parsed
#define HTTP_CLIENT_STATE_HEADERS_OK 0x00000100 // Headers status was OK
#endif // _HTTPCLIENT_PROTOCOL_H_
+433
View File
@@ -0,0 +1,433 @@
///////////////////////////////////////////////////////////////////////////////
//
// 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
+23
View File
@@ -0,0 +1,23 @@
#ifndef _HTTP_CLIENT_STRING
#define _HTTP_CLIENT_STRING
#include "HTTPClientWrapper.h" // Cross platform support
#include "HTTPClient.h"
///////////////////////////////////////////////////////////////////////////////
//
// Section : HTTP Api global definitions
// Last updated : 01/09/2005
//
///////////////////////////////////////////////////////////////////////////////
int stricmp(const char *s1, const char *s2) ;
BOOL HTTPStrInsensitiveCompare (const CHAR *pSrc, const CHAR* pDest, UINT32 nLength);
BOOL HTTPStrSearch (CHAR *pSrc, CHAR *pSearched, UINT32 nOffset, UINT32 nScope,HTTP_PARAM *HttpParam);
CHAR HTTPStrExtract (CHAR *pParam,UINT32 nOffset,CHAR Restore);
CHAR* HTTPStrCaseStr (const CHAR *pSrc, UINT32 nSrcLength, const CHAR *pFind);
CHAR* HTTPStrGetToken (CHAR *pSrc, UINT32 nSrcLength, CHAR *pDest, UINT32 *nDestLength);
UINT32 HTTPStrGetDigestToken (HTTP_PARAM pParamSrc, CHAR *pSearched, HTTP_PARAM *pParamDest);
UINT32 HTTPStrHToL (CHAR * s);
CHAR* HTTPStrLToH (CHAR * dest,UINT32 nSrc);
#endif
+754
View File
@@ -0,0 +1,754 @@
#include "lwip/arch.h"
#include "HTTPClientWrapper.h"
#include "random.h"
#include "wm_osal.h"
#include "wm_sockets.h"
#include "lwip/sockets.h"
#include "wm_debug.h"
#include "HTTPClient.h"
#if TLS_CONFIG_HTTP_CLIENT
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Section : Stdc: HTTPWrapperIsAscii
// Last updated : 15/05/2005
// Author Name : Eitan Michaelson
// Notes : Same as stdc: isascii
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int HTTPWrapperIsAscii(int c)
{
return (!(c & ~0177));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Section : Stdc: HTTPWrapperToUpper
// Last updated : 15/05/2005
// Author Name : Eitan Michaelson
// Notes : Convert character to uppercase.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int HTTPWrapperToUpper(int c)
{
// -32
if(HTTPWrapperIsAscii(c) > 0)
{
if(c >= 97 && c <= 122)
{
return (c - 32);
}
}
return c;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Section : Stdc: HTTPWrapperToLower
// Last updated : 13/06/2006
// Author Name : Eitan Michaelson
// Notes : Convert character to lowercase.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int HTTPWrapperToLower(int c)
{
// +32
if(HTTPWrapperIsAscii(c) > 0)
{
if(c >= 65 && c <= 90)
{
return (c + 32);
}
}
return c;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Section : Stdc: isalpha
// Last updated : 15/05/2005
// Author Name : Eitan Michaelson
// Notes : returns nonzero if c is a particular representation of an alphabetic character
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int HTTPWrapperIsAlpha(int c)
{
if(HTTPWrapperIsAscii(c) > 0)
{
if( (c >= 97 && c <= 122) || (c >= 65 && c <= 90))
{
return c;
}
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Section : Stdc: isalnum
// Last updated : 15/05/2005
// Author Name : Eitan Michaelson
// Notes : returns nonzero if c is a particular representation of an alphanumeric character
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int HTTPWrapperIsAlNum(int c)
{
if(HTTPWrapperIsAscii(c) > 0)
{
if(HTTPWrapperIsAlpha(c) > 0)
{
return c;
}
if( c >= 48 && c <= 57)
{
return c;
}
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Section : HTTPWrapper_itoa
// Last updated : 15/05/2005
// Author Name : Eitan Michaelson
// Notes : same as stdc itoa() // hmm.. allmost the same
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
char* HTTPWrapperItoa(char *s,int a)
{
unsigned int b;
if(a > 2147483647)
{
return 0; // overflow
}
if (a < 0) b = -a, *s++ = '-';
else b = a;
for(;a;a=a/10) s++;
for(*s='\0';b;b=b/10) *--s=b%10+'0';
return s;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Section : HTTPWrapper_ShutDown
// Last updated : 15/05/2005
// Author Name : Eitan Michaelson
// Notes : Handles parameter changes in the socket shutdown() function in AMT
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int HTTPWrapperShutDown (int s,int how)
{
return shutdown(s,how);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Section : HTTPWrapper_GetSocketError
// Last updated : 15/05/2005
// Author Name : Eitan Michaelson
// Notes : WSAGetLastError Wrapper (Win32 Specific)
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int HTTPWrapperGetSocketError (int s)
{
return errno;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Section : HTTPWrapper_GetRandomeNumber
// Last updated : 15/05/2005
// Author Name : Eitan Michaelson
// Notes : GetRandom number for Win32 & AMT
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void HTTPWrapperInitRandomeNumber()
{
srand((unsigned int)tls_os_get_time());
}
int HTTPWrapperGetRandomeNumber()
{
int num;
num = (int)(((double) rand()/ ((double)RAND_MAX+1)) * 16);
return num;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Section : HTTPWrapper_GetRTC
// Last updated : 15/05/2005
// Author Name : Eitan Michaelson
// Notes : Get uptime under Win32 & AMT
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
long HTTPWrapperGetUpTime()
{
long lTime = 0;
lTime = tls_os_get_time();
return lTime;
}
#endif //TLS_CONFIG_HTTP_CLIENT
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Section : HTTPWrapper_GetHostByName
// Last updated : 15/05/2005
// Author Name : Eitan Michaelson
// Notes : gethostbyname for Win32 (supports the AMT edition of the function)
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned long HTTPWrapperGetHostByName(char *name,unsigned long *address)
{
HTTP_HOSTNET *HostEntry;
int iPos = 0, iLen = 0,iNumPos = 0,iDots =0;
long iIPElement;
char c = 0;
char Num[4];
int iHostType = 0; // 0 : numeric IP
// Check if the name is an IP or host
iLen = strlen(name);
for(iPos = 0; iPos <= iLen;iPos++)
{
c = name[iPos];
if((c >= 48 && c <= 57) || (c == '.') )
{
// c is numeric or dot
if(c != '.')
{
// c is numeric
if(iNumPos > 3)
{
iHostType++;
break;
}
Num[iNumPos] = c;
Num[iNumPos + 1] = 0;
iNumPos ++;
}
else
{
iNumPos = 0;
iDots++;
iIPElement = atol(Num);
if(iIPElement > 256 || iDots > 3)
{
return 0; // error invalid IP
}
}
}
else
{
break; // this is an alpha numeric address type
}
}
if(c == 0 && iHostType == 0 && iDots == 3)
{
iIPElement = atol(Num);
if(iIPElement > 256)
{
return 0; // error invalid IP
}
}
else
{
iHostType++;
}
if(iHostType > 0)
{
HostEntry = gethostbyname(name);
if(HostEntry)
{
*(address) = *((u_long*)HostEntry->h_addr_list[0]);
//*(address) = (unsigned long)HostEntry->h_addr_list[0];
return 1; // Error
}
else
{
return 0; // OK
}
}
else // numeric address - no need for DNS resolve
{
*(address) = inet_addr(name);
return 1;
}
}
#if TLS_CONFIG_HTTP_CLIENT_SECURE
#define ALLOW_ANON_CONNECTIONS 1
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int HTTPWrapperSSLNegotiate(HTTP_SESSION_HANDLE pSession,int s,const struct sockaddr *name,int namelen,char *hostname)
{
return 0;
}
#if 1
#if 0
#define PSLL_PRT printf
#else
#define PSLL_PRT(x, ...)
#endif
/************************ memory manage ************************/
void *platform_malloc(uint32_t size)
{
return tls_mem_alloc(size);
}
void platform_free(void *ptr)
{
tls_mem_free(ptr);
}
/************************ mutex manage ************************/
void *platform_mutex_init(void)
{
tls_os_sem_t *mutex = NULL;
tls_os_sem_create(&mutex,1);
return mutex;
}
void platform_mutex_lock(void *mutex)
{
tls_os_sem_acquire(mutex,0);
}
void platform_mutex_unlock(void *mutex)
{
tls_os_sem_release(mutex);
}
void platform_mutex_destroy(void *mutex)
{
if (!mutex)
return;
tls_os_sem_delete(mutex);
}
static int ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
{
return random_get_bytes( output, output_len );
}
static void my_debug( void *ctx, int level, const char *str )
{
PSLL_PRT("%s", str);
}
static int net_is_blocking( void )
{
switch( errno )
{
#if defined EAGAIN
case EAGAIN:
#endif
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
return( 1 );
}
return( 0 );
}
static int net_recv( void *ctx, unsigned char *buf, size_t len )
{
int ret;
int skt = (int)(long) ctx;
#if 0
fd_set read_set;
struct timeval tv;
FD_ZERO(&read_set);
FD_SET(skt, &read_set);
tv.tv_sec = 5;
tv.tv_usec = 0;
ret = select(skt + 1, &read_set, NULL, NULL, &tv);
if (ret > 0)
{
if (FD_ISSET(skt, &read_set))
{
#endif
ret = recv( skt, buf, len, 0);
if( ret < 0 )
{
if( net_is_blocking() != 0 )
return( POLARSSL_ERR_NET_WANT_READ );
if( errno == EPIPE || errno == ECONNRESET )
return( POLARSSL_ERR_NET_CONN_RESET );
if( errno == EINTR )
return( POLARSSL_ERR_NET_WANT_READ );
return( POLARSSL_ERR_NET_RECV_FAILED );
}
#if 0
FD_CLR(skt, &read_set);
}
else
{
PSLL_PRT("\r\n\r\nssl select no\r\n\r\n");
}
}
else if (0 == ret)
{
PSLL_PRT("\r\n\r\nssl recv timeout\r\n\r\n");
}
else
{
PSLL_PRT("\r\n\r\nssl select error\r\n\r\n");
}
#endif
return ret;
}
/*
* Write at most 'len' characters
*/
static int net_send( void *ctx, const unsigned char *buf, size_t len )
{
int ret = send( (long) ctx, buf, len, 0);
if( ret < 0 )
{
if( net_is_blocking() != 0 )
return( POLARSSL_ERR_NET_WANT_WRITE );
if( errno == EPIPE || errno == ECONNRESET )
return( POLARSSL_ERR_NET_CONN_RESET );
if( errno == EINTR )
return( POLARSSL_ERR_NET_WANT_WRITE );
return( POLARSSL_ERR_NET_SEND_FAILED );
}
return( ret );
}
void *platform_ssl_connect(void *tcp_fd,
const char *server_cert,
int server_cert_len)
{
int ret;
ssl_context *ssl;
ssl_session *ssn;
x509_cert *cacert = NULL;
ssl = platform_malloc(sizeof(ssl_context));
if (!ssl)
return NULL;
ssn = platform_malloc(sizeof(ssl_session));
if (!ssn)
{
platform_free(ssl);
return NULL;
}
if (server_cert)
{
cacert = platform_malloc(sizeof(x509_cert));
if (!cacert)
{
platform_free(ssl);
platform_free(ssn);
return NULL;
}
memset(cacert, 0, sizeof(x509_cert));
ret = x509parse_crt(cacert, (unsigned char *) server_cert, server_cert_len);
if( ret != 0 )
{
PSLL_PRT( " failed\n ! x509parse_crt returned %d\n\n", ret );
platform_free(ssl);
platform_free(ssn);
if(cacert)
platform_free(cacert);
return NULL;
}
}
memset(ssl, 0, sizeof(ssl_context));
if( ( ret = ssl_init( ssl ) ) != 0 )
{
PSLL_PRT( " failed\n ! ssl_init returned %d\n\n", ret );
if(cacert)
x509_free( cacert );
platform_free(ssl);
platform_free(ssn);
if(cacert)
platform_free(cacert);
return NULL;
}
ssl_set_endpoint( ssl, SSL_IS_CLIENT );
if (server_cert)
ssl_set_authmode( ssl, SSL_VERIFY_REQUIRED );
else
ssl_set_authmode( ssl, SSL_VERIFY_NONE );
ssl_set_rng( ssl, ctr_drbg_random, NULL );
ssl_set_dbg( ssl, my_debug, NULL);
ssl_set_bio( ssl, net_recv, tcp_fd, net_send, tcp_fd );
ssl_set_ciphersuites( ssl, ssl_default_ciphersuites );
memset(ssn, 0, sizeof(ssl_session));
ssl_set_session( ssl, 1, 600, ssn );
if (server_cert)
ssl_set_ca_chain( ssl, cacert, NULL, NULL);
while( ( ret = ssl_handshake( ssl ) ) != 0 )
{
if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
{
PSLL_PRT( " failed\n ! ssl_handshake returned %d\n\n", ret );
goto fail;
}
PSLL_PRT("INFO: ssl_handshake returned %d\n\n", ret);
}
if (server_cert)
{
if( ( ret = ssl_get_verify_result( ssl ) ) != 0 )
{
PSLL_PRT( "Verifying peer X.509 certificate failed\n" );
if( ( ret & BADCERT_EXPIRED ) != 0 )
PSLL_PRT( " ! server certificate has expired\n" );
if( ( ret & BADCERT_REVOKED ) != 0 )
PSLL_PRT( " ! server certificate has been revoked\n" );
if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
PSLL_PRT( " ! CN mismatch \n");
if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
PSLL_PRT( " ! self-signed or not signed by a trusted CA\n" );
PSLL_PRT( "\n" );
ssl_close_notify( ssl );
goto fail;
}
else
{
PSLL_PRT( "Verifying X.509 certificate pass.\n" );
}
}
//ssl->read_lock = platform_mutex_init();
ssl->write_lock = platform_mutex_init();
//printf("ssl read/write lock 0x%p/0x%p\n", ssl->read_lock, ssl->write_lock);
PSLL_PRT("ssl rdwr lock 0x%p\n", ssl->write_lock);
return ssl;
fail:
if(cacert)
x509_free( cacert );
ssl_free( ssl );
platform_free(ssl);
platform_free(ssn);
if(cacert)
platform_free(cacert);
return NULL;
}
int platform_ssl_close(void *ssl)
{
ssl_context *sslt = (ssl_context *)ssl;
platform_mutex_lock(sslt->write_lock);
ssl_close_notify( sslt );
x509_free( sslt->ca_chain );
platform_free(sslt->ca_chain);
platform_free(sslt->session);
platform_mutex_unlock(sslt->write_lock);
platform_mutex_destroy(sslt->write_lock);
//platform_mutex_destroy(sslt->read_lock);
ssl_free(sslt);
platform_free(sslt);
return 0;
}
int platform_ssl_send(void *ssl, const char *buf, int len)
{
int ret;
ssl_context *sslt = (ssl_context *)ssl;
platform_mutex_lock(sslt->write_lock);
while( ( ret = ssl_write( sslt, (u8 *)buf, len ) ) <= 0 )
{
if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
{
PSLL_PRT( " failed\n ! ssl_write returned %d, errno %d\n", ret , errno);
break;
}
}
platform_mutex_unlock(sslt->write_lock);
return ret;
}
int platform_ssl_recv(void *ssl, char *buf, int len)
{
int ret;
ssl_context *sslt = (ssl_context *)ssl;
platform_mutex_lock(sslt->write_lock);
//platform_mutex_lock(sslt->read_lock);
do
{
ret = ssl_read( sslt, (u8 *)buf, len );
if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE )
continue;
//if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY )
// break;
if( ret < 0 )
{
PSLL_PRT( "failed\n ! ssl_read returned %d, errno %d\n", ret , errno);
break;
}
else if( ret == 0 )
{
PSLL_PRT("\n\nEOF, errno %d\n\n", errno);
break;
}
else
{
//PSLL_PRT( " %d bytes read\n\n%s", ret, (char *) buf );
break;
}
} while(1);
platform_mutex_unlock(sslt->write_lock);
//platform_mutex_unlock(sslt->read_lock);
//PSLL_PRT(" <== platform_ssl_recv ret %d\n", ret);
return ret;
}
int HTTPWrapperSSLConnect(tls_ssl_t **ssl_p,int fd,const struct sockaddr *name,int namelen,char *hostname)
{
int rc;
tls_ssl_t *ssl = NULL;
if(name)
{
char *host_ip = inet_ntoa(((struct sockaddr_in*)name)->sin_addr);
rc = connect(fd, // Socket
name, // Server address
sizeof(struct sockaddr));
if(rc)
{
TLS_DBGPRT_ERR("host_ip=%s\n", host_ip);
TLS_DBGPRT_ERR("Connection Failed: %d. Exiting\n", rc);
return rc;
}
}
ssl = platform_ssl_connect((void *)fd, NULL, 0);
if(ssl == NULL)
return -1;
*ssl_p = ssl;
return 0;
}
int HTTPWrapperSSLSend(tls_ssl_t *ssl, int s,char *sndbuf, int len,int flags)
{
return platform_ssl_send(ssl, sndbuf, len);
}
int HTTPWrapperSSLRecv(tls_ssl_t *ssl,int s,char *buf, int len,int flags)
{
int ret = platform_ssl_recv(ssl, buf, len);
if(ssl->in_msglen > 0)
return SOCKET_SSL_MORE_DATA;
return ret;
}
int HTTPWrapperSSLRecvPending(tls_ssl_t *ssl)
{
return ssl_get_bytes_avail(ssl);
}
int HTTPWrapperSSLClose(tls_ssl_t *ssl, int s)
{
if(ssl == NULL)
return 0;
return platform_ssl_close(ssl);
}
#endif //TLS_CONFIG_USE_POLARSSL
#endif //TLS_CONFIG_HTTP_CLIENT_SECURE
+121
View File
@@ -0,0 +1,121 @@
#ifndef HTTP_CLIENT_WRAPPER
#define HTTP_CLIENT_WRAPPER
#include "wm_config.h"
#include "lwip/arch.h"
#if TLS_CONFIG_HTTP_CLIENT_SECURE
#include "polarssl/config.h"
#include "polarssl/ssl.h"
#endif
// Compilation mode
//#define _HTTP_BUILD_WIN32 // Set Windows Build flag
///////////////////////////////////////////////////////////////////////////////
//
// Section : Microsoft Windows Support
// Last updated : 01/09/2005
//
///////////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <string.h>
//#include <memory.h>
#include <stdio.h>
#include <ctype.h>
//#include <time.h>
//#include <winsock.h>
#include "wm_type_def.h"
#include "wm_sockets.h"
#include "wm_http_client.h"
// Generic types
// Sockets (Winsock wrapper)
#define HTTP_ECONNRESET (ECONNRESET)
#define HTTP_EINPROGRESS (EINPROGRESS)
#define HTTP_EWOULDBLOCK (EWOULDBLOCK)
#define SOCKET_ERROR (-1)
#define SOCKET_SSL_MORE_DATA (-2)
///////////////////////////////////////////////////////////////////////////////
//
// Section : Functions that are not supported by the AMT stdc framework
// So they had to be specificaly added.
// Last updated : 01/09/2005
//
///////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif
#if TLS_CONFIG_HTTP_CLIENT_SECURE
typedef ssl_context tls_ssl_t;
#endif
// STDC Wrapper implimentation
int HTTPWrapperIsAscii (int c);
int HTTPWrapperToUpper (int c);
int HTTPWrapperToLower (int c);
int HTTPWrapperIsAlpha (int c);
int HTTPWrapperIsAlNum (int c);
char* HTTPWrapperItoa (char *buff,int i);
void HTTPWrapperInitRandomeNumber (void);
long HTTPWrapperGetUpTime (void);
int HTTPWrapperGetRandomeNumber (void);
int HTTPWrapperGetSocketError (int s);
unsigned long HTTPWrapperGetHostByName (char *name,unsigned long *address);
int HTTPWrapperShutDown (int s,int in);
// SSL Wrapper prototypes
#if TLS_CONFIG_HTTP_CLIENT_SECURE
int HTTPWrapperSSLConnect (tls_ssl_t **ssl_p,int s,const struct sockaddr *name,int namelen,char *hostname);
int HTTPWrapperSSLNegotiate (tls_http_session_handle_t pSession,int s,const struct sockaddr *name,int namelen,char *hostname);
int HTTPWrapperSSLSend (tls_ssl_t *ssl,int s,char *buf, int len,int flags);
int HTTPWrapperSSLRecv (tls_ssl_t *ssl,int s,char *buf, int len,int flags);
int HTTPWrapperSSLClose (tls_ssl_t *ssl, int s);
int HTTPWrapperSSLRecvPending (tls_ssl_t *ssl);
#endif
// Global wrapper Functions
#define IToA HTTPWrapperItoa
#define GetUpTime HTTPWrapperGetUpTime
#define SocketGetErr HTTPWrapperGetSocketError
#define HostByName HTTPWrapperGetHostByName
#define InitRandomeNumber HTTPWrapperInitRandomeNumber
#define GetRandomeNumber HTTPWrapperGetRandomeNumber
#ifdef __cplusplus
}
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Section : Global type definitions
// Last updated : 01/09/2005
//
///////////////////////////////////////////////////////////////////////////////
//#ifndef NULL
//#define NULL 0
//#endif
//#define TRUE 1
//#define FALSE 0
#ifdef u_long
#undef u_long
#endif
typedef unsigned long u_long;
// Global socket structures and definitions
#define HTTP_INVALID_SOCKET (-1)
typedef struct sockaddr_in HTTP_SOCKADDR_IN;
typedef struct timeval HTTP_TIMEVAL;
typedef struct hostent HTTP_HOSTNET;
typedef struct sockaddr HTTP_SOCKADDR;
typedef struct in_addr HTTP_INADDR;
#endif // HTTP_CLIENT_WRAPPER
+8
View File
@@ -0,0 +1,8 @@
#ifndef WM_HTTP_COMPILE_FILES
#define WM_HTTP_COMPILE_FILES
#include "HTTPClient.c"
#include "HTTPClientAuth.c"
#include "HTTPClientString.c"
#include "HTTPClientWrapper.c"
#include "wm_httpclient_task.c"
#endif
+307
View File
@@ -0,0 +1,307 @@
#include "wm_type_def.h"
#include "wm_http_client.h"
#include "HTTPClient.h"
#include "HTTPClientWrapper.h"
/***************************************************************************
* Function: HTTPClientOpenRequest
* Description: Allocate memory for a new HTTP Session.
*
* Input: Flags: HTTP Session internal API flags, 0 should be passed here.
*
* Output: None
*
* Return: HTTP Session handle
*
* Date : 2014-6-6
****************************************************************************/
tls_http_session_handle_t tls_http_client_open_request(tls_http_session_flags_t flags)
{
return HTTPClientOpenRequest(flags);
}
/***************************************************************************
* Function: HTTPClientCloseRequest
* Description: Closes any active connection and free any used memory.
*
* Input: pSession: HTTP Session handle.
*
* Output: None
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_close_request(tls_http_session_handle_t *session)
{
return HTTPClientCloseRequest(session);
}
#if TLS_CONFIG_HTTP_CLIENT_AUTH
/***************************************************************************
* Function: HTTPClientSetAuth
* Description: Sets the HTTP authentication schema.
*
* Input: pSession: HTTP Session handle.
* AuthSchema: HTTP Supported authentication methods.
* pReserved: Reserved parameter.
*
* Output: None
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_set_auth(tls_http_session_handle_t session,
tls_http_auth_achema_t auth_schema,
void *reserved)
{
return HTTPClientSetAuth(session, (HTTP_AUTH_SCHEMA)auth_schema, reserved);
}
/***************************************************************************
* Function: HTTPClientSetCredentials
* Description: Sets credentials for the target host.
*
* Input: pSession: HTTP Session handle.
* pUserName: User name.
* pPassword: Password.
*
* Output: None
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_set_credentials(tls_http_session_handle_t session,
char *user_name, char *password)
{
return HTTPClientSetCredentials(session, (CHAR *)user_name, (CHAR *)password);
}
#endif
#if TLS_CONFIG_HTTP_CLIENT_PROXY
/***************************************************************************
* Function: HTTPClientSetProxy
* Description: Sets all the proxy related parameters.
*
* Input: pSession: HTTP Session handle.
* pProxyName: The host name.
* nPort: The proxy port number.
* pUserName: User name for proxy authentication (can be null).
* pPassword: User password for proxy authentication (can be null).
*
* Output: None
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_set_proxy(tls_http_session_handle_t session, char *proxy_name,
u16 port, char *user_name, char *password)
{
return HTTPClientSetProxy(session, (CHAR *)proxy_name, port, (CHAR *)user_name, (CHAR *)password);
}
#endif
/***************************************************************************
* Function: HTTPClientSetVerb
* Description: Sets the HTTP verb for the outgoing request.
*
* Input: pSession: HTTP Session handle.
* HttpVerb: HTTP supported verbs
*
* Output: None
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_set_verb(tls_http_session_handle_t session, tls_http_verb_t http_verb)
{
return HTTPClientSetVerb(session, (HTTP_VERB)http_verb);
}
/***************************************************************************
* Function: HTTPClientAddRequestHeaders
* Description: Add headers to the outgoing request.
*
* Input: pSession: HTTP Session handle.
* pHeaderName: The Headers name
* pHeaderData: The headers data
* nInsert: Reserved could be any
*
* Output: None
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_add_request_headers(tls_http_session_handle_t session, char *header_name,
char *header_data, bool insert)
{
return HTTPClientAddRequestHeaders(session, (CHAR *)header_name, (CHAR *)header_data, (BOOL)insert);
}
/***************************************************************************
* Function: HTTPClientSendRequest
* Description: This function builds the request headers, performs a DNS resolution ,
* opens the connection (if it was not opened yet by a previous request or if it has closed)
* and sends the request headers.
*
* Input: pSession: HTTP Session handle.
* pUrl: The requested URL
* pData: Data to post to the server
* nDataLength: Length of posted data
* TotalLength: Valid only when http method is post.
* TRUE: Post data to http server.
* FALSE: In a post request without knowing the total length in advance so return error or use chunking.
* nTimeout: Operation timeout
* nClientPort: Client side port 0 for none
*
* Output: None
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_send_request(tls_http_session_handle_t session, char *url, void *data,
u32 data_len, bool total_len, u32 time_out, u32 client_port)
{
return HTTPClientSendRequest(session, (CHAR *)url, data, data_len, (BOOL)total_len, time_out, client_port);
}
/***************************************************************************
* Function: HTTPClientWriteData
* Description: Write data to the remote server.
*
* Input: pSession: HTTP Session handle.
* pBuffer: Data to write to the server.
* nBufferLength: Length of wtitten data.
* nTimeout: Timeout for the operation.
*
* Output: None
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_write_data(tls_http_session_handle_t session, void *buffer,
u32 buffer_len, u32 time_out)
{
return HTTPClientWriteData(session, buffer, buffer_len, time_out);
}
/***************************************************************************
* Function: HTTPClientRecvResponse
* Description: Receives the response header on the connection and parses it.
* Performs any required authentication.
*
* Input: pSession: HTTP Session handle.
* nTimeout: Timeout for the operation.
*
* Output: None
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_recv_response(tls_http_session_handle_t session, u32 time_out)
{
return HTTPClientRecvResponse(session, time_out);
}
/***************************************************************************
* Function: HTTPClientReadData
* Description: Read data from the server. Parse out the chunks data.
*
* Input: pSession: HTTP Session handle.
* nBytesToRead: The size of the buffer (numbers of bytes to read)
* nTimeout: Operation timeout in seconds
*
* Output: pBuffer: A pointer to a buffer that will be filled with the servers response
* nBytesRecived: Count of the bytes that were received in this operation
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_read_data(tls_http_session_handle_t session, void *buffer,
u32 bytes_to_read, u32 time_out, u32 *bytes_recived)
{
return HTTPClientReadData(session, buffer, bytes_to_read, time_out, bytes_recived);
}
/***************************************************************************
* Function: HTTPClientGetInfo
* Description: Fill the users structure with the session information.
*
* Input: pSession: HTTP Session handle.
*
* Output: HTTPClient: The session information.
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_get_info(tls_http_session_handle_t session, tls_http_client_t *http_client)
{
return HTTPClientGetInfo(session, http_client);
}
/***************************************************************************
* Function: HTTPClientFindFirstHeader
* Description: Initiate the headr searching functions and find the first header.
*
* Input: pSession: HTTP Session handle.
* pSearchClue: Search clue.
*
* Output: pHeaderBuffer: A pointer to a buffer that will be filled with the header name and value.
* nLength: Count of the bytes that were received in this operation.
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_find_first_header(tls_http_session_handle_t session, char *search_clue,
char *header_buffer, u32 *length)
{
return HTTPClientFindFirstHeader(session, (CHAR *)search_clue, (CHAR *)header_buffer, length);
}
/***************************************************************************
* Function: HTTPClientGetNextHeader
* Description: Find the next header.
*
* Input: pSession: HTTP Session handle.
*
* Output: pHeaderBuffer: A pointer to a buffer that will be filled with the header name and value.
* nLength: Count of the bytes that were received in this operation.
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_get_next_header(tls_http_session_handle_t session,
char *header_buffer, u32 *length)
{
return HTTPClientGetNextHeader(session, (CHAR *)header_buffer, length);
}
/***************************************************************************
* Function: HTTPClientFindCloseHeader
* Description: Terminate a headers search session.
*
* Input: pSession: HTTP Session handle.
*
* Output: None
*
* Return: HTTP Status
*
* Date : 2014-6-6
****************************************************************************/
int tls_http_client_find_close_header(tls_http_session_handle_t session)
{
return HTTPClientFindCloseHeader(session);
}
+235
View File
@@ -0,0 +1,235 @@
#include <string.h>
#include "wm_include.h"
#include "wm_config.h"
#include "wm_http_client.h"
#include "lwip/sys.h"
#include "wm_wl_task.h"
#if TLS_CONFIG_HTTP_CLIENT_TASK
#define HTTP_CLIENT_STK_SIZE 256
static sys_mbox_t http_client_mbox = SYS_MBOX_NULL;
static OS_STK httpClientStk[HTTP_CLIENT_STK_SIZE];
#define HTTP_CLIENT_BUFFER_SIZE 1024
extern u8 pSession_flag;
static UINT32 http_snd_req_local(
HTTP_SESSION_HANDLE pHTTP, HTTPParameters ClientParams, HTTP_VERB verb, CHAR* pSndData, u32 dataLen,
http_client_recv_callback_fn recv_fn)
{
INT32 nRetCode;
UINT32 nSize,nTotal = 0;
CHAR* Buffer = NULL;
UINT32 nSndDataLen ;
CHAR token[32];
UINT32 size=32;
char *pRecvData=NULL;
u32 totallen;
do
{
Buffer = (CHAR*)tls_mem_alloc(HTTP_CLIENT_BUFFER_SIZE);
if(Buffer == NULL)
{
return HTTP_CLIENT_ERROR_NO_MEMORY;
}
memset(Buffer, 0, HTTP_CLIENT_BUFFER_SIZE);
//printf("\nHTTP Client v1.0\n\n");
nSndDataLen = (pSndData==NULL ? 0 : dataLen);
// Set the Verb
nRetCode = HTTPClientSetVerb(pHTTP,verb);
if(nRetCode != HTTP_CLIENT_SUCCESS)
{
break;
}
#if TLS_CONFIG_HTTP_CLIENT_AUTH
// Set authentication
if(ClientParams.AuthType != AuthSchemaNone)
{
if((nRetCode = HTTPClientSetAuth(pHTTP,ClientParams.AuthType,NULL)) != HTTP_CLIENT_SUCCESS)
{
break;
}
// Set authentication
if((nRetCode = HTTPClientSetCredentials(pHTTP,ClientParams.UserName,ClientParams.Password)) != HTTP_CLIENT_SUCCESS)
{
break;
}
}
#endif //TLS_CONFIG_HTTP_CLIENT_AUTH
#if TLS_CONFIG_HTTP_CLIENT_PROXY
// Use Proxy server
if(ClientParams.UseProxy == TRUE)
{
if((nRetCode = HTTPClientSetProxy(pHTTP,ClientParams.ProxyHost,ClientParams.ProxyPort,NULL,NULL)) != HTTP_CLIENT_SUCCESS)
{
break;
}
}
#endif //TLS_CONFIG_HTTP_CLIENT_PROXY
if((nRetCode = HTTPClientSendRequest(pHTTP,ClientParams.Uri,pSndData,nSndDataLen,verb==VerbPost || verb==VerbPut,0,0)) != HTTP_CLIENT_SUCCESS)
{
break;
}
// Retrieve the the headers and analyze them
if((nRetCode = HTTPClientRecvResponse(pHTTP,30)) != HTTP_CLIENT_SUCCESS)
{
break;
}
memset(token, 0, 32);
if((nRetCode = HTTPClientFindFirstHeader(pHTTP, "content-length", token, &size)) != HTTP_CLIENT_SUCCESS)
{
totallen = HTTP_CLIENT_BUFFER_SIZE;
}
else
{
totallen = atol(strstr(token,":")+1);
}
HTTPClientFindCloseHeader(pHTTP);
//printf("Start to receive data from remote server...\n");
// Get the data until we get an error or end of stream code
pSession_flag = 0;
while(nRetCode == HTTP_CLIENT_SUCCESS || nRetCode != HTTP_CLIENT_EOS)
{
// Set the size of our buffer
nSize = HTTP_CLIENT_BUFFER_SIZE;
// Get the data
nRetCode = HTTPClientReadData(pHTTP,Buffer,nSize,300,&nSize);
if(nRetCode != HTTP_CLIENT_SUCCESS && nRetCode != HTTP_CLIENT_EOS)
break;
pRecvData = tls_mem_alloc(nSize);
if(pRecvData == NULL)
{
nRetCode = HTTP_CLIENT_ERROR_NO_MEMORY;
break;
}
memcpy(pRecvData, Buffer, nSize);
recv_fn(pHTTP, pRecvData, totallen, nSize);
}
} while(0); // Run only once
if(Buffer)
tls_mem_free(Buffer);
if(pHTTP)
HTTPClientCloseRequest(&pHTTP);
if(ClientParams.Verbose == TRUE)
{
printf("\n\nHTTP Client terminated %d (got %d kb)\n\n",nRetCode,(nTotal/ 1024));
}
return nRetCode;
}
static void http_client_rx(void *sdata)
{
int ret;
void *msg;
http_client_msg *http_msg;
for(;;)
{
sys_arch_mbox_fetch(&http_client_mbox, (void **)&msg, 0);
http_msg = (http_client_msg *)msg;
ret = http_snd_req_local(http_msg->pSession,
http_msg->param,
http_msg->method,
http_msg->sendData,
http_msg->dataLen,
http_msg->recv_fn);
//printf("http_client_rx ret=%d\n", ret);
if(ret == HTTP_CLIENT_SUCCESS || ret == HTTP_CLIENT_EOS)
{
;
}
else
{
if(http_msg->err_fn != NULL)
http_msg->err_fn(http_msg->pSession, ret);
}
if(http_msg->sendData != NULL)
tls_mem_free(http_msg->sendData);
if(http_msg->param.Uri)
tls_mem_free(http_msg->param.Uri);
tls_mem_free(http_msg);
}
}
int http_client_task_init(void)
{
if(sys_mbox_new(&http_client_mbox, 32) != ERR_OK) {
return WM_FAILED;
}
tls_os_task_create(NULL, "HTTPCLNT",
http_client_rx,
NULL,
(void *)httpClientStk, /* task's stack start address */
HTTP_CLIENT_STK_SIZE * sizeof(u32), /* task's stack size, unit:byte */
TLS_HTTP_CLIENT_TASK_PRIO,
0);
return WM_SUCCESS;
}
int http_client_post(http_client_msg * msg)
{
int len;
err_t err;
http_client_msg * msg1 = tls_mem_alloc(sizeof(http_client_msg));
if(!msg1)
return HTTP_CLIENT_ERROR_NO_MEMORY;
memset(msg1, 0, sizeof(http_client_msg));
memcpy(msg1, msg, sizeof(http_client_msg));
if(msg->dataLen > 0)
{
msg1->sendData = tls_mem_alloc(msg->dataLen);
if(msg1->sendData == NULL)
{
tls_mem_free(msg1);
return HTTP_CLIENT_ERROR_NO_MEMORY;
}
memcpy(msg1->sendData, msg->sendData, msg->dataLen);
}
else
msg1->sendData = NULL;
if(msg->param.Uri != NULL)
{
len = strlen(msg->param.Uri);
msg1->param.Uri = tls_mem_alloc(len + 1);
if(msg1->param.Uri == NULL)
{
if(msg1->sendData)
tls_mem_free(msg1->sendData);
tls_mem_free(msg1);
return HTTP_CLIENT_ERROR_NO_MEMORY;
}
memset(msg1->param.Uri, 0, len + 1);
memcpy(msg1->param.Uri,msg->param.Uri,len);
}
// Open the HTTP request handle
msg->pSession= HTTPClientOpenRequest(0);
if(!msg->pSession)
{
if(msg1->sendData)
tls_mem_free(msg1->sendData);
if(msg1->param.Uri)
tls_mem_free(msg1->param.Uri);
tls_mem_free(msg1);
return HTTP_CLIENT_ERROR_INVALID_HANDLE;
}
msg1->pSession = msg->pSession;
err = sys_mbox_trypost(&http_client_mbox, msg1);
//printf("post err=%d\n", err);
if(err != ERR_OK)
{
HTTPClientCloseRequest(&msg->pSession);
if(msg1->sendData)
tls_mem_free(msg1->sendData);
if(msg1->param.Uri)
tls_mem_free(msg1->param.Uri);
tls_mem_free(msg1);
}
return err;
}
#endif //TLS_CONFIG_HTTP_CLIENT_TASK