A _tonne_ of changes. It would almost be easier to just read the source
itself to find out all the changes. Changed the process_client_header() function to use the hashmap and vector modules. I've made this change to better handle the Connection header. The Connection header, it it's present, lists all the headers which should _not_ be transmitted any further along. An HTTP/1.1 proxy must respect this. Other changes are basically cosmetic.
This commit is contained in:
parent
5e9aa90009
commit
fb736ec3fb
373
src/reqs.c
373
src/reqs.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: reqs.c,v 1.52 2001-12-24 00:01:02 rjkaes Exp $
|
/* $Id: reqs.c,v 1.53 2002-04-07 21:35:59 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* This is where all the work in tinyproxy is actually done. Incoming
|
* This is where all the work in tinyproxy is actually done. Incoming
|
||||||
* connections have a new thread created for them. The thread then
|
* connections have a new thread created for them. The thread then
|
||||||
@ -30,6 +30,7 @@
|
|||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "conns.h"
|
#include "conns.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
#include "hashmap.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "regexp.h"
|
#include "regexp.h"
|
||||||
#include "reqs.h"
|
#include "reqs.h"
|
||||||
@ -75,39 +76,38 @@
|
|||||||
* connections. The request line is allocated from the heap, but it must
|
* connections. The request line is allocated from the heap, but it must
|
||||||
* be freed in another function.
|
* be freed in another function.
|
||||||
*/
|
*/
|
||||||
static char *
|
static int
|
||||||
read_request_line(struct conn_s *connptr)
|
read_request_line(struct conn_s *connptr)
|
||||||
{
|
{
|
||||||
char *request_buffer;
|
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
len = readline(connptr->client_fd, &request_buffer);
|
len = readline(connptr->client_fd, &connptr->request_line);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
log_message(LOG_ERR,
|
log_message(LOG_ERR,
|
||||||
"read_request_line: Client (file descriptor: %d) closed socket before read.",
|
"read_request_line: Client (file descriptor: %d) closed socket before read.",
|
||||||
connptr->client_fd);
|
connptr->client_fd);
|
||||||
safefree(request_buffer);
|
safefree(connptr->request_line);
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Strip the new line and character return from the string.
|
* Strip the new line and character return from the string.
|
||||||
*/
|
*/
|
||||||
if (chomp(request_buffer, len) == len) {
|
if (chomp(connptr->request_line, len) == len) {
|
||||||
/*
|
/*
|
||||||
* If the number of characters removed is the same as the
|
* If the number of characters removed is the same as the
|
||||||
* length then it was a blank line. Free the buffer and
|
* length then it was a blank line. Free the buffer and
|
||||||
* try again (since we're looking for a request line.)
|
* try again (since we're looking for a request line.)
|
||||||
*/
|
*/
|
||||||
safefree(request_buffer);
|
safefree(connptr->request_line);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message(LOG_CONN, "Request (file descriptor %d): %s",
|
log_message(LOG_CONN, "Request (file descriptor %d): %s",
|
||||||
connptr->client_fd, request_buffer);
|
connptr->client_fd, connptr->request_line);
|
||||||
|
|
||||||
return request_buffer;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -118,8 +118,9 @@ struct request_s {
|
|||||||
char *protocol;
|
char *protocol;
|
||||||
|
|
||||||
char *host;
|
char *host;
|
||||||
|
uint16_t port;
|
||||||
|
|
||||||
char *path;
|
char *path;
|
||||||
int port;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -154,11 +155,11 @@ extract_http_url(const char *url, struct request_s *request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sscanf
|
if (sscanf
|
||||||
(url, "http://%[^:/]:%d%s", request->host, &request->port,
|
(url, "http://%[^:/]:%hu%s", request->host, &request->port,
|
||||||
request->path) == 3) ;
|
request->path) == 3) ;
|
||||||
else if (sscanf(url, "http://%[^/]%s", request->host, request->path) == 2)
|
else if (sscanf(url, "http://%[^/]%s", request->host, request->path) == 2)
|
||||||
request->port = 80;
|
request->port = 80;
|
||||||
else if (sscanf(url, "http://%[^:/]:%d", request->host, &request->port)
|
else if (sscanf(url, "http://%[^:/]:%hu", request->host, &request->port)
|
||||||
== 2)
|
== 2)
|
||||||
strcpy(request->path, "/");
|
strcpy(request->path, "/");
|
||||||
else if (sscanf(url, "http://%[^/]", request->host) == 1) {
|
else if (sscanf(url, "http://%[^/]", request->host) == 1) {
|
||||||
@ -186,7 +187,7 @@ extract_ssl_url(const char *url, struct request_s *request)
|
|||||||
if (!request->host)
|
if (!request->host)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (sscanf(url, "%[^:]:%d", request->host, &request->port) == 2) ;
|
if (sscanf(url, "%[^:]:%hu", request->host, &request->port) == 2) ;
|
||||||
else if (sscanf(url, "%s", request->host) == 1)
|
else if (sscanf(url, "%s", request->host) == 1)
|
||||||
request->port = 443;
|
request->port = 443;
|
||||||
else {
|
else {
|
||||||
@ -255,7 +256,7 @@ send_ssl_response(struct conn_s *connptr)
|
|||||||
* build a new request line. Finally connect to the remote server.
|
* build a new request line. Finally connect to the remote server.
|
||||||
*/
|
*/
|
||||||
static struct request_s *
|
static struct request_s *
|
||||||
process_request(struct conn_s *connptr, char *request_line)
|
process_request(struct conn_s *connptr)
|
||||||
{
|
{
|
||||||
char *url;
|
char *url;
|
||||||
struct request_s *request;
|
struct request_s *request;
|
||||||
@ -269,7 +270,7 @@ process_request(struct conn_s *connptr, char *request_line)
|
|||||||
if (!request)
|
if (!request)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
request_len = strlen(request_line) + 1;
|
request_len = strlen(connptr->request_line) + 1;
|
||||||
|
|
||||||
request->method = safemalloc(request_len);
|
request->method = safemalloc(request_len);
|
||||||
url = safemalloc(request_len);
|
url = safemalloc(request_len);
|
||||||
@ -283,8 +284,8 @@ process_request(struct conn_s *connptr, char *request_line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
sscanf(request_line, "%[^ ] %[^ ] %[^ ]", request->method, url,
|
sscanf(connptr->request_line, "%[^ ] %[^ ] %[^ ]",
|
||||||
request->protocol);
|
request->method, url, request->protocol);
|
||||||
if (ret < 2) {
|
if (ret < 2) {
|
||||||
log_message(LOG_ERR,
|
log_message(LOG_ERR,
|
||||||
"process_request: Bad Request on file descriptor %d",
|
"process_request: Bad Request on file descriptor %d",
|
||||||
@ -397,33 +398,6 @@ process_request(struct conn_s *connptr, char *request_line)
|
|||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Check to see if the line is allowed or not depending on the anonymous
|
|
||||||
* headers which are to be allowed. If the header is found in the
|
|
||||||
* anonymous list return 0, otherwise return -1.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
compare_header(char *line)
|
|
||||||
{
|
|
||||||
char *buffer;
|
|
||||||
char *ptr;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ((ptr = strstr(line, ":")) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((buffer = safemalloc(ptr - line + 1)) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
memcpy(buffer, line, (size_t) (ptr - line));
|
|
||||||
buffer[ptr - line] = '\0';
|
|
||||||
|
|
||||||
ret = anonymous_search(buffer);
|
|
||||||
safefree(buffer);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pull_client_data is used to pull across any client data (like in a
|
* pull_client_data is used to pull across any client data (like in a
|
||||||
* POST) which needs to be handled before an error can be reported, or
|
* POST) which needs to be handled before an error can be reported, or
|
||||||
@ -450,7 +424,7 @@ pull_client_data(struct conn_s *connptr, unsigned long int length)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!connptr->send_response_message) {
|
if (!connptr->response_message_sent) {
|
||||||
if (safe_write(connptr->server_fd, buffer, len) < 0) {
|
if (safe_write(connptr->server_fd, buffer, len) < 0) {
|
||||||
safefree(buffer);
|
safefree(buffer);
|
||||||
return -1;
|
return -1;
|
||||||
@ -487,6 +461,112 @@ add_xtinyproxy_header(struct conn_s *connptr)
|
|||||||
}
|
}
|
||||||
#endif /* XTINYPROXY */
|
#endif /* XTINYPROXY */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check to see if the header is allowed or not depending on the anonymous
|
||||||
|
* headers which are to be allowed. If the header is found in the
|
||||||
|
* anonymous list return 0, otherwise return -1.
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
compare_header(char *header)
|
||||||
|
{
|
||||||
|
return anonymous_search(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Take a complete header line and break it apart (into a key and the data.)
|
||||||
|
* Now insert this information into the hashmap for the connection so it
|
||||||
|
* can be retrieved and manipulated later.
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
add_header_to_connection(hashmap_t hashofheaders, char *header, size_t len)
|
||||||
|
{
|
||||||
|
char *sep;
|
||||||
|
size_t data_len;
|
||||||
|
|
||||||
|
/* Get rid of the new line and return at the end */
|
||||||
|
chomp(header, len);
|
||||||
|
|
||||||
|
sep = strchr(header, ':');
|
||||||
|
if (!sep)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Blank out colons, spaces, and tabs. */
|
||||||
|
while (*sep == ':' || *sep == ' ' || *sep == '\t')
|
||||||
|
*sep++ = '\0';
|
||||||
|
|
||||||
|
data_len = strlen(sep) + 1; /* need to add the null to the length */
|
||||||
|
return hashmap_insert(hashofheaders, header, sep, data_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read all the headers from the stream
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
get_all_headers(int fd, hashmap_t hashofheaders)
|
||||||
|
{
|
||||||
|
char *header;
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if ((len = readline(fd, &header)) <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we received just a CR LF on a line, the headers are
|
||||||
|
* finished.
|
||||||
|
*/
|
||||||
|
if (CHECK_CRLF(header, len))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (add_header_to_connection(hashofheaders, header, len) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract the headers to remove. These headers were listed in the Connection
|
||||||
|
* header sent via the client (which is stored in data right now.)
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
remove_connection_headers(hashmap_t hashofheaders, char* data, ssize_t len)
|
||||||
|
{
|
||||||
|
char* ptr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Go through the data line and replace any special characters with
|
||||||
|
* a NULL.
|
||||||
|
*/
|
||||||
|
ptr = data;
|
||||||
|
while ((ptr = strpbrk(ptr, "()<>@,;:\\\"/[]?={} \t"))) {
|
||||||
|
*ptr++ = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All the tokens are separated by NULLs. Now go through the tokens
|
||||||
|
* and remove them from the hashofheaders.
|
||||||
|
*/
|
||||||
|
ptr = data;
|
||||||
|
while (ptr < data + len) {
|
||||||
|
DEBUG2("Removing header [%s]", ptr);
|
||||||
|
hashmap_remove(hashofheaders, ptr);
|
||||||
|
|
||||||
|
/* Advance ptr to the next token */
|
||||||
|
ptr += strlen(ptr) + 1;
|
||||||
|
while (*ptr == '\0')
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of buckets to use internally in the hashmap.
|
||||||
|
*/
|
||||||
|
#define HEADER_BUCKETS 32
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Here we loop through all the headers the client is sending. If we
|
* Here we loop through all the headers the client is sending. If we
|
||||||
* are running in anonymous mode, we will _only_ send the headers listed
|
* are running in anonymous mode, we will _only_ send the headers listed
|
||||||
@ -496,11 +576,6 @@ add_xtinyproxy_header(struct conn_s *connptr)
|
|||||||
static int
|
static int
|
||||||
process_client_headers(struct conn_s *connptr)
|
process_client_headers(struct conn_s *connptr)
|
||||||
{
|
{
|
||||||
char *header;
|
|
||||||
long content_length = -1;
|
|
||||||
short int sent_via_header = 0;
|
|
||||||
ssize_t len;
|
|
||||||
|
|
||||||
static char *skipheaders[] = {
|
static char *skipheaders[] = {
|
||||||
"host",
|
"host",
|
||||||
"connection",
|
"connection",
|
||||||
@ -513,122 +588,120 @@ process_client_headers(struct conn_s *connptr)
|
|||||||
"upgrade"
|
"upgrade"
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
hashmap_t hashofheaders;
|
||||||
|
vector_t listofheaders;
|
||||||
|
long content_length = -1;
|
||||||
|
|
||||||
for (;;) {
|
char *data, *header;
|
||||||
if ((len = readline(connptr->client_fd, &header)) <= 0) {
|
size_t len;
|
||||||
DEBUG2("Client (file descriptor %d) closed connection.",
|
|
||||||
connptr->client_fd);
|
hashofheaders = hashmap_create(HEADER_BUCKETS);
|
||||||
|
if (!hashofheaders)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get all the headers from the client in a big hash.
|
||||||
|
*/
|
||||||
|
if (get_all_headers(connptr->client_fd, hashofheaders) < 0) {
|
||||||
|
hashmap_delete(hashofheaders);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If we receive a CR LF (or just a LF) on a line by itself,
|
|
||||||
* the headers are finished.
|
|
||||||
*/
|
|
||||||
if (CHECK_CRLF(header, len))
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't send headers if there's already an error, or if
|
* Don't send headers if there's already an error, or if this was
|
||||||
* this was a CONNECT method (unless upstream proxy is in
|
* a CONNECT method (unless upstream proxy is in use.)
|
||||||
* use.)
|
|
||||||
*/
|
*/
|
||||||
if (connptr->server_fd == -1
|
if (connptr->server_fd == -1
|
||||||
|| (connptr->connect_method && !UPSTREAM_CONFIGURED())) {
|
|| (connptr->connect_method && !UPSTREAM_CONFIGURED())) {
|
||||||
safefree(header);
|
hashmap_delete(hashofheaders);
|
||||||
continue;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we find a Via header we need to append our information
|
* See if there is a "Connection" header. If so, we need to do a bit
|
||||||
* to the end of it.
|
* of processing. :)
|
||||||
*/
|
*/
|
||||||
if (strncasecmp(header, "via", 3) == 0) {
|
len = hashmap_search(hashofheaders, "connection", (void **)&data);
|
||||||
if (sent_via_header == 0) {
|
if (len > 0) {
|
||||||
char hostname[128];
|
/*
|
||||||
|
* Go through the tokens in the connection header and
|
||||||
|
* remove the headers from the hash.
|
||||||
|
*/
|
||||||
|
remove_connection_headers(hashofheaders, data, len);
|
||||||
|
hashmap_remove(hashofheaders, "connection");
|
||||||
|
}
|
||||||
|
|
||||||
chomp(header, len);
|
/*
|
||||||
|
* See if there is a "Content-Length" header. If so, again we need
|
||||||
|
* to do a bit of processing.
|
||||||
|
*/
|
||||||
|
len = hashmap_search(hashofheaders, "content-length", (void **)&data);
|
||||||
|
if (len > 0) {
|
||||||
|
content_length = atol(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See if there is a "Via" header. If so, again we need to do a bit
|
||||||
|
* of processing.
|
||||||
|
*/
|
||||||
|
len = hashmap_search(hashofheaders, "via", (void **)&data);
|
||||||
|
if (len > 0) {
|
||||||
|
/* Take on our information */
|
||||||
|
char hostname[128];
|
||||||
gethostname(hostname, sizeof(hostname));
|
gethostname(hostname, sizeof(hostname));
|
||||||
|
|
||||||
write_message(connptr->server_fd,
|
write_message(connptr->server_fd,
|
||||||
"%s, %hu.%hu %s (%s/%s)\r\n",
|
"Via: %s, %hu.%hu %s (%s/%s)\r\n",
|
||||||
header,
|
data,
|
||||||
connptr->protocol.major,
|
connptr->protocol.major, connptr->protocol.minor,
|
||||||
connptr->protocol.minor,
|
|
||||||
hostname, PACKAGE, VERSION);
|
hostname, PACKAGE, VERSION);
|
||||||
|
|
||||||
sent_via_header = 1;
|
hashmap_remove(hashofheaders, "via");
|
||||||
}
|
} else {
|
||||||
safefree(header);
|
/* There is no header, so we need to create it. */
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Don't send certain headers.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < (sizeof(skipheaders) / sizeof(char *)); i++) {
|
|
||||||
if (strncasecmp
|
|
||||||
(header, skipheaders[i],
|
|
||||||
strlen(skipheaders[i])) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i != (sizeof(skipheaders) / sizeof(char *))) {
|
|
||||||
safefree(header);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_anonymous_enabled() && compare_header(header) < 0) {
|
|
||||||
safefree(header);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content_length == -1
|
|
||||||
&& strncasecmp(header, "content-length", 14) == 0) {
|
|
||||||
char *content_ptr = strchr(header, ':') + 1;
|
|
||||||
content_length = atol(content_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (safe_write(connptr->server_fd, header, strlen(header)) < 0) {
|
|
||||||
safefree(header);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
safefree(header);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!connptr->send_response_message
|
|
||||||
&& (!connptr->connect_method || UPSTREAM_CONFIGURED())) {
|
|
||||||
#ifdef XTINYPROXY_ENABLE
|
|
||||||
if (config.my_domain && add_xtinyproxy_header(connptr) < 0) {
|
|
||||||
safefree(header);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif /* XTINYPROXY */
|
|
||||||
|
|
||||||
if (sent_via_header == 0) {
|
|
||||||
/*
|
|
||||||
* We're the first proxy so send the first Via header.
|
|
||||||
*/
|
|
||||||
char hostname[128];
|
char hostname[128];
|
||||||
|
|
||||||
gethostname(hostname, sizeof(hostname));
|
gethostname(hostname, sizeof(hostname));
|
||||||
|
|
||||||
write_message(connptr->server_fd,
|
write_message(connptr->server_fd,
|
||||||
"Via: %hu.%hu %s (%s/%s)\r\n",
|
"Via: %hu.%hu %s (%s/%s)\r\n",
|
||||||
connptr->protocol.major,
|
connptr->protocol.major, connptr->protocol.minor,
|
||||||
connptr->protocol.minor,
|
|
||||||
hostname, PACKAGE, VERSION);
|
hostname, PACKAGE, VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((connptr->server_fd != -1)
|
/*
|
||||||
&& safe_write(connptr->server_fd, header,
|
* Delete the headers listed in the skipheaders list
|
||||||
strlen(header)) < 0) {
|
*/
|
||||||
safefree(header);
|
for (i = 0; i < (sizeof(skipheaders) / sizeof(char *)); i++) {
|
||||||
return -1;
|
hashmap_remove(hashofheaders, skipheaders[i]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
safefree(header);
|
/*
|
||||||
|
* Output all the remaining headers to the remote machine.
|
||||||
|
*/
|
||||||
|
listofheaders = hashmap_keys(hashofheaders);
|
||||||
|
for (i = 0; i < vector_length(listofheaders); i++) {
|
||||||
|
len = vector_getentry(listofheaders, i, (void **)&data);
|
||||||
|
|
||||||
|
hashmap_search(hashofheaders, data, (void **)&header);
|
||||||
|
|
||||||
|
if (!is_anonymous_enabled() || compare_header(data) == 0) {
|
||||||
|
write_message(connptr->server_fd,
|
||||||
|
"%s: %s\r\n",
|
||||||
|
data, header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector_delete(listofheaders);
|
||||||
|
|
||||||
|
/* Free the hashofheaders since it's no longer needed */
|
||||||
|
hashmap_delete(hashofheaders);
|
||||||
|
|
||||||
|
#if defined(XTINYPROXY_ENABLE)
|
||||||
|
add_xtinyproxy_header(connptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Write the final "blank" line to signify the end of the headers */
|
||||||
|
safe_write(connptr->server_fd, "\r\n", 2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Spin here pulling the data from the client.
|
* Spin here pulling the data from the client.
|
||||||
@ -896,20 +969,15 @@ handle_connection(int fd)
|
|||||||
char peer_ipaddr[PEER_IP_LENGTH];
|
char peer_ipaddr[PEER_IP_LENGTH];
|
||||||
char peer_string[PEER_STRING_LENGTH];
|
char peer_string[PEER_STRING_LENGTH];
|
||||||
|
|
||||||
char *request_line = NULL;
|
|
||||||
|
|
||||||
log_message(LOG_CONN, "Connect (file descriptor %d): %s [%s]",
|
log_message(LOG_CONN, "Connect (file descriptor %d): %s [%s]",
|
||||||
fd,
|
fd,
|
||||||
getpeer_string(fd, peer_string),
|
getpeer_string(fd, peer_string),
|
||||||
getpeer_ip(fd, peer_ipaddr));
|
getpeer_ip(fd, peer_ipaddr));
|
||||||
|
|
||||||
connptr = safemalloc(sizeof(struct conn_s));
|
connptr = initialize_conn(fd);
|
||||||
if (!connptr)
|
if (!connptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
initialize_conn(connptr);
|
|
||||||
connptr->client_fd = fd;
|
|
||||||
|
|
||||||
if (check_acl(fd) <= 0) {
|
if (check_acl(fd) <= 0) {
|
||||||
update_stats(STAT_DENIED);
|
update_stats(STAT_DENIED);
|
||||||
httperr(connptr, 403,
|
httperr(connptr, 403,
|
||||||
@ -925,18 +993,15 @@ handle_connection(int fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal_proxy:
|
internal_proxy:
|
||||||
request_line = read_request_line(connptr);
|
if (read_request_line(connptr) < 0) {
|
||||||
if (!request_line) {
|
|
||||||
update_stats(STAT_BADCONN);
|
update_stats(STAT_BADCONN);
|
||||||
destroy_conn(connptr);
|
destroy_conn(connptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
request = process_request(connptr, request_line);
|
request = process_request(connptr);
|
||||||
safefree(request_line);
|
|
||||||
|
|
||||||
if (!request) {
|
if (!request) {
|
||||||
if (!connptr->send_response_message) {
|
if (!connptr->response_message_sent) {
|
||||||
update_stats(STAT_BADCONN);
|
update_stats(STAT_BADCONN);
|
||||||
destroy_conn(connptr);
|
destroy_conn(connptr);
|
||||||
return;
|
return;
|
||||||
@ -967,13 +1032,13 @@ handle_connection(int fd)
|
|||||||
|
|
||||||
if (process_client_headers(connptr) < 0) {
|
if (process_client_headers(connptr) < 0) {
|
||||||
update_stats(STAT_BADCONN);
|
update_stats(STAT_BADCONN);
|
||||||
if (!connptr->send_response_message) {
|
if (!connptr->response_message_sent) {
|
||||||
destroy_conn(connptr);
|
destroy_conn(connptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connptr->send_response_message) {
|
if (connptr->response_message_sent) {
|
||||||
destroy_conn(connptr);
|
destroy_conn(connptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user