00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <stdarg.h>
00025 #include <errno.h>
00026
00027 #ifdef HAVE_SYS_TYPES_H
00028 #include <sys/types.h>
00029 #endif
00030
00031 #include <sys/socket.h>
00032 #include <time.h>
00033 #include <setjmp.h>
00034
00035 #ifdef HAVE_STRING_H
00036 #include <string.h>
00037 #endif
00038
00039 #ifdef HAVE_UNISTD_H
00040 #include <unistd.h>
00041 #endif
00042
00043 #ifdef HAVE_LIMITS_H
00044 #include <limits.h>
00045 #endif
00046
00047 #include "processor.h"
00048 #include "base64.h"
00049 #include "ssl.h"
00050
00051 #define REQUEST 1
00052 #define RESPONSE 2
00053 #define HEADER 3
00054 #define PARAM 4
00055
00056
00057 extern ssl_server_connection * mySSLServerConnection;
00058
00059
00060 static void do_service(RequestWrapper);
00061 static void send_response(HttpResponse);
00062 static char *get_date();
00063 static char *get_server();
00064 static HttpRequest create_HttpRequest(RequestWrapper);
00065 static HttpResponse create_HttpResponse(RequestWrapper);
00066 static void create_headers(HttpRequest);
00067 static int create_parameters(HttpRequest req);
00068 static void reset_response(HttpResponse res);
00069 static int is_authenticated(HttpRequest, HttpResponse);
00070 static int basic_authenticate(HttpRequest);
00071 static void done(HttpRequest, HttpResponse);
00072 static void destroy_HttpRequest(HttpRequest);
00073 static void destroy_HttpResponse(HttpResponse);
00074 static void destroy_entry(void *);
00075 static void internal_error(int, int, char *);
00076 static void internal_error_ssl(ssl_connection *, int, char *);
00077 static HttpParameter parse_parameters(char *);
00078 static int is_available(int);
00079
00080
00114
00115
00116
00123 void *http_processor(void *wrapper) {
00124
00125 RequestWrapper W= wrapper;
00126
00127 if(! is_available(W->socket)) {
00128
00129 internal_error(W->socket, SC_REQUEST_TIMEOUT,
00130 "Time out when handling the Request");
00131 goto shutdown;
00132
00133 }
00134 do_service(W);
00135
00136 shutdown:
00137 destroy_wrapper(W);
00138
00139 return NULL;
00140
00141 }
00142
00143
00149 void add_Impl(void *doGetFunc, void *doPostFunc) {
00150
00151 Impl.doGet= doGetFunc;
00152 Impl.doPost= doPostFunc;
00153
00154 }
00155
00156
00157
00158
00159
00166 void send_error(HttpResponse res, int code, char *msg) {
00167
00168 char *err= get_status_string(code);
00169 char *server= get_server();
00170
00171 reset_response(res);
00172 set_content_type(res, "text/html");
00173 set_status(res, code, err);
00174 out_print(res,
00175 "<html><head><title>%d %s</title></head>"\
00176 "<body bgcolor=#FFFFFF><h2>%s</h2>%s<p>"\
00177 "<hr><a href='%s'><font size=-1>%s</font></a>"\
00178 "</body></html>\r\n",
00179 code, err, err, msg?msg:"", SERVER_URL, server);
00180 free(err);
00181 free(server);
00182
00183 }
00184
00185
00192 void send_redirect(HttpResponse res, char *location) {
00193
00194 char *string= get_status_string(SC_MOVED_TEMPORARILY);
00195 reset_response(res);
00196 set_status(res, SC_MOVED_TEMPORARILY, string);
00197 set_header(res, "Location", location);
00198 free(string);
00199
00200 }
00201
00202
00217 void out_print(HttpResponse res, const char *format, ...) {
00218
00219 if ( format ) {
00220
00221 int n= 0;
00222 ssize_t need= 0;
00223 ssize_t have= 0;
00224 int size= RES_STRLEN;
00225 char *string= xmalloc(size);
00226 va_list ap;
00227
00228
00229 while (1) {
00230
00231 va_start(ap, format);
00232 n= vsnprintf(string, size, format, ap);
00233 va_end(ap);
00234
00235 if (n > -1 && n < size) {
00236
00237 break;
00238
00239 }
00240
00241 if (n > -1) {
00242
00243 size= n+1;
00244
00245 } else {
00246
00247 size*= 2;
00248
00249 }
00250
00251 string= xresize(string, size);
00252
00253 }
00254
00255
00256 if ( (float)((float)(sizeof(char)*(res->bufsize + RES_STRLEN + n + 1))
00257 > SSIZE_MAX) ) {
00258
00259 log("out_print: Possible http response buffer overflow detected. "
00260 "aborting \n");
00261 exit(1);
00262
00263 }
00264
00265 have= res->bufsize - res->bufused;
00266 need= sizeof(char)*( n + 1);
00267
00268 if ( have <= need ) {
00269
00270
00271 res->outputbuffer=
00272 xresize(res->outputbuffer,(res->bufsize + need + RES_STRLEN));
00273
00274 res->bufsize+= (need + RES_STRLEN);
00275
00276 if ( !res->bufused ) {
00277
00278 memset(res->outputbuffer, 0, res->bufsize);
00279
00280 }
00281
00282 res->bufused+= need;
00283
00284 } else {
00285
00286 res->bufused+= need;
00287
00288 }
00289
00290 strcat(res->outputbuffer, string);
00291
00292 free(string);
00293
00294 }
00295
00296 }
00297
00298
00303 void destroy_wrapper(RequestWrapper w) {
00304
00305 if ( w && w->inetaddr ) {
00306
00307 free(w->inetaddr->remote_host);
00308 free(w->inetaddr->local_host);
00309 free(w->inetaddr);
00310
00311 }
00312
00313 if ( Run.httpdssl ) {
00314
00315 close_accepted_ssl_socket(mySSLServerConnection, w->ssl);
00316
00317 } else {
00318
00319 close_socket(w->socket);
00320
00321 }
00322
00323 free(w);
00324
00325 }
00326
00327
00328
00329
00330
00338 void set_header(HttpResponse res, char *name, char *value) {
00339
00340 HttpHeader h= NEW(h);
00341
00342 h->name= xstrdup(name);
00343 h->value= xstrdup(value);
00344
00345 if ( res->headers ) {
00346
00347 HttpHeader n, p;
00348
00349 for ( n= p= res->headers; p; n= p, p= p->next) {
00350
00351 if ( !strcasecmp(p->name, name) ) {
00352
00353 free(p->value);
00354 p->value= xstrdup(value);
00355 destroy_entry(h);
00356 return;
00357
00358 }
00359
00360 }
00361
00362 n->next= h;
00363
00364 } else {
00365
00366 res->headers= h;
00367
00368 }
00369
00370 }
00371
00372
00379 void set_status(HttpResponse res, int code, char *msg) {
00380
00381 res->status= code;
00382 free(res->status_msg);
00383 res->status_msg= xstrdup(msg);
00384
00385 }
00386
00387
00393 void set_content_type(HttpResponse res, char *mime) {
00394
00395 set_header(res, "Content-Type", mime);
00396
00397 }
00398
00399
00406 char *get_header(HttpRequest req, const char *name) {
00407
00408 HttpHeader p;
00409
00410 for ( p= req->headers; p; p= p->next) {
00411
00412 if ( !strcasecmp(p->name, name) ) {
00413
00414 return xstrdup(p->value);
00415
00416 }
00417
00418 }
00419
00420 return NULL;
00421
00422 }
00423
00424
00431 char *get_parameter(HttpRequest req, const char *name) {
00432
00433 HttpParameter p;
00434
00435 for ( p= req->params; p; p= p->next) {
00436
00437 if ( !strcasecmp(p->name, name) ) {
00438
00439 return xstrdup(p->value);
00440
00441 }
00442
00443 }
00444
00445 return NULL;
00446
00447 }
00448
00449
00457 char *get_headers(HttpResponse res) {
00458
00459 HttpHeader p;
00460 char buf[RES_STRLEN];
00461 char *b= buf;
00462
00463 for ( p= res->headers; p; p= p->next) {
00464
00465 b+= sprintf(b, "%s: %s\r\n", p->name, p->value);
00466
00467 }
00468
00469 return buf[0]?xstrdup(buf):NULL;
00470
00471 }
00472
00473
00481 char *get_status_string(int status) {
00482
00483 switch (status) {
00484 case SC_OK:
00485 return xstrdup("OK");
00486 case SC_ACCEPTED:
00487 return xstrdup("Accepted");
00488 case SC_BAD_GATEWAY:
00489 return xstrdup("Bad Gateway");
00490 case SC_BAD_REQUEST:
00491 return xstrdup("Bad Request");
00492 case SC_CONFLICT:
00493 return xstrdup("Conflict");
00494 case SC_CONTINUE:
00495 return xstrdup("Continue");
00496 case SC_CREATED:
00497 return xstrdup("Created");
00498 case SC_EXPECTATION_FAILED:
00499 return xstrdup("Expectation Failed");
00500 case SC_FORBIDDEN:
00501 return xstrdup("Forbidden");
00502 case SC_GATEWAY_TIMEOUT:
00503 return xstrdup("Gateway Timeout");
00504 case SC_GONE:
00505 return xstrdup("Gone");
00506 case SC_VERSION_NOT_SUPPORTED:
00507 return xstrdup("HTTP Version Not Supported");
00508 case SC_INTERNAL_SERVER_ERROR:
00509 return xstrdup("Internal Server Error");
00510 case SC_LENGTH_REQUIRED:
00511 return xstrdup("Length Required");
00512 case SC_METHOD_NOT_ALLOWED:
00513 return xstrdup("Method Not Allowed");
00514 case SC_MOVED_PERMANENTLY:
00515 return xstrdup("Moved Permanently");
00516 case SC_MOVED_TEMPORARILY:
00517 return xstrdup("Moved Temporarily");
00518 case SC_MULTIPLE_CHOICES:
00519 return xstrdup("Multiple Choices");
00520 case SC_NO_CONTENT:
00521 return xstrdup("No Content");
00522 case SC_NON_AUTHORITATIVE:
00523 return xstrdup("Non-Authoritative Information");
00524 case SC_NOT_ACCEPTABLE:
00525 return xstrdup("Not Acceptable");
00526 case SC_NOT_FOUND:
00527 return xstrdup("Not Found");
00528 case SC_NOT_IMPLEMENTED:
00529 return xstrdup("Not Implemented");
00530 case SC_NOT_MODIFIED:
00531 return xstrdup("Not Modified");
00532 case SC_PARTIAL_CONTENT:
00533 return xstrdup("Partial Content");
00534 case SC_PAYMENT_REQUIRED:
00535 return xstrdup("Payment Required");
00536 case SC_PRECONDITION_FAILED:
00537 return xstrdup("Precondition Failed");
00538 case SC_PROXY_AUTHENTICATION_REQUIRED:
00539 return xstrdup("Proxy Authentication Required");
00540 case SC_REQUEST_ENTITY_TOO_LARGE:
00541 return xstrdup("Request Entity Too Large");
00542 case SC_REQUEST_TIMEOUT:
00543 return xstrdup("Request Timeout");
00544 case SC_REQUEST_URI_TOO_LARGE:
00545 return xstrdup("Request URI Too Large");
00546 case SC_RANGE_NOT_SATISFIABLE:
00547 return xstrdup("Requested Range Not Satisfiable");
00548 case SC_RESET_CONTENT:
00549 return xstrdup("Reset Content");
00550 case SC_SEE_OTHER:
00551 return xstrdup("See Other");
00552 case SC_SERVICE_UNAVAILABLE:
00553 return xstrdup("Service Unavailable");
00554 case SC_SWITCHING_PROTOCOLS:
00555 return xstrdup("Switching Protocols");
00556 case SC_UNAUTHORIZED:
00557 return xstrdup("Unauthorized");
00558 case SC_UNSUPPORTED_MEDIA_TYPE:
00559 return xstrdup("Unsupported Media Type");
00560 case SC_USE_PROXY:
00561 return xstrdup("Use Proxy");
00562 default: {
00563 char buf[STRLEN];
00564 snprintf(buf, STRLEN, "HTTP Response Status %d", status);
00565 return xstrdup(buf);
00566 }
00567 }
00568
00569 }
00570
00571
00572
00573
00574
00579 static void do_service(RequestWrapper w) {
00580
00581 volatile HttpResponse res= create_HttpResponse(w);
00582 volatile HttpRequest req= create_HttpRequest(w);
00583
00584 if ( res && req ) {
00585
00586 if ( is_authenticated(req, res) ) {
00587
00588 if ( !strcmp(req->method, METHOD_GET) ) {
00589
00590 Impl.doGet(req, res);
00591
00592 }
00593 else if ( !strcmp(req->method, METHOD_POST) ) {
00594
00595 Impl.doPost(req, res);
00596
00597 }
00598 else {
00599
00600 send_error(res, SC_NOT_IMPLEMENTED, "Method not implemented");
00601
00602 }
00603
00604 }
00605
00606 if ( Run.httpdssl ) {
00607
00608 send_response(res);
00609
00610 } else {
00611
00612 if ( check_socket(w->socket) ) {
00613
00614 send_response(res);
00615 }
00616
00617 }
00618
00619 }
00620
00621 done(req, res);
00622
00623 }
00624
00625
00629 static char *get_date() {
00630
00631 char date[STRLEN];
00632 time_t now;
00633
00634 time(&now);
00635
00636 if ( !strftime(date, STRLEN, DATEFMT, gmtime(&now)) ) {
00637
00638 memset(date, 0, STRLEN);
00639
00640 }
00641
00642 return xstrdup(date);
00643
00644 }
00645
00646
00650 static char *get_server() {
00651
00652 char server[STRLEN];
00653 snprintf(server, STRLEN, "%s %s", SERVER_NAME, SERVER_VERSION);
00654
00655 return xstrdup(server);
00656
00657 }
00658
00659
00664 static void send_response(HttpResponse res) {
00665
00666 if ( !res->is_committed ) {
00667 char *date= get_date();
00668 char *server= get_server();
00669 char *headers= get_headers(res);
00670 int len= res->bufused?strlen(res->outputbuffer):0;
00671
00672 if ( Run.httpdssl ) {
00673
00674 printf_ssl_socket(res->ssl, "%s %d %s\r\n", res->protocol, res->status,
00675 res->status_msg);
00676 printf_ssl_socket(res->ssl, "Date: %s\r\n", date);
00677 printf_ssl_socket(res->ssl, "Server: %s\r\n", server);
00678 printf_ssl_socket(res->ssl, "Content-length: %d\r\n", len);
00679 printf_ssl_socket(res->ssl, "Connection: close\r\n");
00680 if ( headers ) printf_ssl_socket(res->ssl, "%s", headers);
00681 printf_ssl_socket(res->ssl, "\r\n\r\n");
00682
00683 if ( res->bufused ) send_ssl_socket(res->ssl, res->outputbuffer, len);
00684
00685 } else {
00686
00687 FILE *out= res->outputstream;
00688
00689 fprintf(out, "%s %d %s\r\n", res->protocol, res->status,
00690 res->status_msg);
00691 fprintf(out, "Date: %s\r\n", date);
00692 fprintf(out, "Server: %s\r\n", server);
00693 fprintf(out, "Content-length: %d\r\n", len);
00694 fprintf(out, "Connection: close\r\n");
00695 if ( headers ) fprintf(out, "%s", headers);
00696 fprintf(out, "\r\n\r\n");
00697
00698 if ( res->bufused ) fprintf(out, "%s", res->outputbuffer);
00699
00700 }
00701
00702 free(headers);
00703 free(date);
00704 free(server);
00705
00706 }
00707
00708 }
00709
00710
00711
00712
00713
00717 static HttpRequest create_HttpRequest(RequestWrapper W) {
00718
00719 char line[REQ_STRLEN];
00720 char method[STRLEN];
00721 char url[REQ_STRLEN];
00722 char protocol[STRLEN];
00723 HttpRequest req;
00724 FILE *in= NULL;
00725
00726 if ( Run.httpdssl ) {
00727
00728 if ( gets_ssl_socket(W->ssl, line, sizeof(line)) == NULL ) {
00729
00730 internal_error_ssl(W->ssl, SC_BAD_REQUEST, "No request found");
00731 return NULL;
00732
00733 }
00734
00735 if ( sscanf(line, "%s %s HTTP/%3[1.0]", method, url, protocol) != 3 ) {
00736
00737 internal_error_ssl(W->ssl, SC_BAD_REQUEST, "Cannot parse request");
00738 return NULL;
00739
00740 }
00741
00742 } else {
00743
00744 in= fdopen(dup(W->socket), "r");
00745
00746 if ( in == NULL ) {
00747
00748 internal_error(W->socket, SC_INTERNAL_SERVER_ERROR,
00749 "Cannot create inputstream");
00750 return NULL;
00751
00752 }
00753
00754 if ( fgets(line, sizeof(line), in) == NULL ) {
00755
00756 internal_error(W->socket, SC_BAD_REQUEST, "No request found");
00757 fclose(in);
00758 return NULL;
00759
00760 }
00761
00762 if ( sscanf(line, "%s %s HTTP/%3[1.0]", method, url, protocol) != 3 ) {
00763
00764 internal_error(W->socket, SC_BAD_REQUEST, "Cannot parse request");
00765 fclose(in);
00766 return NULL;
00767
00768 }
00769 }
00770
00771 req= NEW(req);
00772 unescape_url(url);
00773 chomp(protocol);
00774 req->method= xstrdup(method);
00775 req->url= xstrdup(url);
00776 req->protocol= xstrdup(protocol);
00777 req->ssl= W->ssl;
00778
00779 if (! Run.httpdssl ) {
00780
00781 req->inputstream= in;
00782
00783 } else {
00784
00785 req->inputstream= NULL;
00786
00787 }
00788
00789 req->inetaddr= W->inetaddr;
00790
00791 create_headers(req);
00792
00793 if ( !create_parameters(req) ) {
00794
00795 if ( Run.httpdssl ) {
00796
00797 internal_error_ssl(W->ssl, SC_BAD_REQUEST,
00798 "Cannot parse Request parameters");
00799
00800 } else {
00801
00802 internal_error(W->socket, SC_BAD_REQUEST,
00803 "Cannot parse Request parameters");
00804 fclose(in);
00805
00806 }
00807
00808 return NULL;
00809
00810 }
00811
00812 return req;
00813
00814 }
00815
00816
00821 static HttpResponse create_HttpResponse(RequestWrapper W) {
00822
00823 HttpResponse res;
00824 FILE *out= NULL;
00825
00826 if ( ! Run.httpdssl ) {
00827
00828 out = fdopen(dup(W->socket), "w");
00829
00830 if ( out == NULL ) {
00831
00832 internal_error(W->socket, SC_INTERNAL_SERVER_ERROR,
00833 "Cannot create outputstream");
00834
00835 return NULL;
00836 }
00837
00838 }
00839
00840 res= NEW(res);
00841 res->protocol= xstrdup(SERVER_PROTOCOL);
00842 res->status= 200;
00843 res->status_msg= get_status_string(SC_OK);
00844 res->outputstream= out;
00845 res->outputbuffer= NULL;
00846 res->bufsize= 0;
00847 res->bufused= 0;
00848 res->is_committed= FALSE;
00849 res->ssl= W->ssl;
00850
00851 return res;
00852
00853 }
00854
00855
00859 static void create_headers(HttpRequest req) {
00860
00861 char line[REQ_STRLEN];
00862 char *value;
00863 HttpHeader p;
00864 HttpHeader header;
00865
00866 while ( 1 ) {
00867
00868 if ( Run.httpdssl ) {
00869
00870 if (NULL == gets_ssl_socket(req->ssl, line, sizeof(line))) {
00871
00872 break;
00873
00874 }
00875
00876 } else {
00877
00878 if (NULL == fgets(line, sizeof(line), req->inputstream)) {
00879
00880 break;
00881
00882 }
00883
00884 }
00885
00886 if ( !strcmp(line, "\r\n") || !strcmp(line, "\n") )
00887 break;
00888
00889 if( NULL != (value= strchr(line, ':')) ) {
00890
00891 header= NEW(header);
00892 *value++= '\0';
00893 trim(line);
00894 trim(value);
00895 chomp(value);
00896 header->name= xstrdup(line);
00897 header->value= xstrdup(value);
00898
00899 if ( req->headers ) {
00900
00901 for ( p= req->headers; p->next; p= p->next)
00902 ;
00903 p->next= header;
00904
00905 } else {
00906
00907 req->headers= header;
00908
00909 }
00910
00911 }
00912
00913 }
00914
00915 }
00916
00917
00922 static int create_parameters(HttpRequest req) {
00923
00924 char *query_string= NULL;
00925 int alloc= FALSE;
00926
00927 if ( !strcmp(req->method, METHOD_POST) ) {
00928
00929 int len; char *l= get_header(req, "Content-Length");
00930
00931 if ( l && (len= atoi(l)) ) {
00932
00933 query_string= xmalloc(sizeof(char) * (len + 1));
00934
00935 if ( fgets(query_string, (sizeof(char)*(len+1)),
00936 req->inputstream) == NULL ) {
00937
00938 free(query_string);
00939 return FALSE;
00940
00941 }
00942
00943 alloc= TRUE;
00944
00945 }
00946
00947 } else if ( !strcmp(req->method, METHOD_GET) ) {
00948
00949 char *p;
00950
00951 if( NULL != (p= strchr(req->url, '?')) ) {
00952
00953 *p++= '\0';
00954 query_string= p;
00955
00956 }
00957
00958 }
00959
00960 if ( query_string ) {
00961
00962 char *p;
00963
00964 if( NULL != (p= strchr(query_string, '/')) ) {
00965
00966 *p++= '\0';
00967 req->pathinfo= p;
00968
00969 }
00970
00971 req->params= parse_parameters(query_string);
00972
00973 }
00974
00975 if ( alloc ) free(query_string);
00976
00977 return TRUE;
00978
00979 }
00980
00981
00982
00983
00984
00985
00989 static void reset_response(HttpResponse res) {
00990
00991 if ( res->headers ) destroy_entry(res->headers);
00992 memset(res->outputbuffer, 0, res->bufsize);
00993 res->headers= NULL;
00994
00995 }
00996
00997
01001 static void done(HttpRequest req, HttpResponse res) {
01002
01003 destroy_HttpRequest(req);
01004 destroy_HttpResponse(res);
01005
01006 }
01007
01008
01012 static void destroy_HttpRequest(HttpRequest req) {
01013
01014 if ( req ) {
01015
01016 if ( req->inputstream ) fclose(req->inputstream);
01017 free(req->method);
01018 free(req->url);
01019 free(req->protocol);
01020 if ( req->headers ) destroy_entry(req->headers);
01021 if ( req->params ) destroy_entry(req->params);
01022 free(req);
01023
01024 }
01025
01026 }
01027
01028
01032 static void destroy_HttpResponse(HttpResponse res) {
01033
01034 if ( res ) {
01035
01036 if ( res->outputstream ) fclose(res->outputstream);
01037 free(res->protocol);
01038 free(res->status_msg);
01039 free(res->outputbuffer);
01040 if ( res->headers) destroy_entry(res->headers);
01041 free(res);
01042
01043 }
01044
01045 }
01046
01047
01052 static void destroy_entry(void *p) {
01053
01054 struct entry *h= p;
01055
01056 if ( h->next ) {
01057
01058 destroy_entry(h->next);
01059
01060 }
01061
01062 free(h->name);
01063 free(h->value);
01064 free(h);
01065
01066 }
01067
01068
01069
01070
01071
01075 static int is_authenticated(HttpRequest req, HttpResponse res) {
01076
01077 if ( Run.Auth.defined ) {
01078
01079 if ( ! basic_authenticate(req) ) {
01080
01081 send_error(res, SC_UNAUTHORIZED,
01082 "You are <b>not</b> authorized to access <i>monit</i>. "
01083 "Either you supplied the wrong credentials (e.g. bad "
01084 "password), or your browser doesn't understand how to supply "
01085 "the credentials required");
01086 set_header(res, "WWW-Authenticate", "Basic realm=\"monit\"");
01087
01088 return FALSE;
01089
01090 }
01091
01092 }
01093
01094 return TRUE;
01095
01096 }
01097
01098
01103 static int basic_authenticate(HttpRequest req) {
01104
01105 int rv= FALSE;
01106 char *credentials= get_header(req, "Authorization");
01107
01108 if ( credentials ) {
01109
01110 unsigned char *cr= xcalloc(sizeof(unsigned char), strlen(credentials)+1);
01111
01112 if ( decode_base64(cr, strchr(credentials, ' ')) ) {
01113
01114 char buf[STRLEN];
01115
01116 snprintf(buf, STRLEN, "%s:%s", Run.Auth.uname, Run.Auth.passwd);
01117
01118 if ( !strncmp(cr, buf, strlen(buf)) ) {
01119
01120 rv= TRUE;
01121
01122 }
01123
01124 }
01125
01126 free(cr);
01127 free(credentials);
01128
01129 }
01130
01131 return rv;
01132
01133 }
01134
01135
01136
01137
01138
01144 static void internal_error(int client, int status, char *msg) {
01145
01146 char response[RES_STRLEN];
01147 char *server= get_server();
01148 char *date= get_date();
01149 char *status_msg= get_status_string(status);
01150
01151 snprintf(response, RES_STRLEN,
01152 "%s %d %s\r\n"
01153 "Date: %s\r\n"
01154 "Server: %s\r\n"
01155 "Content-Type: text/html\r\n"
01156 "Connection: close\r\n"
01157 "\r\n"
01158 "<html><head><title>%s</title></head>"
01159 "<body bgcolor=#FFFFFF><h2>%s</h2>%s<p>"
01160 "<hr><a href='%s'><font size=-1>%s</font></a>"
01161 "</body></html>\r\n",
01162 SERVER_PROTOCOL, status, status_msg, date, server,
01163 status_msg, status_msg, msg, SERVER_URL, server);
01164 sock_send(client, response, strlen(response), 0);
01165 free(server);
01166 free(date);
01167 free(status_msg);
01168
01169 }
01170
01171 static void internal_error_ssl(ssl_connection *ssl, int status, char *msg) {
01172
01173 char response[RES_STRLEN];
01174 char *server= get_server();
01175 char *date= get_date();
01176 char *status_msg= get_status_string(status);
01177
01178 snprintf(response, RES_STRLEN,
01179 "%s %d %s\r\n"
01180 "Date: %s\r\n"
01181 "Server: %s\r\n"
01182 "Content-Type: text/html\r\n"
01183 "Connection: close\r\n"
01184 "\r\n"
01185 "<html><head><title>%s</title></head>"
01186 "<body bgcolor=#FFFFFF><h2>%s</h2>%s<p>"
01187 "<hr><a href='%s'><font size=-1>%s</font></a>"
01188 "</body></html>\r\n",
01189 SERVER_PROTOCOL, status, status_msg, date, server,
01190 status_msg, status_msg, msg, SERVER_URL, server);
01191
01192 send_ssl_socket(ssl, response, strlen(response));
01193 free(server);
01194 free(date);
01195 free(status_msg);
01196
01197 }
01198
01199
01204 static HttpParameter parse_parameters(char *query_string) {
01205
01206 HttpParameter head= NULL;
01207 int controller= 1000;
01208
01209 while ( query_string[0] && controller-- ) {
01210
01211 HttpParameter p= NEW(p);
01212 p->value= makeword(query_string,'&');
01213 p->name= makeword(p->value,'=');
01214 plustospace(p->value);
01215 unescape_url(p->value);
01216 plustospace(p->name);
01217 unescape_url(p->name);
01218 p->next= head;
01219 head= p;
01220
01221 }
01222
01223 return head;
01224
01225 }
01226
01227
01234 static int is_available(int s) {
01235
01236 fd_set rset;
01237 struct timeval tv;
01238
01239 if(s < 0)
01240 return FALSE;
01241
01242 FD_ZERO(&rset);
01243 FD_SET(s, &rset);
01244 tv.tv_sec= REQUEST_TIMEOUT;
01245 tv.tv_usec= 0;
01246
01247 return (select(s+1, &rset, NULL, NULL, &tv)>0);
01248
01249 }
01250