summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert James Kaes <rjkaes@users.sourceforge.net>2003-04-16 18:11:58 +0000
committerRobert James Kaes <rjkaes@users.sourceforge.net>2003-04-16 18:11:58 +0000
commitc94bfa82230472fa625e31b7e3d931b566433a80 (patch)
tree0a5ec45c17b537789fea5f2f529ccf872e2b63c7
parent648e8f1438e2c39e20ef6b4d6f6891246237abe5 (diff)
downloadtinyproxy-c94bfa82230472fa625e31b7e3d931b566433a80.tar.gz
tinyproxy-c94bfa82230472fa625e31b7e3d931b566433a80.zip
(build_url): Rebuild the URL from the component pieces. This function
is used by the transparent proxy code. [Anatole Shaw] (process_request): Fixed up the transparent proxy code so that filtering can be done on the whole URL. [Anatole Shaw] (pull_client_data): Added a bug fix for Internet Explorer (IE). IE will leave an extra CR and LF after the data in an HTTP POST. The new code will eat the extra bytes if they're present. Thanks to Yannick Koehler for finding the bug and offering an explanation as to why it was happening. Changed all calls of connptr->remote_content_length to connptr->content_length.server
Diffstat (limited to '')
-rw-r--r--src/reqs.c66
1 files changed, 53 insertions, 13 deletions
diff --git a/src/reqs.c b/src/reqs.c
index 9fe3404..516851d 100644
--- a/src/reqs.c
+++ b/src/reqs.c
@@ -1,4 +1,4 @@
-/* $Id: reqs.c,v 1.95 2003-03-26 16:47:30 rjkaes Exp $
+/* $Id: reqs.c,v 1.96 2003-04-16 18:11:58 rjkaes Exp $
*
* This is where all the work in tinyproxy is actually done. Incoming
* connections have a new child created for them. The child then
@@ -276,6 +276,27 @@ extract_ssl_url(const char *url, struct request_s *request)
}
/*
+ * Build a URL from parts.
+ */
+static int
+build_url(char **url, const char *host, int port, const char *path)
+{
+ int len;
+
+ assert(url != NULL);
+ assert(host != NULL);
+ assert(port > 0 && port < 32768);
+ assert(path != NULL);
+
+ len = strlen(host) + strlen(path) + 14;
+ *url = safemalloc(len);
+ if (*url == NULL)
+ return -1;
+
+ return snprintf(*url, len, "http://%s:%d%s", host, port, path);
+}
+
+/*
* Create a connection for HTTP connections.
*/
static int
@@ -358,6 +379,7 @@ process_request(struct conn_s *connptr, hashmap_t hashofheaders)
return NULL;
}
+
/*
* FIXME: We need to add code for the simple HTTP/0.9 style GET
* request.
@@ -456,9 +478,11 @@ process_request(struct conn_s *connptr, hashmap_t hashofheaders)
request->port = ntohs(dest_addr.sin_port);
request->path = safemalloc(strlen(url) + 1);
strcpy(request->path, url);
+ safefree(url);
+ build_url(&url, request->host, request->port, request->path);
log_message(LOG_INFO,
- "process_request: trans IP %s http://%s:%d%s for %d",
- request->method, request->host, request->port, request->path, connptr->client_fd);
+ "process_request: trans IP %s %s for %d",
+ request->method, url, connptr->client_fd);
} else {
request->host = safemalloc(length+1);
if (sscanf(data, "%[^:]:%hu", request->host, &request->port) != 2) {
@@ -467,9 +491,11 @@ process_request(struct conn_s *connptr, hashmap_t hashofheaders)
}
request->path = safemalloc(strlen(url) + 1);
strcpy(request->path, url);
+ safefree(url);
+ build_url(&url, request->host, request->port, request->path);
log_message(LOG_INFO,
- "process_request: trans Host %s http://%s:%d%s for %d",
- request->method, request->host, request->port, request->path, connptr->client_fd);
+ "process_request: trans Host %s %s for %d",
+ request->method, url, connptr->client_fd);
}
if (config.ipAddr &&
strcmp(request->host, config.ipAddr) == 0) {
@@ -567,7 +593,7 @@ process_request(struct conn_s *connptr, hashmap_t hashofheaders)
* - rjkaes
*/
static int
-pull_client_data(struct conn_s *connptr, unsigned long int length)
+pull_client_data(struct conn_s *connptr, long int length)
{
char *buffer;
ssize_t len;
@@ -590,6 +616,21 @@ pull_client_data(struct conn_s *connptr, unsigned long int length)
length -= len;
} while (length > 0);
+ /*
+ * BUG FIX: Internet Explorer will leave two bytes (carriage
+ * return and line feed) at the end of a POST message. These
+ * need to be eaten for tinyproxy to work correctly.
+ */
+ socket_nonblocking(connptr->client_fd);
+ len = recv(connptr->client_fd, buffer, 2, MSG_PEEK);
+ socket_blocking(connptr->client_fd);
+
+ if (len < 0 && errno != EAGAIN)
+ goto ERROR_EXIT;
+
+ if (len == 2 && CHECK_CRLF(buffer, len))
+ read(connptr->client_fd, buffer, 2);
+
safefree(buffer);
return 0;
@@ -840,7 +881,6 @@ process_client_headers(struct conn_s *connptr, hashmap_t hashofheaders)
};
int i;
hashmap_iter iter;
- long content_length = -1;
int ret = 0;
char *data, *header;
@@ -860,7 +900,7 @@ process_client_headers(struct conn_s *connptr, hashmap_t hashofheaders)
* See if there is a "Content-Length" header. If so, again we need
* to do a bit of processing.
*/
- content_length = get_content_length(hashofheaders);
+ connptr->content_length.client = get_content_length(hashofheaders);
/*
* See if there is a "Connection" header. If so, we need to do a bit
@@ -928,9 +968,9 @@ process_client_headers(struct conn_s *connptr, hashmap_t hashofheaders)
* Spin here pulling the data from the client.
*/
PULL_CLIENT_DATA:
- if (content_length > 0)
+ if (connptr->content_length.client > 0)
return pull_client_data(connptr,
- (unsigned long int) content_length);
+ connptr->content_length.client);
else
return ret;
}
@@ -1010,7 +1050,7 @@ process_server_headers(struct conn_s *connptr)
* If there is a "Content-Length" header, retrieve the information
* from it for later use.
*/
- connptr->remote_content_length = get_content_length(hashofheaders);
+ connptr->content_length.server = get_content_length(hashofheaders);
/*
* See if there is a connection header. If so, we need to to a bit of
@@ -1136,8 +1176,8 @@ relay_connection(struct conn_s *connptr)
if (bytes_received < 0)
break;
- connptr->remote_content_length -= bytes_received;
- if (connptr->remote_content_length == 0)
+ connptr->content_length.server -= bytes_received;
+ if (connptr->content_length.server == 0)
break;
}
if (FD_ISSET(connptr->client_fd, &rset)