Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save fbzhong/1027470 to your computer and use it in GitHub Desktop.
Save fbzhong/1027470 to your computer and use it in GitHub Desktop.
add CONNECT bypass NextProxy support for Ziproxy 3.2.0
From 185ff4a2980137182a8bd2cbaf72973769cbd54d Mon Sep 17 00:00:00 2001
From: robin <[email protected]>
Date: Thu, 16 Jun 2011 00:10:24 +0800
Subject: [PATCH] add CONNECT bypass NextProxy support.
---
src/http.c | 192 +++++++++++++++++++++++++++++++--------------------------
src/http.h | 7 +-
src/ziproxy.c | 35 ++++++-----
3 files changed, 127 insertions(+), 107 deletions(-)
diff --git a/src/http.c b/src/http.c
index 52a4daa..1dcedcb 100644
--- a/src/http.c
+++ b/src/http.c
@@ -85,7 +85,7 @@ static char line[MAX_LINELEN];
//Local forwards.
-static int check_trim( char* line );
+static int check_trim( char* line );
ZP_DATASIZE_TYPE forward_content (http_headers *hdr, FILE *from, FILE *to);
ZP_DATASIZE_TYPE read_content (http_headers *hdr, FILE *from, FILE *to, char ** inbuf, ZP_DATASIZE_TYPE *inlen);
static void clean_hdr(char* ln);
@@ -143,12 +143,12 @@ void proxy_http (http_headers *client_hdr, FILE* sockrfp, FILE* sockwfp)
snprintf (new_user_agent, HEADER_REPLACEMENT_ENTRY_LEN, "User-Agent: %s\n", RedefineUserAgent);
replace_header_str(client_hdr, "User-Agent", new_user_agent);
}
-
+
add_header(client_hdr, "Connection: close");
// Send request
debug_log_puts ("Headers sent to server:");
-
+
send_headers_to(sockwfp, client_hdr);
// If there's content, forward that too
@@ -189,7 +189,7 @@ void proxy_http (http_headers *client_hdr, FILE* sockrfp, FILE* sockwfp)
serv_hdr->type, (serv_hdr->where_chunked > 0));
debug_log_printf ("WillGZip = %d, Compress = %d, DoPreDecompress = %d\n",
- (client_hdr->flags & H_WILLGZIP) != 0,
+ (client_hdr->flags & H_WILLGZIP) != 0,
(serv_hdr->flags & DO_COMPRESS) != 0,
(serv_hdr->flags & DO_PRE_DECOMPRESS) != 0);
@@ -223,7 +223,7 @@ void proxy_http (http_headers *client_hdr, FILE* sockrfp, FILE* sockwfp)
if ( ((serv_hdr->content_encoding_flags & ~PROP_ENCODED_GZIP) != PROP_ENCODED_NONE) ||
( (serv_hdr->content_encoding_flags == PROP_ENCODED_GZIP) && (! (serv_hdr->flags & DO_PRE_DECOMPRESS)) ) ) {
- debug_log_puts ("Data is encoded and cannot be decoded");
+ debug_log_puts ("Data is encoded and cannot be decoded");
is_sending_data = 1;
debug_log_puts ("Forwarding header and streaming data.");
add_header (serv_hdr, "Connection: close");
@@ -276,13 +276,13 @@ void proxy_http (http_headers *client_hdr, FILE* sockrfp, FILE* sockwfp)
) \
) {
int ret;
-
+
ret = do_decompress_stream_stream (serv_hdr, sockrfp, sess_wclient, &inlen, &outlen, MaxUncompressedGzipRatio, MinUncompressedGzipStreamEval);
if (ret != 0) {
// TODO: add flags of 'error' to access log in this case
debug_log_printf ("Error while gunzip-streaming: %d\n", ret);
}
-
+
access_log_def_inlen(inlen);
access_log_def_outlen(outlen);
access_log_dump_entry ();
@@ -315,7 +315,7 @@ void proxy_http (http_headers *client_hdr, FILE* sockrfp, FILE* sockwfp)
access_log_dump_entry ();
return;
}
-
+
debug_log_puts ("Trying to load the whole data into memory");
// this will read both streaming data and data with specified content-length
if ((streamed_len = read_content(serv_hdr,sockrfp, sess_wclient, &inbuf, &inlen)) != 0) {
@@ -347,7 +347,7 @@ void proxy_http (http_headers *client_hdr, FILE* sockrfp, FILE* sockwfp)
access_log_dump_entry ();
return;
}
-
+
//serv_hdr->chunklen isn't used anywhere else
/* TODO: i'm not sure what this block of code does (legacy code).
verify this later */
@@ -436,7 +436,7 @@ void proxy_http (http_headers *client_hdr, FILE* sockrfp, FILE* sockwfp)
// (start) only if data is not encoded
// data may (still) be encoded in case gzip decompressing failed
if ((serv_hdr->content_encoding_flags == PROP_ENCODED_NONE) && (inlen > 0)) {
-
+
/* text/html optimizer */
/* FIXME: inbuf must be at least (inlen + 1) chars big in order to hold added '\0' from htmlopt */
if (serv_hdr->flags & DO_OPTIMIZE_HTML) {
@@ -486,7 +486,7 @@ void proxy_http (http_headers *client_hdr, FILE* sockrfp, FILE* sockwfp)
inlen = hopt_pack_javascript (inbuf, inlen, inbuf);
outlen = inlen;
}
-
+
/* preemptive name resolution */
if (serv_hdr->flags & DO_PREEMPT_DNS)
preempt_dns_from_html (inbuf, inlen);
@@ -509,11 +509,11 @@ void proxy_http (http_headers *client_hdr, FILE* sockrfp, FILE* sockwfp)
access_log_dump_entry ();
exit (0);
}
-
+
} /* (end) only if data is not encoded */
is_sending_data = 1;
-
+
debug_log_puts ("Forwarding header and modified content.");
debug_log_puts ("Out Headers:");
@@ -533,13 +533,13 @@ void proxy_http (http_headers *client_hdr, FILE* sockrfp, FILE* sockwfp)
tosmarking_add_check_bytecount (outlen); /* update TOS if necessary */
if (inlen != 0){
int outcount = outlen;
-
+
do{
i = fwrite(tempp, 1, outcount, sess_wclient);
outcount -= i;
tempp += i;
}while((i > 0) && outcount);
-
+
fflush (sess_wclient);
if(outcount == 0) {
@@ -612,16 +612,16 @@ void blind_tunnel (http_headers *hdr, FILE* sockrfp, FILE* sockwfp)
int maxp1, r;
char buf [10000];
ZP_DATASIZE_TYPE total_transferred = 0;
-
+
/* Now forward (SSL packets) || (other data) in both directions until done. */
client_read_fd = fileno (sess_rclient);
server_read_fd = fileno (sockrfp);
client_write_fd = fileno (sess_wclient);
server_write_fd = fileno (sockwfp);
-
+
if (ConnTimeout)
timeout = malloc (sizeof (struct timeval));
-
+
if ( client_read_fd >= server_read_fd )
maxp1 = client_read_fd + 1;
else
@@ -659,7 +659,7 @@ void blind_tunnel (http_headers *hdr, FILE* sockrfp, FILE* sockwfp)
if (r <= 0)
break;
}
-
+
// update access log stats
access_log_def_inlen(total_transferred);
access_log_def_outlen(total_transferred);
@@ -681,7 +681,7 @@ void send_error( int status, char* title, char* extra_header, char* text )
time_t local_time;
struct tm local_time_tm;
char local_time_str [32];
-
+
switch (status){
case 400:
txtfilename = CustomError400;
@@ -716,20 +716,20 @@ void send_error( int status, char* title, char* extra_header, char* text )
if ((txtfile = fopen (txtfilename, "r")) != NULL){
fseek (txtfile, 0, SEEK_END);
txtfilesize = ftell (txtfile);
- fseek (txtfile, 0, SEEK_SET);
+ fseek (txtfile, 0, SEEK_SET);
if ((txtfilebuf = malloc (txtfilesize + 1)) != NULL){
fread (txtfilebuf, 1, txtfilesize, txtfile);
- *(txtfilebuf+txtfilesize) = '\0';
+ *(txtfilebuf+txtfilesize) = '\0';
send_headers( status, title, extra_header, "text/html", -1, -1 );
printf ("%s", txtfilebuf); /* we don't want problems with '%' characters */
fflush (sess_wclient);
- custom_error_sent = 1;
+ custom_error_sent = 1;
free (txtfilebuf);
}
fclose (txtfile);
}
}
-
+
if (custom_error_sent == 0){
local_hostname [0] = '\0';
gethostname (local_hostname, LOCAL_HOSTNAME_LEN - 1);
@@ -784,9 +784,9 @@ http_headers *new_headers(void){
h->content_encoding_flags = PROP_ENCODED_NONE;
h->client_explicity_accepts_jp2 = 0;
- h->where_content_type = h->where_content_length =
- h->where_chunked = h->where_content_encoding =
- h->where_etag = h->status =
+ h->where_content_type = h->where_content_length =
+ h->where_chunked = h->where_content_encoding =
+ h->where_etag = h->status =
h->chunklen = -1;
h->content_length = -1;
@@ -794,7 +794,7 @@ http_headers *new_headers(void){
h->port = -1;
h->user_agent = h->content_encoding = h->method = h->url = h->path = h->host = h->proto = NULL;
-
+
return h;
}
@@ -822,12 +822,12 @@ int add_header(http_headers *hdr, const char *newhdr){
}
else {
char *keyword;
-
+
if(hdr->status == -1)
keyword = "Bad request";
- else
+ else
keyword = "Bad response";
-
+
send_error( 400, keyword , NULL, "Too many headers.");
}
return hdr->lines - 1;
@@ -872,7 +872,7 @@ http_headers * parse_initial_request(void){
/* Read the first line of the request. */
if (fgets (line, sizeof(line), sess_rclient) == NULL)
{
- send_error( 400, "Bad Request", NULL,
+ send_error( 400, "Bad Request", NULL,
"No request found or request too long." );
}
linelen = check_trim(line);
@@ -901,7 +901,7 @@ http_headers * parse_initial_request(void){
{
strncpy( hdr->url, "http", 4 ); /* make sure it's lower case */
- if ( sscanf( hdr->url, "http://%[^:/]:%hu%s", hdr->host, &hdr->port, hdr->path ) == 3 );
+ if ( sscanf( hdr->url, "http://%[^:/]:%hu%s", hdr->host, &hdr->port, hdr->path ) == 3 );
else if ( sscanf( hdr->url, "http://%[^/]%s", hdr->host, hdr->path ) == 2 )
{
hdr->port = 80;
@@ -983,18 +983,18 @@ http_headers * parse_initial_request(void){
}
else
send_error( 400, "Bad Request", NULL, "Unknown URL type." );
-
+
return hdr;
}
-//If it returns line length > 0, line was correctly ended with newline - use to
+//If it returns line length > 0, line was correctly ended with newline - use to
//check output
-//from fgets().
+//from fgets().
static int check_trim( char* line ) {
int k,l;
k = l = strlen( line );
-
+
while (l > 0 && (line[l-1] == '\n' || line[l-1] == '\r'))
line[--l] = '\0';
@@ -1008,13 +1008,13 @@ void get_client_headers(http_headers * hdr){
int was_auth=0;
debug_log_puts ("Headers from client:");
-
-
+
+
while (fgets(line, sizeof(line), sess_rclient) != NULL)
{
if (strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0)
break;
-
+
if((linelen=check_trim(line))==0)
send_error( 400, "Bad request", NULL, "Line too long.");
@@ -1050,11 +1050,11 @@ void get_client_headers(http_headers * hdr){
if (strncasecmp (line, "X-Ziproxy-Flags:", 16) == 0) {
char *provided_ziproxy_flags;
-
+
provided_ziproxy_flags = line + 16;
if (*provided_ziproxy_flags == ' ')
provided_ziproxy_flags++;
-
+
hdr->x_ziproxy_flags = strdup (provided_ziproxy_flags);
if (strstr (hdr->x_ziproxy_flags, "jp2") != NULL)
@@ -1064,26 +1064,26 @@ void get_client_headers(http_headers * hdr){
continue; // there's no point in forwarding this header
}
-
+
if (strncasecmp(line,"Keep-Alive:",11) == 0)
continue;
-
+
/* REMOVEME: we do accept ranges now
* compression/optimization is limited in such cases though. */
//hmmm, this should not happen. But we should forward this unchanged
//instead!
- //if (strncasecmp(line, "Range:", 6) == 0) continue;
+ //if (strncasecmp(line, "Range:", 6) == 0) continue;
// define host data if empty
if (strncasecmp(line,"Host:", 5) == 0) {
if (*(hdr->host) == '\0') {
char *provided_host_str;
char *colonpos;
-
+
provided_host_str = line + 5;
if (*provided_host_str == ' ')
provided_host_str++;
-
+
hdr->host = strdup (provided_host_str);
// if host contains a defined port, processess that too
@@ -1115,22 +1115,22 @@ void get_client_headers(http_headers * hdr){
if(strncasecmp(line,"Via:",4) == 0){
if (ServHost != NULL) {
- if((strstr(line,ServHost) != NULL) && (strstr(line, SERVER_NAME) != NULL))
+ if((strstr(line,ServHost) != NULL) && (strstr(line, SERVER_NAME) != NULL))
/*prevent infinite recursion*/
send_error( 503, "Service Unavailable", NULL,
"Connection refused (based on Via header)." );
-
- if(linelen + strlen(ServHost) +
+
+ if(linelen + strlen(ServHost) +
sizeof(SERVER_NAME) + 15 >= MAX_LINELEN) continue;
-
- snprintf(line + linelen , sizeof(line) - linelen,
+
+ snprintf(line + linelen , sizeof(line) - linelen,
", 1.1 %s (%s)",ServHost ,SERVER_NAME);
was_via = 1;
-
+
}else continue; //forget Via header
}
add_header(hdr, line);
-
+
}
if ((ServHost != NULL) && !was_via)
@@ -1148,18 +1148,18 @@ void get_client_headers(http_headers * hdr){
/*Does not release the headers ! Rather use special function?*/
void send_headers_to(FILE * sockfp, http_headers *hdr){
int i, len;
-
+
if (0 == hdr->lines) return; //useful for simple response
-
+
if (hdr->status == -1){//treat first line specially
i = 1;
len = snprintf(line,sizeof(line),"%s %s %s\r\n", hdr->method, hdr->path, hdr->proto);
fputs(line, sockfp);
-
+
line[len-2] = '\0';
debug_log_puts_hdr (line);
}else i = 0;
-
+
// Forward the remainder of the request from the client
for(;i < hdr->lines && i<MAX_HEADERS;i++)
{
@@ -1171,6 +1171,22 @@ void send_headers_to(FILE * sockfp, http_headers *hdr){
fflush(sockfp);
}
+/* forward ssl request header to NextProxy */
+void forward_ssl_headers_to(FILE * sockfp, http_headers *hdr)
+{
+ int i;
+
+ // Forward the remainder of the request from the client
+ for(i=0; i < hdr->lines && i<MAX_HEADERS;i++)
+ {
+ fputs(hdr->hdr[i],sockfp);
+ debug_log_puts_hdr (hdr->hdr[i]);
+ fputs("\r\n",sockfp);
+ }
+ fputs("\r\n",sockfp);
+ fflush (sockfp);
+}
+
// TODO: we should standardize such defines in only one, global, one.
// This may not be > 2GB
#define STRM_BUFSIZE 16384
@@ -1191,7 +1207,7 @@ ZP_DATASIZE_TYPE forward_content (http_headers *hdr, FILE *from, FILE *to)
requestlen = remainlen;
remainlen -= requestlen;
}
-
+
inlen = fread (stream, 1, requestlen, from);
tosmarking_add_check_bytecount (inlen);
access_log_add_inlen(inlen);
@@ -1203,7 +1219,7 @@ ZP_DATASIZE_TYPE forward_content (http_headers *hdr, FILE *from, FILE *to)
alarmcount = 0;
alarm (ConnTimeout);
}
-
+
if (inlen > 0) {
outlen = fwrite (stream, 1, inlen, to);
access_log_add_outlen(outlen);
@@ -1218,7 +1234,7 @@ ZP_DATASIZE_TYPE forward_content (http_headers *hdr, FILE *from, FILE *to)
}
fflush (to);
-
+
return (access_log_ret_outlen());
}
@@ -1238,7 +1254,7 @@ ZP_DATASIZE_TYPE read_content (http_headers *hdr, FILE *from, FILE *to, char **
int de_chunk = 0;
int stream_instead = 0; // != 0 if streaming data exceeded MaxSize
int streamed_len = 0;
-
+
/* see if we can allocate a buffer the exact size we need */
if (hdr->content_length == -1)
buf_alloc = BUF_ALLOCATION_GRANULARITY;
@@ -1255,11 +1271,11 @@ ZP_DATASIZE_TYPE read_content (http_headers *hdr, FILE *from, FILE *to, char **
hdr->where_chunked = -1;
de_chunk = 1;
debug_log_puts ("Chunked data. De-chunking while loading into memory.");
- }
-
+ }
+
while ((feof (from) == 0) && (ferror (from) == 0) && (feof (to) == 0) && (ferror (to) == 0)) {
to_read_len = (buf_alloc - buf_used);
-
+
if (de_chunk) {
if (pending_chunk_len == 0) {
// discards chunk end CRLF
@@ -1269,7 +1285,7 @@ ZP_DATASIZE_TYPE read_content (http_headers *hdr, FILE *from, FILE *to, char **
} else {
first_chunk = 0;
}
-
+
fscanf (from, "%x", &pending_chunk_len);
if (pending_chunk_len != 0) {
char prevchar = '\0';
@@ -1307,7 +1323,7 @@ ZP_DATASIZE_TYPE read_content (http_headers *hdr, FILE *from, FILE *to, char **
access_log_def_inlen(streamed_len);
access_log_def_outlen(streamed_len);
-
+
buf_used = 0; // avoids indefinite growth of buffer size (see below)
}
@@ -1337,7 +1353,7 @@ ZP_DATASIZE_TYPE read_content (http_headers *hdr, FILE *from, FILE *to, char **
}
buf_alloc = STRM_BUFSIZE;
}
-
+
// perhaps we've already spent too much time downloading that file,
// let's reset the timeout alarm
if (ConnTimeout)
@@ -1354,7 +1370,7 @@ ZP_DATASIZE_TYPE read_content (http_headers *hdr, FILE *from, FILE *to, char **
fflush (to);
return (streamed_len);
}
-
+
/* avoids possible bugs in htmlopt, make sure the data has a trailing '\0' */
if (buf_alloc == buf_used) {
if ((buf = realloc (buf, buf_alloc + 1)) == NULL) {
@@ -1364,12 +1380,12 @@ ZP_DATASIZE_TYPE read_content (http_headers *hdr, FILE *from, FILE *to, char **
buf_alloc += 1;
}
*(buf + buf_used) = '\0'; // doesn't count as part of the file
-
+
if (hdr->content_length == -1)
*inlen = buf_used;
else
*inlen = hdr->content_length;
-
+
*inbuf = buf;
*inlen = buf_used;
@@ -1421,7 +1437,7 @@ http_headers * get_response_headers(FILE *sockrfp){
if ((linelen = check_trim(line)) == 0)
send_error(500,"Internal Error",NULL,
"Too long line in response from server");
-
+
debug_log_puts_hdr (line);
clean_hdr(line);
savepos = NULL;
@@ -1446,14 +1462,14 @@ http_headers * get_response_headers(FILE *sockrfp){
else if (strncasecmp(line, "Content-Type:", 13) == 0)
savepos = &hdr->where_content_type;
-
+
/* REMOVEME: we do accept ranges now
* compression/optimization is limited in such cases though. */
//else if (strncasecmp(line, "Accept-Ranges:", 14) == 0)
// strcpy(&line[14], " none");
else if (strncasecmp(line, "Content-range:", 14) == 0)
hdr->has_content_range = 1;
-
+
else if (strncasecmp(line, "ETag:", 5) == 0)
savepos = &hdr->where_etag;
@@ -1470,18 +1486,18 @@ http_headers * get_response_headers(FILE *sockrfp){
tempp = line + 17;
else if(!strncasecmp(line,"Keep-Alive:",11))
tempp = line;
-
+
if((tempp != NULL) && (strstr(tempp, "Keep-Alive") != NULL))
hdr->flags |= H_KEEPALIVE;
}
//store header entry, except certain ones
- if(strncasecmp(line, "Connection:", 11) &&
+ if(strncasecmp(line, "Connection:", 11) &&
strncasecmp(line, "Proxy-Connection:", 17) &&
strncasecmp(line,"Keep-Alive:",11)){
n = add_header(hdr,line);
if (savepos != NULL) *savepos = n;
- if (0 == n) hdr->proto = hdr->hdr[0];
+ if (0 == n) hdr->proto = hdr->hdr[0];
}
} while (fgets(line, sizeof(line), sockrfp) != 0);
@@ -1512,7 +1528,7 @@ http_headers * get_response_headers(FILE *sockrfp){
* TODO: if other (unknown) encodings are present, it should return PROP_ENCODED_UNKNOWN */
int return_content_encoding(http_headers *shdr){
int content_encoding = PROP_ENCODED_NONE;
-
+
if (shdr->where_content_encoding > 0) {
if (strstr (shdr->content_encoding, "gzip") != NULL)
content_encoding |= PROP_ENCODED_GZIP;
@@ -1540,8 +1556,8 @@ void decide_what_to_do(http_headers *chdr, http_headers *shdr){
shdr->type = OTHER_CONTENT;
shdr->flags &= ~DO_COMPRESS;
shdr->flags &= ~DO_PRE_DECOMPRESS;
-
- if(-1 == shdr->where_content_type) return;
+
+ if(-1 == shdr->where_content_type) return;
/* is this something we can losslessly compress? */
if (ct_check_if_matches (lossless_compress_ct, shdr->content_type) != 0) {
@@ -1557,7 +1573,7 @@ void decide_what_to_do(http_headers *chdr, http_headers *shdr){
} else if (!strncasecmp(tempp, "image/jpeg", 10) ||
!strncasecmp(tempp, "image/pjpeg", 11) ||
!strncasecmp(tempp, "image/jpg", 9) ||
- !strncasecmp(tempp, "image/pjpg", 10)
+ !strncasecmp(tempp, "image/pjpg", 10)
) {
shdr->type = IMG_JPEG;
if (ProcessJPG)
@@ -1584,7 +1600,7 @@ void decide_what_to_do(http_headers *chdr, http_headers *shdr){
shdr->flags |= DO_OPTIMIZE_HTML;
if ((ProcessCSS) && (shdr->type == TEXT_CSS))
- shdr->flags |= DO_OPTIMIZE_CSS;
+ shdr->flags |= DO_OPTIMIZE_CSS;
if ((ProcessJS) && (shdr->type == APPLICATION_JAVASCRIPT))
shdr->flags |= DO_OPTIMIZE_JS;
@@ -1598,8 +1614,8 @@ void decide_what_to_do(http_headers *chdr, http_headers *shdr){
if (DecompressIncomingGzipData)
shdr->flags |= DO_PRE_DECOMPRESS;
}
-
- /*
+
+ /*
* From this point, manage flags only to clear DO_* bits
*/
@@ -1618,7 +1634,7 @@ void decide_what_to_do(http_headers *chdr, http_headers *shdr){
shdr->flags &= ~DO_PREEMPT_DNS;
}
}
-
+
/* Workaround for MSIE's pseudo-feature "Show friendly HTTP error messages."
* Don't optimize the body of this in any way, since it could go down below 256 or 512 bytes
* and be replaced with a local error message instead.
@@ -1630,14 +1646,14 @@ void decide_what_to_do(http_headers *chdr, http_headers *shdr){
shdr->flags &= ~META_CONTENT_MODIFICATION;
}
}
-
+
}
//Remove extra whitespace that may prevent correct parsing.
void clean_hdr(char* ln){
int spaces = 0;
char * colon, *i;
-
+
colon = strchr(ln,':');
if (colon == NULL) return;
for(i = colon + 1; *i != '\0'; i++){
@@ -1655,7 +1671,7 @@ void clean_hdr(char* ln){
*/
void fix_request_url (http_headers *hdr) {
char *new_url;
-
+
if (*(hdr->host) == '\0')
send_error (400, "Bad Request", NULL, "Malformed request or non-HTTP/1.1 compliant.");
diff --git a/src/http.h b/src/http.h
index 9add513..9965eab 100644
--- a/src/http.h
+++ b/src/http.h
@@ -60,7 +60,7 @@
#define EXTERN
#else
#define EXTERN extern
-#endif
+#endif
//To stop multiple inclusions.
#ifndef SRC_HTTP_H
@@ -78,7 +78,7 @@ typedef struct {
/* those "where_*" vars store the position in the array of headers */
int where_content_type, where_content_length, where_chunked;
int where_content_encoding, where_etag;
-
+
// If headers contain request from client, status is always -1.
// It may be 200, 404 etc
int status;
@@ -91,7 +91,7 @@ typedef struct {
int client_explicity_accepts_jp2;
unsigned short int port;
- int chunklen;
+ int chunklen;
} http_headers;
#define H_WILLGZIP (1<<1) // whether the (real, user's) client supports Gzip
@@ -140,6 +140,7 @@ EXTERN void remove_header_str(http_headers *hdr, const char* key);
EXTERN void replace_header_str(http_headers *hdr, const char* key, const char *newhdr);
EXTERN http_headers * get_response_headers(FILE *sockrfp);
EXTERN void send_headers_to(FILE * sockfp, http_headers *hdr);
+EXTERN void forward_ssl_headers_to(FILE * sockfp, http_headers *hdr);
EXTERN int return_content_encoding(http_headers *shdr);
EXTERN void decide_what_to_do(http_headers *chdr, http_headers *shdr);
diff --git a/src/ziproxy.c b/src/ziproxy.c
index 376d642..b985005 100644
--- a/src/ziproxy.c
+++ b/src/ziproxy.c
@@ -100,7 +100,7 @@ int ziproxy (const char *client_addr, struct sockaddr_in *socket_host, SOCKET so
debug_log_puts ("TOS marking is enabled.");
if (tosmarking_init (TOSMarking, sock_child_out, TOSFlagsDefault, TOSFlagsDiff, tos_markasdiff_url, tos_maskasdiff_ct, TOSMarkAsDiffSizeBT))
debug_log_printf ("TOS: default traffic set to 0x%x\n", TOSFlagsDefault);
-
+
if(ConnTimeout){
/* catch timeouts */
(void) signal (SIGALRM, sigcatch);
@@ -123,11 +123,10 @@ int ziproxy (const char *client_addr, struct sockaddr_in *socket_host, SOCKET so
if (((hdrs->flags & H_TRANSP_PROXY_REQUEST) == 0) && (! ConventionalProxy))
send_error (400, "Bad Request", NULL, "HTTP proxy requests not honoured by server.");
-
+
if (hdrs->flags & H_USE_SSL) {
access_log_set_flags (LOG_AC_FLAG_CONV_PROXY); /* CONNECT only works in conventional proxy mode */
access_log_set_flags (LOG_AC_FLAG_CONN_METHOD);
- NextProxy = NULL;
} else { /* not SSL, fill in the rest of client request */
get_client_headers (hdrs);
debug_log_difftime ("getting, parsing headers");
@@ -198,7 +197,7 @@ int ziproxy (const char *client_addr, struct sockaddr_in *socket_host, SOCKET so
/* Open the client socket to the real web server. */
sockfd = open_client_socket (hdrs->host, hdrs->port, socket_host);
- /* Open separate streams for read and write, r+ doesn't always work.
+ /* Open separate streams for read and write, r+ doesn't always work.
* What about "a+" ? */
sockrfp = fdopen( sockfd, "r" );
sockwfp = fdopen( sockfd, "w" );
@@ -243,7 +242,7 @@ static int open_client_socket (char* hostname, unsigned short int Port, struct s
int sa_len, sock_family, sock_type, sock_protocol;
int sockfd;
int sa_entries = 0;
-
+
memset( (void*) &sa, 0, sizeof(sa) );
#ifdef USE_IPV6
@@ -251,7 +250,7 @@ static int open_client_socket (char* hostname, unsigned short int Port, struct s
#else
#define SIZEOF_SA sizeof(struct sockaddr_in)
#endif
-
+
if (NextProxy != NULL) {
hostname = NextProxy;
Port = NextPort;
@@ -273,7 +272,7 @@ if (NextProxy != NULL) {
{
switch ( ai2->ai_family )
{
- case AF_INET:
+ case AF_INET:
if ( aiv4 == NULL )
aiv4 = ai2;
break;
@@ -299,16 +298,16 @@ if (NextProxy != NULL) {
sa_len = aiv4->ai_addrlen;
/* loops each returned IP address and fills the array */
- {
+ {
struct addrinfo* current_aiv4 = aiv4;
-
+
(void) memmove (&sa[sa_entries++], current_aiv4->ai_addr, sa_len);
while ((sa_entries < MAX_SA_ENTRIES) && (current_aiv4->ai_next != NULL)) {
current_aiv4 = current_aiv4->ai_next;
(void) memmove (&sa[sa_entries++], current_aiv4->ai_addr, sa_len);
}
}
-
+
goto ok;
}
if ( aiv6 != NULL )
@@ -362,7 +361,7 @@ if (NextProxy != NULL) {
sa[sa_entries].sin_port = htons (Port);
sa_entries++;
}
-
+
#endif /* USE_IPV6 */
sockfd = socket( sock_family, sock_type, sock_protocol );
@@ -385,12 +384,16 @@ if (NextProxy != NULL) {
return (-1);
}
-
void proxy_ssl (http_headers *hdr, FILE* sockrfp, FILE* sockwfp)
-{
- /* Return SSL-proxy greeting header. */
- fputs ("HTTP/1.0 200 Connection established\r\n\r\n", sess_wclient);
- fflush (sess_wclient);
+{
+ if(NextProxy == NULL) {
+ /* Return SSL-proxy greeting header. */
+ fputs ("HTTP/1.0 200 Connection established\r\n\r\n", sess_wclient);
+ fflush (sess_wclient);
+ } else {
+ // forward connect message to server.
+ forward_ssl_headers_to (sockwfp, hdr);
+ }
blind_tunnel (hdr, sockrfp, sockwfp);
access_log_dump_entry ();
--
1.7.5.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment