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:
@@ -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
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user