76 |
|
|
77 |
#include "processor.h" |
#include "processor.h" |
78 |
#include "base64.h" |
#include "base64.h" |
|
#include "ssl.h" |
|
|
|
|
|
#define REQUEST 1 |
|
|
#define RESPONSE 2 |
|
|
#define HEADER 3 |
|
|
#define PARAM 4 |
|
|
|
|
|
/* Private variables */ |
|
|
extern ssl_server_connection * mySSLServerConnection; |
|
|
|
|
|
/* Private prototypes */ |
|
|
static void do_service(RequestWrapper); |
|
|
static void send_response(HttpResponse); |
|
|
static char *get_date(); |
|
|
static char *get_server(); |
|
|
static HttpRequest create_HttpRequest(RequestWrapper); |
|
|
static HttpResponse create_HttpResponse(RequestWrapper); |
|
|
static void create_headers(HttpRequest); |
|
|
static int create_parameters(HttpRequest req); |
|
|
static void reset_response(HttpResponse res); |
|
|
static int is_authenticated(HttpRequest, HttpResponse); |
|
|
static int basic_authenticate(HttpRequest); |
|
|
static void done(HttpRequest, HttpResponse); |
|
|
static void destroy_HttpRequest(HttpRequest); |
|
|
static void destroy_HttpResponse(HttpResponse); |
|
|
static void destroy_entry(void *); |
|
|
static void internal_error(int, int, char *); |
|
|
static void internal_error_ssl(ssl_connection *, int, char *); |
|
|
static HttpParameter parse_parameters(char *); |
|
79 |
|
|
80 |
|
|
81 |
/** |
/** |
107 |
*/ |
*/ |
108 |
|
|
109 |
|
|
110 |
/* ------------------------------------------------------------------- Entry */ |
/* -------------------------------------------------------------- Prototypes */ |
111 |
|
|
112 |
|
|
113 |
|
static void do_service(Socket_T); |
114 |
|
static void destroy_entry(void *); |
115 |
|
static char *get_date(char *, int); |
116 |
|
static char *get_server(char *, int); |
117 |
|
static void create_headers(HttpRequest); |
118 |
|
static void send_response(HttpResponse); |
119 |
|
static int basic_authenticate(HttpRequest); |
120 |
|
static void done(HttpRequest, HttpResponse); |
121 |
|
static void destroy_HttpRequest(HttpRequest); |
122 |
|
static void reset_response(HttpResponse res); |
123 |
|
static HttpParameter parse_parameters(char *); |
124 |
|
static int create_parameters(HttpRequest req); |
125 |
|
static void destroy_HttpResponse(HttpResponse); |
126 |
|
static HttpRequest create_HttpRequest(Socket_T); |
127 |
|
static void internal_error(Socket_T, int, char *); |
128 |
|
static HttpResponse create_HttpResponse(Socket_T); |
129 |
|
static int is_authenticated(HttpRequest, HttpResponse); |
130 |
|
|
131 |
|
|
132 |
|
/* ------------------------------------------------------------------ Public */ |
133 |
|
|
134 |
|
|
135 |
/** |
/** |
136 |
* Process a HTTP request. This is done by dispatching to the service |
* Process a HTTP request. This is done by dispatching to the service |
137 |
* function. |
* function. |
138 |
* @param wrapper A Wrapper object wrapping the client socket connection |
* @param s A Socket_T object wrapping the client socket connection |
139 |
*/ |
*/ |
140 |
void *http_processor(void *wrapper) { |
void *http_processor(void *s) { |
141 |
|
|
142 |
RequestWrapper W= wrapper; |
Socket_T S= s; |
143 |
|
|
144 |
if(! can_read(W->socket, REQUEST_TIMEOUT)) { |
if(! can_read(socket_get_socket(S), REQUEST_TIMEOUT)) { |
145 |
internal_error(W->socket, SC_REQUEST_TIMEOUT, |
internal_error(S, SC_REQUEST_TIMEOUT, "Time out when handling the Request"); |
|
"Time out when handling the Request"); |
|
146 |
goto shutdown; |
goto shutdown; |
147 |
} |
} |
148 |
do_service(W); |
|
149 |
|
do_service(S); |
150 |
|
|
151 |
shutdown: |
shutdown: |
152 |
destroy_wrapper(W); |
socket_free(&S); |
153 |
|
|
154 |
return NULL; |
return NULL; |
155 |
|
|
169 |
} |
} |
170 |
|
|
171 |
|
|
|
/* ------------------------------------------------------------------ Public */ |
|
|
|
|
|
|
|
172 |
/** |
/** |
173 |
* Send an error message |
* Send an error message |
174 |
* @param res HttpResponse object |
* @param res HttpResponse object |
177 |
*/ |
*/ |
178 |
void send_error(HttpResponse res, int code, const char *msg) { |
void send_error(HttpResponse res, int code, const char *msg) { |
179 |
|
|
180 |
char *server= get_server(); |
char server[STRLEN]; |
181 |
const char *err= get_status_string(code); |
const char *err= get_status_string(code); |
182 |
|
|
183 |
reset_response(res); |
reset_response(res); |
184 |
set_content_type(res, "text/html"); |
set_content_type(res, "text/html"); |
185 |
set_status(res, code); |
set_status(res, code); |
188 |
"<body bgcolor=#FFFFFF><h2>%s</h2>%s<p>"\ |
"<body bgcolor=#FFFFFF><h2>%s</h2>%s<p>"\ |
189 |
"<hr><a href='%s'><font size=-1>%s</font></a>"\ |
"<hr><a href='%s'><font size=-1>%s</font></a>"\ |
190 |
"</body></html>\r\n", |
"</body></html>\r\n", |
191 |
code, err, err, msg?msg:"", SERVER_URL, server); |
code, err, err, msg?msg:"", SERVER_URL, get_server(server, STRLEN)); |
192 |
free(server); |
|
|
|
|
193 |
} |
} |
194 |
|
|
195 |
|
|
220 |
* is_committed flag in the HttpResponse object and is responsible for |
* is_committed flag in the HttpResponse object and is responsible for |
221 |
* sending all HTTP headers and content by itself. |
* sending all HTTP headers and content by itself. |
222 |
* @param res HttpResponse object |
* @param res HttpResponse object |
223 |
* @param format A formated string to be sent to the client |
* @param m A formated string to be sent to the client |
224 |
*/ |
*/ |
225 |
void out_print(HttpResponse res, const char *format, ...) { |
void out_print(HttpResponse res, const char *m, ...) { |
226 |
|
|
227 |
if(format) { |
if(format) { |
228 |
|
|
229 |
int n= 0; |
char *buf; |
|
ssize_t need= 0; |
|
|
ssize_t have= 0; |
|
|
int size= RES_STRLEN; |
|
|
char *string= xmalloc(size); |
|
230 |
va_list ap; |
va_list ap; |
231 |
|
long need= 0; |
232 |
|
ssize_t have= 0; |
233 |
|
|
234 |
/* Ripped from the Linux vsnprintf man page */ |
va_start(ap, m); |
235 |
while (1) { |
buf= format(m, ap, &need); |
236 |
|
va_end(ap); |
|
va_start(ap, format); |
|
|
n= vsnprintf(string, size, format, ap); |
|
|
va_end(ap); |
|
|
|
|
|
if (n > -1 && n < size) { |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
if (n > -1) { |
|
|
|
|
|
size= n+1; |
|
|
|
|
|
} else { |
|
|
|
|
|
size*= 2; |
|
|
|
|
|
} |
|
|
|
|
|
string= xresize(string, size); |
|
|
|
|
|
} |
|
|
|
|
|
/* Check for possible buffersize overflow and abort if detected */ |
|
|
if((float)((float)(sizeof(char)*(res->bufsize + RES_STRLEN + n + 1)) |
|
|
> SSIZE_MAX)) { |
|
|
|
|
|
log("out_print: Possible http response buffer overflow detected. " |
|
|
"aborting \n"); |
|
|
exit(1); |
|
|
|
|
|
} |
|
237 |
|
|
238 |
have= res->bufsize - res->bufused; |
have= res->bufsize - res->bufused; |
|
need= sizeof(char)*( n + 1); |
|
239 |
|
|
240 |
if(have <= need) { |
if(have <= need) { |
241 |
|
|
|
/* Geometrical expand the outputbuffer size */ |
|
242 |
res->outputbuffer= |
res->outputbuffer= |
243 |
xresize(res->outputbuffer,(res->bufsize + need + RES_STRLEN)); |
xresize(res->outputbuffer,(res->bufsize + need + RES_STRLEN)); |
244 |
|
|
250 |
|
|
251 |
} |
} |
252 |
|
|
|
res->bufused+= need; |
|
|
|
|
|
} else { |
|
|
|
|
|
res->bufused+= need; |
|
|
|
|
253 |
} |
} |
254 |
|
|
255 |
strcat((char *) res->outputbuffer, string); |
memcpy(&res->outputbuffer[res->bufused], buf, need); |
256 |
|
res->bufused+= need; |
257 |
free(string); |
res->outputbuffer[res->bufused]= 0; |
258 |
|
free(buf); |
259 |
|
|
260 |
} |
} |
261 |
|
|
262 |
} |
} |
263 |
|
|
264 |
|
|
|
/** |
|
|
* Free a RequestWrapper object |
|
|
* @param w A RequestWrapper object (Should not be NULL) |
|
|
*/ |
|
|
void destroy_wrapper(RequestWrapper w) { |
|
|
|
|
|
if(w && w->inetaddr) { |
|
|
|
|
|
free(w->inetaddr->remote_host); |
|
|
free(w->inetaddr->local_host); |
|
|
free(w->inetaddr); |
|
|
|
|
|
} |
|
|
|
|
|
if(Run.httpdssl) { |
|
|
|
|
|
close_accepted_ssl_socket(mySSLServerConnection, w->ssl); |
|
|
|
|
|
} else { |
|
|
|
|
|
close_socket(w->socket); |
|
|
|
|
|
} |
|
|
|
|
|
free(w); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
265 |
/* -------------------------------------------------------------- Properties */ |
/* -------------------------------------------------------------- Properties */ |
266 |
|
|
267 |
|
|
396 |
|
|
397 |
*buf=0; |
*buf=0; |
398 |
|
|
399 |
for(p= res->headers; p; p= p->next) { |
for(p= res->headers; p && ((b-buf)>RES_STRLEN); p= p->next) { |
400 |
|
|
401 |
b+= snprintf(b, STRLEN-(b-buf),"%s: %s\r\n", p->name, p->value); |
b+= snprintf(b, STRLEN-(b-buf),"%s: %s\r\n", p->name, p->value); |
402 |
|
|
510 |
* Receives standard HTTP requests from a client socket and dispatches |
* Receives standard HTTP requests from a client socket and dispatches |
511 |
* them to the doXXX methods defined in a cervlet module. |
* them to the doXXX methods defined in a cervlet module. |
512 |
*/ |
*/ |
513 |
static void do_service(RequestWrapper w) { |
static void do_service(Socket_T s) { |
514 |
|
|
515 |
volatile HttpResponse res= create_HttpResponse(w); |
volatile HttpResponse res= create_HttpResponse(s); |
516 |
volatile HttpRequest req= create_HttpRequest(w); |
volatile HttpRequest req= create_HttpRequest(s); |
517 |
|
|
518 |
if(res && req) { |
if(res && req) { |
519 |
|
|
537 |
|
|
538 |
} |
} |
539 |
|
|
540 |
if(Run.httpdssl) { |
send_response(res); |
|
|
|
|
send_response(res); |
|
|
|
|
|
} else { |
|
|
|
|
|
if(check_socket(w->socket)) { |
|
|
|
|
|
send_response(res); |
|
|
} |
|
|
|
|
|
} |
|
541 |
|
|
542 |
} |
} |
543 |
|
|
549 |
/** |
/** |
550 |
* Return a (RFC1123) Date string |
* Return a (RFC1123) Date string |
551 |
*/ |
*/ |
552 |
static char *get_date() { |
static char *get_date(char *result, int size) { |
553 |
|
|
|
char date[STRLEN]; |
|
554 |
time_t now; |
time_t now; |
555 |
|
|
556 |
time(&now); |
time(&now); |
557 |
|
|
558 |
if(!strftime(date, STRLEN, DATEFMT, gmtime(&now))) { |
if(strftime(result, size, DATEFMT, gmtime(&now)) <= 0) { |
559 |
|
|
560 |
memset(date, 0, STRLEN); |
*result= 0; |
561 |
|
|
562 |
} |
} |
563 |
|
|
564 |
return xstrdup(date); |
return result; |
565 |
|
|
566 |
} |
} |
567 |
|
|
569 |
/** |
/** |
570 |
* Return this server name + version |
* Return this server name + version |
571 |
*/ |
*/ |
572 |
static char *get_server() { |
static char *get_server(char *result, int size) { |
573 |
|
|
574 |
char server[STRLEN]; |
snprintf(result, size, "%s %s", SERVER_NAME, SERVER_VERSION); |
|
snprintf(server, STRLEN, "%s %s", SERVER_NAME, SERVER_VERSION); |
|
575 |
|
|
576 |
return xstrdup(server); |
return result; |
577 |
|
|
578 |
} |
} |
579 |
|
|
584 |
*/ |
*/ |
585 |
static void send_response(HttpResponse res) { |
static void send_response(HttpResponse res) { |
586 |
|
|
587 |
|
Socket_T S= res->S; |
588 |
|
|
589 |
if(!res->is_committed) { |
if(!res->is_committed) { |
590 |
char *date= get_date(); |
char date[STRLEN]; |
591 |
char *server= get_server(); |
char server[STRLEN]; |
592 |
char *headers= get_headers(res); |
char *headers= get_headers(res); |
|
int len= res->bufused?strlen((char *) res->outputbuffer):0; |
|
|
|
|
|
if(Run.httpdssl) { |
|
|
|
|
|
printf_ssl_socket(res->ssl, "%s %d %s\r\n", res->protocol, res->status, |
|
|
res->status_msg); |
|
|
printf_ssl_socket(res->ssl, "Date: %s\r\n", date); |
|
|
printf_ssl_socket(res->ssl, "Server: %s\r\n", server); |
|
|
printf_ssl_socket(res->ssl, "Content-length: %d\r\n", len); |
|
|
printf_ssl_socket(res->ssl, "Connection: close\r\n"); |
|
|
if(headers)printf_ssl_socket(res->ssl, "%s", headers); |
|
|
printf_ssl_socket(res->ssl, "\r\n\r\n"); |
|
|
|
|
|
if(res->bufused)send_ssl_socket(res->ssl, res->outputbuffer, len); |
|
593 |
|
|
594 |
} else { |
get_date(date, STRLEN); |
595 |
|
get_server(server, STRLEN); |
|
FILE *out= res->outputstream; |
|
596 |
|
|
597 |
fprintf(out, "%s %d %s\r\n", res->protocol, res->status, |
socket_print(S, "%s %d %s\r\n", res->protocol, res->status, |
598 |
res->status_msg); |
res->status_msg); |
599 |
fprintf(out, "Date: %s\r\n", date); |
socket_print(S, "Date: %s\r\n", date); |
600 |
fprintf(out, "Server: %s\r\n", server); |
socket_print(S, "Server: %s\r\n", server); |
601 |
fprintf(out, "Content-length: %d\r\n", len); |
socket_print(S, "Content-length: %d\r\n", res->bufused); |
602 |
fprintf(out, "Connection: close\r\n"); |
socket_print(S, "Connection: close\r\n"); |
603 |
if(headers)fprintf(out, "%s", headers); |
if(headers) |
604 |
fprintf(out, "\r\n\r\n"); |
socket_print(S, "%s", headers); |
605 |
|
socket_print(S, "\r\n\r\n"); |
|
if(res->bufused)fprintf(out, "%s", res->outputbuffer); |
|
606 |
|
|
607 |
} |
if(res->bufused) |
608 |
|
socket_write(S, res->outputbuffer, res->bufused); |
609 |
|
|
610 |
free(headers); |
free(headers); |
|
free(date); |
|
|
free(server); |
|
611 |
|
|
612 |
} |
} |
613 |
|
|
620 |
/** |
/** |
621 |
* Returns a new HttpRequest object wrapping the client request |
* Returns a new HttpRequest object wrapping the client request |
622 |
*/ |
*/ |
623 |
static HttpRequest create_HttpRequest(RequestWrapper W) { |
static HttpRequest create_HttpRequest(Socket_T S) { |
624 |
|
|
625 |
char line[REQ_STRLEN]; |
HttpRequest req; |
626 |
char method[STRLEN]; |
char method[STRLEN]; |
627 |
char url[REQ_STRLEN]; |
char url[REQ_STRLEN]; |
628 |
|
char line[REQ_STRLEN]; |
629 |
char protocol[STRLEN]; |
char protocol[STRLEN]; |
|
HttpRequest req; |
|
|
FILE *in= NULL; |
|
|
|
|
|
if(Run.httpdssl) { |
|
|
|
|
|
if(gets_ssl_socket(W->ssl, line, sizeof(line)) == NULL) { |
|
|
|
|
|
internal_error_ssl(W->ssl, SC_BAD_REQUEST, "No request found"); |
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
if(sscanf(line, "%s %s HTTP/%3[1.0]", method, url, protocol) != 3) { |
|
|
|
|
|
internal_error_ssl(W->ssl, SC_BAD_REQUEST, "Cannot parse request"); |
|
|
return NULL; |
|
|
|
|
|
} |
|
630 |
|
|
|
} else { |
|
|
|
|
|
in= fdopen(dup(W->socket), "r"); |
|
|
|
|
|
if(in == NULL) { |
|
|
|
|
|
internal_error(W->socket, SC_INTERNAL_SERVER_ERROR, |
|
|
"Cannot create inputstream"); |
|
|
return NULL; |
|
|
|
|
|
} else { |
|
|
setvbuf(in, NULL, _IONBF, 0); |
|
|
} |
|
631 |
|
|
632 |
if(fgets(line, sizeof(line), in) == NULL) { |
if(socket_readln(S, line, REQ_STRLEN) == NULL) { |
633 |
|
internal_error(S, SC_BAD_REQUEST, "No request found"); |
634 |
internal_error(W->socket, SC_BAD_REQUEST, "No request found"); |
return NULL; |
635 |
fclose(in); |
} |
636 |
return NULL; |
|
637 |
|
if(sscanf(line, "%s %s HTTP/%3[1.0]", method, url, protocol) != 3) { |
638 |
} |
internal_error(S, SC_BAD_REQUEST, "Cannot parse request"); |
639 |
|
return NULL; |
640 |
if(sscanf(line, "%s %s HTTP/%3[1.0]", method, url, protocol) != 3) { |
} |
641 |
|
|
642 |
internal_error(W->socket, SC_BAD_REQUEST, "Cannot parse request"); |
if(strlen(url) >= MAX_URL_LENGTH) { |
643 |
fclose(in); |
internal_error(S, SC_BAD_REQUEST, "[error] URL too long"); |
644 |
return NULL; |
return NULL; |
|
|
|
|
} |
|
645 |
} |
} |
646 |
|
|
647 |
NEW(req); |
NEW(req); |
648 |
unescape_url(url); |
req->S= S; |
649 |
chomp(protocol); |
chomp(protocol); |
650 |
req->method= xstrdup(method); |
unescape_url(url); |
651 |
req->url= xstrdup(url); |
req->url= xstrdup(url); |
652 |
|
req->method= xstrdup(method); |
653 |
req->protocol= xstrdup(protocol); |
req->protocol= xstrdup(protocol); |
|
req->ssl= W->ssl; |
|
|
|
|
|
if (! Run.httpdssl) { |
|
|
|
|
|
req->inputstream= in; |
|
|
|
|
|
} else { |
|
|
|
|
|
req->inputstream= NULL; |
|
|
|
|
|
} |
|
|
|
|
|
req->inetaddr= W->inetaddr; |
|
654 |
|
|
655 |
create_headers(req); |
create_headers(req); |
656 |
|
|
657 |
if(!create_parameters(req)) { |
if(!create_parameters(req)) { |
658 |
|
|
659 |
if(Run.httpdssl) { |
internal_error(S, SC_BAD_REQUEST, "Cannot parse Request parameters"); |
660 |
|
destroy_HttpRequest(req); |
|
internal_error_ssl(W->ssl, SC_BAD_REQUEST, |
|
|
"Cannot parse Request parameters"); |
|
|
|
|
|
} else { |
|
|
|
|
|
internal_error(W->socket, SC_BAD_REQUEST, |
|
|
"Cannot parse Request parameters"); |
|
|
fclose(in); |
|
|
|
|
|
} |
|
661 |
|
|
662 |
return NULL; |
return NULL; |
663 |
|
|
672 |
* Returns a new HttpResponse object wrapping a default response. Use |
* Returns a new HttpResponse object wrapping a default response. Use |
673 |
* set_XXX methods to change the object. |
* set_XXX methods to change the object. |
674 |
*/ |
*/ |
675 |
static HttpResponse create_HttpResponse(RequestWrapper W) { |
static HttpResponse create_HttpResponse(Socket_T S) { |
676 |
|
|
677 |
HttpResponse res; |
HttpResponse res; |
|
FILE *out= NULL; |
|
678 |
|
|
|
if(! Run.httpdssl) { |
|
|
|
|
|
out = fdopen(dup(W->socket), "w"); |
|
|
if(out == NULL) { |
|
|
|
|
|
internal_error(W->socket, SC_INTERNAL_SERVER_ERROR, |
|
|
"Cannot create outputstream"); |
|
|
|
|
|
return NULL; |
|
|
} else { |
|
|
setvbuf(out, NULL, _IONBF, 0); |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
679 |
NEW(res); |
NEW(res); |
680 |
res->protocol= xstrdup(SERVER_PROTOCOL); |
res->S= S; |
|
res->status= 200; |
|
|
res->status_msg= get_status_string(SC_OK); |
|
|
res->outputstream= out; |
|
|
res->outputbuffer= NULL; |
|
681 |
res->bufsize= 0; |
res->bufsize= 0; |
682 |
res->bufused= 0; |
res->bufused= 0; |
683 |
|
res->status= 200; |
684 |
|
res->outputbuffer= NULL; |
685 |
res->is_committed= FALSE; |
res->is_committed= FALSE; |
686 |
res->ssl= W->ssl; |
res->protocol= SERVER_PROTOCOL; |
687 |
|
res->status_msg= get_status_string(SC_OK); |
688 |
|
|
689 |
return res; |
return res; |
690 |
|
|
696 |
*/ |
*/ |
697 |
static void create_headers(HttpRequest req) { |
static void create_headers(HttpRequest req) { |
698 |
|
|
699 |
char line[REQ_STRLEN]; |
Socket_T S; |
700 |
char *value; |
char *value; |
701 |
HttpHeader p; |
HttpHeader p; |
702 |
HttpHeader header; |
HttpHeader header; |
703 |
|
char line[REQ_STRLEN]; |
704 |
|
|
705 |
|
S= req->S; |
706 |
|
|
707 |
while(1) { |
while(1) { |
708 |
|
|
709 |
if(Run.httpdssl) { |
if(! socket_readln(S, line, sizeof(line))) |
|
|
|
|
if (NULL == gets_ssl_socket(req->ssl, line, sizeof(line))) { |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
if (NULL == fgets(line, sizeof(line), req->inputstream)) { |
|
|
|
|
710 |
break; |
break; |
711 |
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
712 |
if(!strcmp(line, "\r\n") || !strcmp(line, "\n")) |
if(!strcmp(line, "\r\n") || !strcmp(line, "\n")) |
713 |
break; |
break; |
714 |
|
|
747 |
*/ |
*/ |
748 |
static int create_parameters(HttpRequest req) { |
static int create_parameters(HttpRequest req) { |
749 |
|
|
|
char *query_string= NULL; |
|
750 |
int alloc= FALSE; |
int alloc= FALSE; |
751 |
|
char *query_string= NULL; |
752 |
|
|
753 |
if(!strcmp(req->method, METHOD_POST)) { |
if(!strcmp(req->method, METHOD_POST)) { |
754 |
|
|
755 |
|
Socket_T S= req->S; |
756 |
|
|
757 |
int len; char *l= get_header(req, "Content-Length"); |
int len; char *l= get_header(req, "Content-Length"); |
758 |
|
|
760 |
|
|
761 |
query_string= xmalloc(sizeof(char) * (len + 1)); |
query_string= xmalloc(sizeof(char) * (len + 1)); |
762 |
|
|
763 |
if(fgets(query_string, (sizeof(char)*(len+1)), |
if(socket_read(S, query_string, len) <= 0) { |
|
req->inputstream) == NULL) { |
|
764 |
|
|
765 |
free(query_string); |
free(query_string); |
766 |
return FALSE; |
return FALSE; |
840 |
|
|
841 |
if(req) { |
if(req) { |
842 |
|
|
|
if(req->inputstream)fclose(req->inputstream); |
|
843 |
free(req->method); |
free(req->method); |
844 |
free(req->url); /* req->pathinfo is freed with url */ |
free(req->url); /* req->pathinfo is freed with url */ |
845 |
free(req->protocol); |
free(req->protocol); |
859 |
|
|
860 |
if(res) { |
if(res) { |
861 |
|
|
|
if(res->outputstream)fclose(res->outputstream); |
|
|
free(res->protocol); |
|
862 |
free(res->outputbuffer); |
free(res->outputbuffer); |
863 |
if(res->headers) destroy_entry(res->headers); |
if(res->headers) destroy_entry(res->headers); |
864 |
free(res); |
free(res); |
945 |
} else { |
} else { |
946 |
|
|
947 |
log("Warning: Client '%s' supplied wrong credentials" |
log("Warning: Client '%s' supplied wrong credentials" |
948 |
" accessing monit httpd\n", req->inetaddr->remote_host); |
" accessing monit httpd\n", socket_get_remote_host(req->S)); |
949 |
|
|
950 |
} |
} |
951 |
|
|
969 |
* used internal if the service function fails to setup the framework |
* used internal if the service function fails to setup the framework |
970 |
* properly; i.e. with a valid HttpRequest and a valid HttpResponse. |
* properly; i.e. with a valid HttpRequest and a valid HttpResponse. |
971 |
*/ |
*/ |
972 |
static void internal_error(int client, int status, char *msg) { |
static void internal_error(Socket_T S, int status, char *msg) { |
|
|
|
|
char response[RES_STRLEN]; |
|
|
char *server= get_server(); |
|
|
char *date= get_date(); |
|
|
const char *status_msg= get_status_string(status); |
|
|
|
|
|
snprintf(response, RES_STRLEN, |
|
|
"%s %d %s\r\n" |
|
|
"Date: %s\r\n" |
|
|
"Server: %s\r\n" |
|
|
"Content-Type: text/html\r\n" |
|
|
"Connection: close\r\n" |
|
|
"\r\n" |
|
|
"<html><head><title>%s</title></head>" |
|
|
"<body bgcolor=#FFFFFF><h2>%s</h2>%s<p>" |
|
|
"<hr><a href='%s'><font size=-1>%s</font></a>" |
|
|
"</body></html>\r\n", |
|
|
SERVER_PROTOCOL, status, status_msg, date, server, |
|
|
status_msg, status_msg, msg, SERVER_URL, server); |
|
|
sock_write(client, response, strlen(response)); |
|
|
free(server); |
|
|
free(date); |
|
973 |
|
|
974 |
} |
char date[STRLEN]; |
975 |
|
char server[STRLEN]; |
|
static void internal_error_ssl(ssl_connection *ssl, int status, char *msg) { |
|
|
|
|
|
char response[RES_STRLEN]; |
|
|
char *server= get_server(); |
|
|
char *date= get_date(); |
|
976 |
const char *status_msg= get_status_string(status); |
const char *status_msg= get_status_string(status); |
977 |
|
|
978 |
snprintf(response, RES_STRLEN, |
get_date(date, STRLEN); |
979 |
"%s %d %s\r\n" |
get_server(server, STRLEN); |
980 |
"Date: %s\r\n" |
|
981 |
"Server: %s\r\n" |
socket_print(S, |
982 |
"Content-Type: text/html\r\n" |
"%s %d %s\r\n" |
983 |
"Connection: close\r\n" |
"Date: %s\r\n" |
984 |
"\r\n" |
"Server: %s\r\n" |
985 |
"<html><head><title>%s</title></head>" |
"Content-Type: text/html\r\n" |
986 |
"<body bgcolor=#FFFFFF><h2>%s</h2>%s<p>" |
"Connection: close\r\n" |
987 |
"<hr><a href='%s'><font size=-1>%s</font></a>" |
"\r\n" |
988 |
"</body></html>\r\n", |
"<html><head><title>%s</title></head>" |
989 |
SERVER_PROTOCOL, status, status_msg, date, server, |
"<body bgcolor=#FFFFFF><h2>%s</h2>%s<p>" |
990 |
status_msg, status_msg, msg, SERVER_URL, server); |
"<hr><a href='%s'><font size=-1>%s</font></a>" |
991 |
|
"</body></html>\r\n", |
992 |
send_ssl_socket(ssl, response, strlen(response)); |
SERVER_PROTOCOL, status, status_msg, date, server, |
993 |
free(server); |
status_msg, status_msg, msg, SERVER_URL, server); |
|
free(date); |
|
994 |
|
|
995 |
} |
} |
996 |
|
|
1001 |
*/ |
*/ |
1002 |
static HttpParameter parse_parameters(char *query_string) { |
static HttpParameter parse_parameters(char *query_string) { |
1003 |
|
|
|
HttpParameter head= NULL; |
|
1004 |
int controller= 1000; |
int controller= 1000; |
1005 |
|
HttpParameter head= NULL; |
1006 |
|
|
1007 |
while(query_string[0] && controller--) { |
while(query_string[0] && controller--) { |
1008 |
|
|
1009 |
HttpParameter p; |
HttpParameter p; |