summaryrefslogtreecommitdiffstats
path: root/tinyHTTP/src/thttp_proxy_node_plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinyHTTP/src/thttp_proxy_node_plugin.c')
-rwxr-xr-xtinyHTTP/src/thttp_proxy_node_plugin.c161
1 files changed, 78 insertions, 83 deletions
diff --git a/tinyHTTP/src/thttp_proxy_node_plugin.c b/tinyHTTP/src/thttp_proxy_node_plugin.c
index 431016b..a5b5fa7 100755
--- a/tinyHTTP/src/thttp_proxy_node_plugin.c
+++ b/tinyHTTP/src/thttp_proxy_node_plugin.c
@@ -59,10 +59,9 @@
"Proxy-Connection: keep-Alive\r\n" \
"Pragma: no-cache\r\n"
-typedef struct thttp_proxy_node_plugin_s
-{
+typedef struct thttp_proxy_node_plugin_s {
TNET_DECLARE_PROXY_NONE;
-
+
struct {
tsk_bool_t completed;
tsk_bool_t started;
@@ -76,7 +75,7 @@ typedef struct thttp_proxy_node_plugin_s
struct thttp_proxy_auth_cache_s* proxy_auth_cache;
#endif
} handshacking;
-
+
TSK_DECLARE_SAFEOBJ;
}
thttp_proxy_node_plugin_t;
@@ -103,7 +102,7 @@ static int _thttp_proxy_node_plugin_configure(tnet_proxy_node_t* self, ...)
int ret = 0;
thttp_proxy_node_plugin_t* node = (thttp_proxy_node_plugin_t*)self;
// input parameters already checked by the caller
-
+
va_start(ap, self);
tsk_safeobj_lock(node);
ret = tnet_proxy_node_configure_2(self, &ap);
@@ -118,7 +117,7 @@ static int _thttp_proxy_node_plugin_start_handshaking(tnet_proxy_node_t* self)
int ret = 0;
#define kConnectContentData tsk_null
// input parameters already checked by the caller
-
+
if (tsk_strnullORempty(self->dst_host) || !self->dst_port) {
TSK_DEBUG_ERROR("Invalid destination address for HTTP proxy node: %s:%d", self->dst_host, self->dst_port);
return -1;
@@ -129,11 +128,11 @@ static int _thttp_proxy_node_plugin_start_handshaking(tnet_proxy_node_t* self)
TSK_DEBUG_ERROR("handshaking already started");
goto bail;
}
-
+
TSK_OBJECT_SAFE_FREE(node->handshacking.req_connect);
TSK_FREE(node->handshacking.pending_data_ptr);
node->handshacking.pending_data_len = 0;
-
+
/* Build the HTTP(S) CONNECT Request */
#if BUILD_USING_PARSE
{
@@ -155,7 +154,7 @@ static int _thttp_proxy_node_plugin_start_handshaking(tnet_proxy_node_t* self)
TSK_OBJECT_SAFE_FREE(auth_hdr);
}
tsk_strcat((char**)&node->handshacking.pending_data_ptr, ONE_CRLF);
-
+
node->handshacking.pending_data_len = (int)tsk_strlen(node->handshacking.pending_data_ptr);
tsk_ragel_state_init(&state, node->handshacking.pending_data_ptr, node->handshacking.pending_data_len);
if ((ret = thttp_message_parse(&state, &node->handshacking.req_connect, tsk_false/* do not extract the content */)) != 0) {
@@ -193,7 +192,7 @@ static int _thttp_proxy_node_plugin_start_handshaking(tnet_proxy_node_t* self)
THTTP_HEADER_DUMMY_VA_ARGS("Connection", "keep-Alive"),
THTTP_HEADER_DUMMY_VA_ARGS("Pragma", "no-cache"),
END_OF_ADD_HEADERS()
- );
+ );
# if THTTP_PROXY_AUTH_CACHE
tsk_sprintf(&uristring, "%s:%d", self->dst_host, self->dst_port);
auth_hdr = _thttp_proxy_auth_cache_create_header_authorization(node->handshacking.proxy_auth_cache, self->proxy_host, self->proxy_port, self->login, self->password, uristring);
@@ -210,19 +209,19 @@ static int _thttp_proxy_node_plugin_start_handshaking(tnet_proxy_node_t* self)
}
}
#endif
-
+
/* Parse the connect method */
if (!node->handshacking.pending_data_ptr) { // see "BUILD_USING_PARSE"
node->handshacking.pending_data_ptr = thttp_message_tostring(node->handshacking.req_connect);
node->handshacking.pending_data_len = (int)tsk_strlen((const char*)node->handshacking.pending_data_ptr);
}
-
+
if (!(node->handshacking.started = (node->handshacking.pending_data_len > 0))) {
TSK_DEBUG_ERROR("Failed to parse HTTP connect data");
ret = -3;
goto bail;
}
-
+
bail:
tsk_safeobj_unlock(node);
return ret;
@@ -235,19 +234,19 @@ static int _thttp_proxy_node_plugin_set_handshaking_data(tnet_proxy_node_t* self
thttp_message_t *message = tsk_null;
tsk_bool_t have_all_content = tsk_false;
thttp_proxy_node_plugin_t* node = (thttp_proxy_node_plugin_t*)self;
-
+
// input parameters already checked by the caller
-
+
TSK_DEBUG_INFO("HTTP(s) incoming proxy handshaking data:%.*s", (int)data_size, data_ptr);
-
+
tsk_safeobj_lock(node);
-
+
if (!node->handshacking.started) {
TSK_DEBUG_ERROR("handshaking not started");
ret = -3;
goto bail;
}
-
+
if (!node->handshacking.buff) {
if (!(node->handshacking.buff = tsk_buffer_create(data_ptr, data_size))) {
ret = -2;
@@ -259,27 +258,27 @@ static int _thttp_proxy_node_plugin_set_handshaking_data(tnet_proxy_node_t* self
goto bail;
}
}
-
+
/* Check if we have all HTTP headers. */
parse_buffer:
if ((endOfheaders = tsk_strindexOf(TSK_BUFFER_DATA(node->handshacking.buff), TSK_BUFFER_SIZE(node->handshacking.buff), TWO_CRLF)) < 0) {
TSK_DEBUG_INFO("No all HTTP headers in the TCP buffer.");
goto bail;
}
-
+
/* If we are here this mean that we have all HTTP headers.
* ==> Parse the HTTP message without the content.
*/
tsk_ragel_state_init(&state, TSK_BUFFER_DATA(node->handshacking.buff), endOfheaders + TWO_CRLF_LEN);
if ((ret = thttp_message_parse(&state, &message, tsk_false/* do not extract the content */)) == 0) {
const thttp_header_Transfer_Encoding_t* transfer_Encoding;
-
+
/* chunked? */
if ((transfer_Encoding = (const thttp_header_Transfer_Encoding_t*)thttp_message_get_header(message, thttp_htype_Transfer_Encoding)) && tsk_striequals(transfer_Encoding->encoding, "chunked")) {
const char* start = (const char*)(TSK_BUFFER_TO_U8(node->handshacking.buff) + (endOfheaders + TWO_CRLF_LEN));
const char* end = (const char*)(TSK_BUFFER_TO_U8(node->handshacking.buff) + TSK_BUFFER_SIZE(node->handshacking.buff));
int index;
-
+
TSK_DEBUG_INFO("CHUNKED transfer.");
while (start < end) {
/* RFC 2616 - 19.4.6 Introduction of Transfer-Encoding */
@@ -292,14 +291,14 @@ parse_buffer:
TSK_DEBUG_ERROR("Parsing chunked data has failed.");
break;
}
-
+
if (chunk_size == 0 && ((start + 2) <= end) && *start == '\r' && *(start+ 1) == '\n') {
int parsed_len = (int)(start - (const char*)(TSK_BUFFER_TO_U8(node->handshacking.buff))) + TWO_CRLF_LEN;
tsk_buffer_remove(node->handshacking.buff, 0, parsed_len);
have_all_content = tsk_true;
break;
}
-
+
thttp_message_append_content(message, start, chunk_size);
start += chunk_size + ONE_CRLF_LEN;
}
@@ -325,7 +324,7 @@ parse_buffer:
}
}
}
-
+
/* Alert the dialog (FSM) */
if (message) {
if (have_all_content) { /* only if we have all data */
@@ -373,11 +372,11 @@ parse_buffer:
tsk_object_unref(auth_hdr), auth_hdr = tsk_null;
}
TSK_FREE(uristring);
-
+
#if BUILD_USING_PARSE
tsk_strcat((char**)&node->handshacking.pending_data_ptr, ONE_CRLF);
#endif /* BUILD_USING_PARSE */
-
+
// update pending handshaking data
if (!node->handshacking.pending_data_ptr && !(node->handshacking.pending_data_ptr = thttp_message_tostring(node->handshacking.req_connect))) {
TSK_DEBUG_ERROR("Breaking HTTP(s) handshaking process (failed to parse request)");
@@ -400,7 +399,7 @@ parse_buffer:
ret = -4;
goto bail;
}
-
+
/* Parse next chunck */
if (TSK_BUFFER_SIZE(node->handshacking.buff) > 0) {
TSK_OBJECT_SAFE_FREE(message);
@@ -408,7 +407,7 @@ parse_buffer:
}
}
}
-
+
bail:
tsk_safeobj_unlock(node);
TSK_OBJECT_SAFE_FREE(message);
@@ -419,10 +418,10 @@ static int _thttp_proxy_node_plugin_get_handshaking_pending_data(tnet_proxy_node
{
thttp_proxy_node_plugin_t* node = (thttp_proxy_node_plugin_t*)self;
int ret = -1;
-
+
// input parameters already checked by the caller
tsk_safeobj_lock(node);
-
+
if (node->handshacking.pending_data_ptr && node->handshacking.pending_data_len > 0) {
if ((*data_pptr = tsk_realloc(*data_pptr, node->handshacking.pending_data_len))) {
memcpy(*data_pptr, node->handshacking.pending_data_ptr, (tsk_size_t) node->handshacking.pending_data_len);
@@ -433,7 +432,7 @@ static int _thttp_proxy_node_plugin_get_handshaking_pending_data(tnet_proxy_node
TSK_FREE(node->handshacking.pending_data_ptr);
node->handshacking.pending_data_len = 0;
}
-
+
tsk_safeobj_unlock(node);
return ret;
}
@@ -441,11 +440,11 @@ static int _thttp_proxy_node_plugin_get_handshaking_pending_data(tnet_proxy_node
static int _thttp_proxy_node_plugin_get_handshaking_completed(tnet_proxy_node_t* self, tsk_bool_t* completed)
{
thttp_proxy_node_plugin_t* node = (thttp_proxy_node_plugin_t*)self;
-
+
tsk_safeobj_lock(node);
*completed = node->handshacking.completed;
tsk_safeobj_unlock(node);
-
+
return 0;
}
@@ -457,25 +456,25 @@ static int _thttp_proxy_node_plugin_update_challenge(thttp_proxy_node_plugin_t *
#endif
int ret = 0;
const thttp_header_Proxy_Authenticate_t *Proxy_Authenticate;
-
+
if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
#define kIsProxyYes tsk_true
-
+
tsk_safeobj_lock(self);
#if THTTP_PROXY_AUTH_CACHE
_thttp_proxy_auth_cache_lock(self->handshacking.proxy_auth_cache);
#endif
-
+
/* RFC 2617 - Digest Operation
-
+
* (A) The client response to a WWW-Authenticate challenge for a protection
space starts an authentication session with that protection space.
The authentication session lasts until the client receives another
WWW-Authenticate challenge from any server in the protection space.
-
+
(B) The server may return a 401 response with a new nonce value, causing the client
to retry the request; by specifying stale=TRUE with this response,
the server tells the client to retry with the new nonce, but without
@@ -491,14 +490,14 @@ static int _thttp_proxy_node_plugin_update_challenge(thttp_proxy_node_plugin_t *
#if THTTP_PROXY_AUTH_CACHE
TSK_OBJECT_SAFE_FREE(self->handshacking.challenge);
self->handshacking.challenge = _thttp_proxy_auth_cache_challenge_get(self->handshacking.proxy_auth_cache,
- base->proxy_host,
- base->proxy_port,
- Proxy_Authenticate->scheme,
- Proxy_Authenticate->realm,
- Proxy_Authenticate->nonce,
- Proxy_Authenticate->opaque,
- Proxy_Authenticate->algorithm,
- Proxy_Authenticate->qop);
+ base->proxy_host,
+ base->proxy_port,
+ Proxy_Authenticate->scheme,
+ Proxy_Authenticate->realm,
+ Proxy_Authenticate->nonce,
+ Proxy_Authenticate->opaque,
+ Proxy_Authenticate->algorithm,
+ Proxy_Authenticate->qop);
#else
ret = thttp_challenge_update(self->handshacking.challenge,
Proxy_Authenticate->scheme,
@@ -521,22 +520,22 @@ static int _thttp_proxy_node_plugin_update_challenge(thttp_proxy_node_plugin_t *
else {
#if THTTP_PROXY_AUTH_CACHE
self->handshacking.challenge = _thttp_proxy_auth_cache_challenge_get(self->handshacking.proxy_auth_cache,
- base->proxy_host,
- base->proxy_port,
- Proxy_Authenticate->scheme,
- Proxy_Authenticate->realm,
- Proxy_Authenticate->nonce,
- Proxy_Authenticate->opaque,
- Proxy_Authenticate->algorithm,
- Proxy_Authenticate->qop);
+ base->proxy_host,
+ base->proxy_port,
+ Proxy_Authenticate->scheme,
+ Proxy_Authenticate->realm,
+ Proxy_Authenticate->nonce,
+ Proxy_Authenticate->opaque,
+ Proxy_Authenticate->algorithm,
+ Proxy_Authenticate->qop);
#else
self->handshacking.challenge = thttp_challenge_create(kIsProxyYes,
- Proxy_Authenticate->scheme,
- Proxy_Authenticate->realm,
- Proxy_Authenticate->nonce,
- Proxy_Authenticate->opaque,
- Proxy_Authenticate->algorithm,
- Proxy_Authenticate->qop);
+ Proxy_Authenticate->scheme,
+ Proxy_Authenticate->realm,
+ Proxy_Authenticate->nonce,
+ Proxy_Authenticate->opaque,
+ Proxy_Authenticate->algorithm,
+ Proxy_Authenticate->qop);
#endif /* THTTP_PROXY_AUTH_CACHE */
if (!self->handshacking.challenge) {
ret = -1;
@@ -549,14 +548,14 @@ static int _thttp_proxy_node_plugin_update_challenge(thttp_proxy_node_plugin_t *
ret = -1;
goto bail;
}
-
+
bail:
#if THTTP_PROXY_AUTH_CACHE
_thttp_proxy_auth_cache_unlock(self->handshacking.proxy_auth_cache);
#endif
tsk_safeobj_unlock(self);
return ret;
-
+
}
@@ -591,31 +590,29 @@ static tsk_object_t* thttp_proxy_node_plugin_dtor(tsk_object_t * self)
#if THTTP_PROXY_AUTH_CACHE
TSK_OBJECT_SAFE_FREE(node->handshacking.proxy_auth_cache);
#endif
-
+
tsk_safeobj_deinit(node);
-
+
TSK_DEBUG_INFO("*** HTTP proxy node destroyed ***");
}
return self;
}
/* object definition */
-static const tsk_object_def_t thttp_proxy_node_def_s =
-{
+static const tsk_object_def_t thttp_proxy_node_def_s = {
sizeof(thttp_proxy_node_plugin_t),
thttp_proxy_node_plugin_ctor,
thttp_proxy_node_plugin_dtor,
tsk_null,
};
/* plugin definition*/
-static const struct tnet_proxy_node_plugin_def_s thttp_proxy_node_plugin_def_s =
-{
+static const struct tnet_proxy_node_plugin_def_s thttp_proxy_node_plugin_def_s = {
&thttp_proxy_node_def_s,
-
+
tnet_proxy_type_http | tnet_proxy_type_https,
-
+
"HTTP(s) proxy node plugin",
-
+
_thttp_proxy_node_plugin_configure,
_thttp_proxy_node_plugin_start_handshaking,
_thttp_proxy_node_plugin_set_handshaking_data,
@@ -633,7 +630,7 @@ extern const tsk_object_def_t* thttp_proxy_auth_def_t;
typedef struct thttp_proxy_auth_s {
TSK_DECLARE_OBJECT;
-
+
char* hostname;
tnet_port_t port;
struct {
@@ -653,7 +650,7 @@ typedef tsk_list_t thttp_proxy_auths_L_t;
typedef struct thttp_proxy_auth_cache_s {
TSK_DECLARE_OBJECT;
-
+
thttp_proxy_auths_L_t* auths_list;
TSK_DECLARE_SAFEOBJ;
}
@@ -710,7 +707,7 @@ static thttp_challenge_t* _thttp_proxy_auth_cache_challenge_get(thttp_proxy_auth
((thttp_proxy_auth_t*)proxy_auth)->challenge.nc = 1;
tsk_strrandom(&istr);
tsk_md5compute(istr, tsk_strlen(istr), &((thttp_proxy_auth_t*)proxy_auth)->challenge.cnonce);
-
+
((thttp_proxy_auth_t*)proxy_auth)->challenge.is_active = tsk_true;
}
}
@@ -736,7 +733,7 @@ static thttp_header_t * _thttp_proxy_auth_cache_create_header_authorization(stru
{
thttp_challenge_t* challenge = tsk_null;
thttp_header_t * header = tsk_null;
-
+
if (!self || !uristring) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
@@ -825,11 +822,10 @@ static tsk_object_t* _thttp_proxy_auth_cache_dtor(tsk_object_t * self)
TSK_OBJECT_SAFE_FREE(cache->auths_list);
tsk_safeobj_deinit(cache);
}
-
+
return self;
}
-static const tsk_object_def_t thttp_proxy_auth_cache_def_s =
-{
+static const tsk_object_def_t thttp_proxy_auth_cache_def_s = {
sizeof(thttp_proxy_auth_cache_t),
_thttp_proxy_auth_cache_ctor,
_thttp_proxy_auth_cache_dtor,
@@ -845,7 +841,7 @@ static tsk_object_t* _thttp_proxy_auth_ctor(tsk_object_t * self, va_list * app)
{
thttp_proxy_auth_t *auth = (thttp_proxy_auth_t *)self;
if (auth) {
-
+
}
return self;
}
@@ -861,11 +857,10 @@ static tsk_object_t* _thttp_proxy_auth_dtor(tsk_object_t * self)
TSK_FREE(auth->challenge.qop);
TSK_FREE(auth->hostname);
}
-
+
return self;
}
-static const tsk_object_def_t thttp_proxy_auth_def_s =
-{
+static const tsk_object_def_t thttp_proxy_auth_def_s = {
sizeof(thttp_proxy_auth_t),
_thttp_proxy_auth_ctor,
_thttp_proxy_auth_dtor,
OpenPOWER on IntegriCloud