Changed the error boolean flag into a pointer to an error string and an

error code.  We're storing this information because tinyproxy doesn't
output the error information until _after_ the client has sent it's
information.
This commit is contained in:
Robert James Kaes 2002-04-15 02:07:27 +00:00
parent c86d22226f
commit a5d3212751
6 changed files with 65 additions and 28 deletions

View File

@ -1,3 +1,14 @@
2002-04-14 Robert James Kaes <rjkaes@flarenet.com>
* src/conns.h: Replaced the error boolean with a pointer to an
error string and error number for use in the
send_http_error_message() function.
* src/utils.c (indicate_http_error): Replaced the httperr()
function with this one. Instead of sending the error right away,
we store the error string and number and send them _after_ the
client headers have been processed.
2002-04-13 Robert James Kaes <rjkaes@flarenet.com> 2002-04-13 Robert James Kaes <rjkaes@flarenet.com>
* src/sock.c (opensock): If the Listen directive is in use, then * src/sock.c (opensock): If the Listen directive is in use, then

View File

@ -1,4 +1,4 @@
/* $Id: conns.c,v 1.8 2002-04-11 20:27:51 rjkaes Exp $ /* $Id: conns.c,v 1.9 2002-04-15 02:07:27 rjkaes Exp $
* *
* Create and free the connection structure. One day there could be * Create and free the connection structure. One day there could be
* other connnection related tasks put here, but for now the header * other connnection related tasks put here, but for now the header
@ -57,7 +57,10 @@ initialize_conn(int client_fd)
connptr->request_line = NULL; connptr->request_line = NULL;
connptr->response_message_sent = FALSE; /* These store any error strings */
connptr->error_string = NULL;
connptr->error_number = -1;
connptr->connect_method = FALSE; connptr->connect_method = FALSE;
connptr->protocol.major = connptr->protocol.minor = 0; connptr->protocol.major = connptr->protocol.minor = 0;
@ -98,6 +101,9 @@ destroy_conn(struct conn_s *connptr)
if (connptr->request_line) if (connptr->request_line)
safefree(connptr->request_line); safefree(connptr->request_line);
if (connptr->error_string)
safefree(connptr->error_string);
safefree(connptr); safefree(connptr);
update_stats(STAT_CLOSE); update_stats(STAT_CLOSE);

View File

@ -1,4 +1,4 @@
/* $Id: conns.h,v 1.7 2002-04-11 20:27:51 rjkaes Exp $ /* $Id: conns.h,v 1.8 2002-04-15 02:07:27 rjkaes Exp $
* *
* See 'conns.c' for a detailed description. * See 'conns.c' for a detailed description.
* *
@ -34,7 +34,10 @@ struct conn_s {
char *request_line; char *request_line;
bool_t connect_method; bool_t connect_method;
bool_t response_message_sent;
/* Store the error response if there is one */
char *error_string;
int error_number;
/* A Content-Length value from the remote server */ /* A Content-Length value from the remote server */
long remote_content_length; long remote_content_length;

View File

@ -1,4 +1,4 @@
/* $Id: reqs.c,v 1.57 2002-04-12 17:00:42 rjkaes Exp $ /* $Id: reqs.c,v 1.58 2002-04-15 02:07:27 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
@ -348,7 +348,7 @@ process_request(struct conn_s *connptr)
log_message(LOG_ERR, log_message(LOG_ERR,
"process_request: Bad Request on file descriptor %d", "process_request: Bad Request on file descriptor %d",
connptr->client_fd); connptr->client_fd);
httperr(connptr, 400, "Bad Request. No request found."); indicate_http_error(connptr, 400, "Bad Request. No request found.");
safefree(url); safefree(url);
free_request_struct(request); free_request_struct(request);
@ -364,7 +364,7 @@ process_request(struct conn_s *connptr)
log_message(LOG_ERR, log_message(LOG_ERR,
"process_request: Null URL on file descriptor %d", "process_request: Null URL on file descriptor %d",
connptr->client_fd); connptr->client_fd);
httperr(connptr, 400, "Bad Request. Null URL."); indicate_http_error(connptr, 400, "Bad Request. Null URL.");
safefree(url); safefree(url);
free_request_struct(request); free_request_struct(request);
@ -377,7 +377,7 @@ process_request(struct conn_s *connptr)
memcpy(url, "http", 4); memcpy(url, "http", 4);
if (extract_http_url(url, request) < 0) { if (extract_http_url(url, request) < 0) {
httperr(connptr, 400, indicate_http_error(connptr, 400,
"Bad Request. Could not parse URL."); "Bad Request. Could not parse URL.");
safefree(url); safefree(url);
@ -387,7 +387,7 @@ process_request(struct conn_s *connptr)
} }
} else if (strcmp(request->method, "CONNECT") == 0) { } else if (strcmp(request->method, "CONNECT") == 0) {
if (extract_ssl_url(url, request) < 0) { if (extract_ssl_url(url, request) < 0) {
httperr(connptr, 400, indicate_http_error(connptr, 400,
"Bad Request. Could not parse URL."); "Bad Request. Could not parse URL.");
safefree(url); safefree(url);
@ -398,7 +398,7 @@ process_request(struct conn_s *connptr)
/* Verify that the port in the CONNECT method is allowed */ /* Verify that the port in the CONNECT method is allowed */
if (check_allowed_connect_ports(request->port) <= 0) { if (check_allowed_connect_ports(request->port) <= 0) {
httperr(connptr, 403, indicate_http_error(connptr, 403,
"CONNECT method not allowed with selected port."); "CONNECT method not allowed with selected port.");
log_message(LOG_INFO, "Refused CONNECT method on port %d", log_message(LOG_INFO, "Refused CONNECT method on port %d",
request->port); request->port);
@ -414,7 +414,7 @@ process_request(struct conn_s *connptr)
log_message(LOG_ERR, log_message(LOG_ERR,
"process_request: Unknown URL type on file descriptor %d", "process_request: Unknown URL type on file descriptor %d",
connptr->client_fd); connptr->client_fd);
httperr(connptr, 400, "Bad Request. Unknown URL type."); indicate_http_error(connptr, 400, "Bad Request. Unknown URL type.");
safefree(url); safefree(url);
free_request_struct(request); free_request_struct(request);
@ -435,7 +435,7 @@ process_request(struct conn_s *connptr)
log_message(LOG_NOTICE, log_message(LOG_NOTICE,
"Proxying refused on filtered domain \"%s\"", "Proxying refused on filtered domain \"%s\"",
request->host); request->host);
httperr(connptr, 404, indicate_http_error(connptr, 404,
"Connection to filtered domain is now allowed."); "Connection to filtered domain is now allowed.");
free_request_struct(request); free_request_struct(request);
@ -495,7 +495,7 @@ pull_client_data(struct conn_s *connptr, unsigned long int length)
return -1; return -1;
} }
if (!connptr->response_message_sent) { if (!connptr->error_string) {
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;
@ -1022,7 +1022,7 @@ connect_to_upstream(struct conn_s *connptr, struct request_s *request)
if (connptr->server_fd < 0) { if (connptr->server_fd < 0) {
log_message(LOG_WARNING, log_message(LOG_WARNING,
"Could not connect to upstream proxy."); "Could not connect to upstream proxy.");
httperr(connptr, 404, "Unable to connect to upstream proxy."); indicate_http_error(connptr, 404, "Unable to connect to upstream proxy.");
return -1; return -1;
} }
@ -1094,7 +1094,7 @@ connect_to_tunnel(struct conn_s *connptr)
if (connptr->server_fd < 0) { if (connptr->server_fd < 0) {
log_message(LOG_WARNING, log_message(LOG_WARNING,
"Could not connect to tunnel."); "Could not connect to tunnel.");
httperr(connptr, 404, "Unable to connect to tunnel."); indicate_http_error(connptr, 404, "Unable to connect to tunnel.");
return -1; return -1;
} }
@ -1136,7 +1136,7 @@ handle_connection(int fd)
if (check_acl(fd) <= 0) { if (check_acl(fd) <= 0) {
update_stats(STAT_DENIED); update_stats(STAT_DENIED);
httperr(connptr, 403, indicate_http_error(connptr, 403,
"You do not have authorization for using this service."); "You do not have authorization for using this service.");
goto send_error; goto send_error;
} }
@ -1157,7 +1157,7 @@ handle_connection(int fd)
request = process_request(connptr); request = process_request(connptr);
if (!request) { if (!request) {
if (!connptr->response_message_sent) { if (!connptr->error_string) {
update_stats(STAT_BADCONN); update_stats(STAT_BADCONN);
destroy_conn(connptr); destroy_conn(connptr);
return; return;
@ -1171,7 +1171,7 @@ handle_connection(int fd)
} else { } else {
connptr->server_fd = opensock(request->host, request->port); connptr->server_fd = opensock(request->host, request->port);
if (connptr->server_fd < 0) { if (connptr->server_fd < 0) {
httperr(connptr, 500, HTTP500ERROR); indicate_http_error(connptr, 500, HTTP500ERROR);
goto send_error; goto send_error;
} }
@ -1188,13 +1188,14 @@ 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->response_message_sent) { if (!connptr->error_string) {
destroy_conn(connptr); destroy_conn(connptr);
return; return;
} }
} }
if (connptr->response_message_sent) { if (connptr->error_string) {
send_http_error_message(connptr);
destroy_conn(connptr); destroy_conn(connptr);
return; return;
} }

View File

@ -1,4 +1,4 @@
/* $Id: utils.c,v 1.22 2002-04-07 21:37:07 rjkaes Exp $ /* $Id: utils.c,v 1.23 2002-04-15 02:07:27 rjkaes Exp $
* *
* Misc. routines which are used by the various functions to handle strings * Misc. routines which are used by the various functions to handle strings
* and memory allocation and pretty much anything else we can think of. Also, * and memory allocation and pretty much anything else we can think of. Also,
@ -100,8 +100,6 @@ send_http_message(struct conn_s *connptr, int http_code,
safe_write(connptr->client_fd, message, strlen(message)); safe_write(connptr->client_fd, message, strlen(message));
connptr->response_message_sent = TRUE;
return 0; return 0;
} }
@ -109,7 +107,7 @@ send_http_message(struct conn_s *connptr, int http_code,
* Display an error to the client. * Display an error to the client.
*/ */
int int
httperr(struct conn_s *connptr, int err, const char *msg) send_http_error_message(struct conn_s *connptr)
{ {
static char *message = \ static char *message = \
"<html><head><title>%s</title></head>\r\n" \ "<html><head><title>%s</title></head>\r\n" \
@ -135,7 +133,9 @@ httperr(struct conn_s *connptr, int err, const char *msg)
* See the write_message() function in sock.c for more information. * See the write_message() function in sock.c for more information.
*/ */
while (1) { while (1) {
n = snprintf(message_buffer, size, message, msg, err, msg, PACKAGE, VERSION); n = snprintf(message_buffer, size, message,
connptr->error_string, connptr->error_number,
connptr->error_string, PACKAGE, VERSION);
if (n > -1 && n < size) if (n > -1 && n < size)
break; break;
@ -152,11 +152,26 @@ httperr(struct conn_s *connptr, int err, const char *msg)
message_buffer = tmpbuf; message_buffer = tmpbuf;
} }
ret = send_http_message(connptr, err, msg, message_buffer); ret = send_http_message(connptr, connptr->error_number,
connptr->error_string, message_buffer);
safefree(message_buffer); safefree(message_buffer);
return ret; return ret;
} }
/*
* Add the error information to the conn structure.
*/
int
indicate_http_error(struct conn_s* connptr, int number, const char* string)
{
connptr->error_string = strdup(string);
if (!connptr->error_string)
return -1;
connptr->error_number = number;
return 0;
}
void void
makedaemon(void) makedaemon(void)
{ {

View File

@ -1,4 +1,4 @@
/* $Id: utils.h,v 1.13 2001-11-25 02:22:05 rjkaes Exp $ /* $Id: utils.h,v 1.14 2002-04-15 02:07:27 rjkaes Exp $
* *
* See 'utils.h' for a detailed description. * See 'utils.h' for a detailed description.
* *
@ -32,7 +32,8 @@
extern int send_http_message(struct conn_s *connptr, int http_code, extern int send_http_message(struct conn_s *connptr, int http_code,
const char *error_title, const char *message); const char *error_title, const char *message);
extern int httperr(struct conn_s *connptr, int err, const char *msg); extern int send_http_error_message(struct conn_s *connptr);
extern int indicate_http_error(struct conn_s* connptr, int number, const char *string);
extern void makedaemon(void); extern void makedaemon(void);
extern void pidfile_create(const char *path); extern void pidfile_create(const char *path);