46 |
|
|
47 |
#include "processor.h" |
#include "processor.h" |
48 |
#include "base64.h" |
#include "base64.h" |
49 |
|
#include "ssl.h" |
50 |
|
|
51 |
#define REQUEST 1 |
#define REQUEST 1 |
52 |
#define RESPONSE 2 |
#define RESPONSE 2 |
53 |
#define HEADER 3 |
#define HEADER 3 |
54 |
#define PARAM 4 |
#define PARAM 4 |
55 |
|
|
56 |
|
/* Private variables */ |
57 |
|
extern ssl_server_connection * mySSLServerConnection; |
58 |
|
|
59 |
/* Private prototypes */ |
/* Private prototypes */ |
60 |
static void do_service(RequestWrapper); |
static void do_service(RequestWrapper); |
73 |
static void destroy_HttpResponse(HttpResponse); |
static void destroy_HttpResponse(HttpResponse); |
74 |
static void destroy_entry(void *); |
static void destroy_entry(void *); |
75 |
static void internal_error(int, int, char *); |
static void internal_error(int, int, char *); |
76 |
|
static void internal_error_ssl(ssl_connection *, int, char *); |
77 |
static HttpParameter parse_parameters(char *); |
static HttpParameter parse_parameters(char *); |
78 |
static int is_available(int); |
static int is_available(int); |
79 |
|
|
130 |
goto shutdown; |
goto shutdown; |
131 |
|
|
132 |
} |
} |
|
|
|
133 |
do_service(W); |
do_service(W); |
134 |
|
|
135 |
shutdown: |
shutdown: |
309 |
|
|
310 |
} |
} |
311 |
|
|
312 |
close_socket(w->socket); |
if ( Run.httpdssl ) { |
313 |
|
|
314 |
|
delete_accepted_ssl_socket(mySSLServerConnection, w->ssl); |
315 |
|
|
316 |
|
} else { |
317 |
|
|
318 |
|
close_socket(w->socket); |
319 |
|
|
320 |
|
} |
321 |
|
|
322 |
free(w); |
free(w); |
323 |
|
|
579 |
|
|
580 |
volatile HttpResponse res= create_HttpResponse(w); |
volatile HttpResponse res= create_HttpResponse(w); |
581 |
volatile HttpRequest req= create_HttpRequest(w); |
volatile HttpRequest req= create_HttpRequest(w); |
582 |
|
|
583 |
if ( res && req ) { |
if ( res && req ) { |
584 |
|
|
585 |
if ( is_authenticated(req, res) ) { |
if ( is_authenticated(req, res) ) { |
586 |
|
|
587 |
if ( !strcmp(req->method, METHOD_GET) ) { |
if ( !strcmp(req->method, METHOD_GET) ) { |
588 |
|
|
589 |
Impl.doGet(req, res); |
Impl.doGet(req, res); |
590 |
|
|
591 |
} |
} |
592 |
else if ( !strcmp(req->method, METHOD_POST) ) { |
else if ( !strcmp(req->method, METHOD_POST) ) { |
593 |
|
|
594 |
Impl.doPost(req, res); |
Impl.doPost(req, res); |
595 |
|
|
596 |
} |
} |
601 |
} |
} |
602 |
|
|
603 |
} |
} |
604 |
|
|
605 |
if ( check_socket(w->socket) ) { |
if ( Run.httpdssl ) { |
606 |
|
|
607 |
send_response(res); |
send_response(res); |
608 |
|
|
609 |
|
} else { |
610 |
|
|
611 |
|
if ( check_socket(w->socket) ) { |
612 |
|
|
613 |
|
send_response(res); |
614 |
|
} |
615 |
|
|
616 |
} |
} |
617 |
|
|
618 |
} |
} |
663 |
static void send_response(HttpResponse res) { |
static void send_response(HttpResponse res) { |
664 |
|
|
665 |
if ( !res->is_committed ) { |
if ( !res->is_committed ) { |
|
|
|
|
FILE *out= res->outputstream; |
|
666 |
char *date= get_date(); |
char *date= get_date(); |
667 |
char *server= get_server(); |
char *server= get_server(); |
668 |
char *headers= get_headers(res); |
char *headers= get_headers(res); |
669 |
int len= res->bufused?strlen(res->outputbuffer):0; |
int len= res->bufused?strlen(res->outputbuffer):0; |
670 |
|
|
671 |
|
if ( Run.httpdssl ) { |
672 |
|
|
673 |
|
printf_ssl_socket(res->ssl, "%s %d %s\r\n", res->protocol, res->status, |
674 |
|
res->status_msg); |
675 |
|
printf_ssl_socket(res->ssl, "Date: %s\r\n", date); |
676 |
|
printf_ssl_socket(res->ssl, "Server: %s\r\n", server); |
677 |
|
printf_ssl_socket(res->ssl, "Content-length: %d\r\n", len); |
678 |
|
printf_ssl_socket(res->ssl, "Connection: close\r\n"); |
679 |
|
if ( headers ) printf_ssl_socket(res->ssl, "%s", headers); |
680 |
|
printf_ssl_socket(res->ssl, "\r\n\r\n"); |
681 |
|
|
682 |
|
if ( res->bufused ) send_ssl_socket(res->ssl, res->outputbuffer, len); |
683 |
|
|
684 |
|
} else { |
685 |
|
|
686 |
|
FILE *out= res->outputstream; |
687 |
|
|
688 |
fprintf(out, "%s %d %s\r\n", res->protocol, res->status, res->status_msg); |
fprintf(out, "%s %d %s\r\n", res->protocol, res->status, |
689 |
fprintf(out, "Date: %s\r\n", date); |
res->status_msg); |
690 |
fprintf(out, "Server: %s\r\n", server); |
fprintf(out, "Date: %s\r\n", date); |
691 |
fprintf(out, "Content-length: %d\r\n", len); |
fprintf(out, "Server: %s\r\n", server); |
692 |
fprintf(out, "Connection: close\r\n"); |
fprintf(out, "Content-length: %d\r\n", len); |
693 |
if ( headers ) fprintf(out, "%s", headers); |
fprintf(out, "Connection: close\r\n"); |
694 |
fprintf(out, "\r\n\r\n"); |
if ( headers ) fprintf(out, "%s", headers); |
695 |
|
fprintf(out, "\r\n\r\n"); |
696 |
if ( res->bufused ) fprintf(out, "%s", res->outputbuffer); |
|
697 |
|
if ( res->bufused ) fprintf(out, "%s", res->outputbuffer); |
698 |
|
|
699 |
|
} |
700 |
|
|
701 |
free(headers); |
free(headers); |
702 |
free(date); |
free(date); |
720 |
char url[REQ_STRLEN]; |
char url[REQ_STRLEN]; |
721 |
char protocol[STRLEN]; |
char protocol[STRLEN]; |
722 |
HttpRequest req; |
HttpRequest req; |
723 |
FILE *in= fdopen(dup(W->socket), "r"); |
FILE *in= NULL; |
724 |
|
|
725 |
if ( in == NULL ) { |
if ( Run.httpdssl ) { |
726 |
|
|
727 |
internal_error(W->socket, SC_INTERNAL_SERVER_ERROR, |
if ( gets_ssl_socket(W->ssl, line, sizeof(line)) == NULL ) { |
728 |
"Cannot create inputstream"); |
|
729 |
return NULL; |
internal_error_ssl(W->ssl, SC_BAD_REQUEST, "No request found"); |
730 |
|
return NULL; |
731 |
} |
|
732 |
|
} |
733 |
if ( fgets(line, sizeof(line), in) == NULL ) { |
|
734 |
|
if ( sscanf(line, "%s %s HTTP/%3[1.0]", method, url, protocol) != 3 ) { |
735 |
internal_error(W->socket, SC_BAD_REQUEST, "No request found"); |
|
736 |
fclose(in); |
internal_error_ssl(W->ssl, SC_BAD_REQUEST, "Cannot parse request"); |
737 |
return NULL; |
return NULL; |
738 |
|
|
739 |
} |
} |
740 |
|
|
741 |
if ( sscanf(line, "%s %s HTTP/%3[1.0]", method, url, protocol) != 3 ) { |
} else { |
742 |
|
|
743 |
|
in= fdopen(dup(W->socket), "r"); |
744 |
|
|
745 |
|
if ( in == NULL ) { |
746 |
|
|
747 |
|
internal_error(W->socket, SC_INTERNAL_SERVER_ERROR, |
748 |
|
"Cannot create inputstream"); |
749 |
|
return NULL; |
750 |
|
|
751 |
|
} |
752 |
|
|
753 |
internal_error(W->socket, SC_BAD_REQUEST, "Cannot parse request"); |
if ( fgets(line, sizeof(line), in) == NULL ) { |
754 |
fclose(in); |
|
755 |
return NULL; |
internal_error(W->socket, SC_BAD_REQUEST, "No request found"); |
756 |
|
fclose(in); |
757 |
|
return NULL; |
758 |
|
|
759 |
|
} |
760 |
|
|
761 |
|
if ( sscanf(line, "%s %s HTTP/%3[1.0]", method, url, protocol) != 3 ) { |
762 |
|
|
763 |
|
internal_error(W->socket, SC_BAD_REQUEST, "Cannot parse request"); |
764 |
|
fclose(in); |
765 |
|
return NULL; |
766 |
|
|
767 |
|
} |
768 |
} |
} |
769 |
|
|
770 |
req= NEW(req); |
req= NEW(req); |
773 |
req->method= xstrdup(method); |
req->method= xstrdup(method); |
774 |
req->url= xstrdup(url); |
req->url= xstrdup(url); |
775 |
req->protocol= xstrdup(protocol); |
req->protocol= xstrdup(protocol); |
776 |
req->inputstream= in; |
req->ssl= W->ssl; |
777 |
|
|
778 |
|
if (! Run.httpdssl ) { |
779 |
|
|
780 |
|
req->inputstream= in; |
781 |
|
|
782 |
|
} else { |
783 |
|
|
784 |
|
req->inputstream= NULL; |
785 |
|
|
786 |
|
} |
787 |
|
|
788 |
req->inetaddr= W->inetaddr; |
req->inetaddr= W->inetaddr; |
789 |
|
|
790 |
create_headers(req); |
create_headers(req); |
791 |
|
|
792 |
if ( !create_parameters(req) ) { |
if ( !create_parameters(req) ) { |
793 |
|
|
794 |
internal_error(W->socket, SC_BAD_REQUEST, |
if ( Run.httpdssl ) { |
795 |
"Cannot parse Request parameters"); |
|
796 |
fclose(in); |
internal_error_ssl(W->ssl, SC_BAD_REQUEST, |
797 |
|
"Cannot parse Request parameters"); |
798 |
|
|
799 |
|
} else { |
800 |
|
|
801 |
|
internal_error(W->socket, SC_BAD_REQUEST, |
802 |
|
"Cannot parse Request parameters"); |
803 |
|
fclose(in); |
804 |
|
|
805 |
|
} |
806 |
|
|
807 |
return NULL; |
return NULL; |
808 |
|
|
809 |
} |
} |
820 |
static HttpResponse create_HttpResponse(RequestWrapper W) { |
static HttpResponse create_HttpResponse(RequestWrapper W) { |
821 |
|
|
822 |
HttpResponse res; |
HttpResponse res; |
823 |
FILE *out= fdopen(dup(W->socket), "w"); |
FILE *out= NULL; |
824 |
|
|
825 |
if ( out == NULL ) { |
if ( ! Run.httpdssl ) { |
826 |
|
|
827 |
internal_error(W->socket, SC_INTERNAL_SERVER_ERROR, |
out = fdopen(dup(W->socket), "w"); |
828 |
"Cannot create outputstream"); |
|
829 |
return NULL; |
if ( out == NULL ) { |
830 |
|
|
831 |
|
internal_error(W->socket, SC_INTERNAL_SERVER_ERROR, |
832 |
|
"Cannot create outputstream"); |
833 |
|
|
834 |
|
return NULL; |
835 |
|
} |
836 |
|
|
837 |
} |
} |
838 |
|
|
839 |
res= NEW(res); |
res= NEW(res); |
845 |
res->bufsize= 0; |
res->bufsize= 0; |
846 |
res->bufused= 0; |
res->bufused= 0; |
847 |
res->is_committed= FALSE; |
res->is_committed= FALSE; |
848 |
|
res->ssl= W->ssl; |
849 |
|
|
850 |
return res; |
return res; |
851 |
|
|
861 |
char *value; |
char *value; |
862 |
HttpHeader p; |
HttpHeader p; |
863 |
HttpHeader header; |
HttpHeader header; |
864 |
|
|
865 |
while ( NULL != fgets(line, sizeof(line), req->inputstream) ) { |
while ( 1 ) { |
866 |
|
|
867 |
|
if ( Run.httpdssl ) { |
868 |
|
|
869 |
|
if (NULL == gets_ssl_socket(req->ssl, line, sizeof(line))) { |
870 |
|
|
871 |
|
break; |
872 |
|
|
873 |
|
} |
874 |
|
|
875 |
|
} else { |
876 |
|
|
877 |
|
if (NULL == fgets(line, sizeof(line), req->inputstream)) { |
878 |
|
|
879 |
|
break; |
880 |
|
|
881 |
|
} |
882 |
|
|
883 |
|
} |
884 |
|
|
885 |
if ( !strcmp(line, "\r\n") || !strcmp(line, "\n") ) |
if ( !strcmp(line, "\r\n") || !strcmp(line, "\n") ) |
886 |
break; |
break; |
887 |
|
|
1164 |
free(server); |
free(server); |
1165 |
free(date); |
free(date); |
1166 |
free(status_msg); |
free(status_msg); |
1167 |
|
|
1168 |
|
} |
1169 |
|
|
1170 |
|
static void internal_error_ssl(ssl_connection *ssl, int status, char *msg) { |
1171 |
|
|
1172 |
|
char response[RES_STRLEN]; |
1173 |
|
char *server= get_server(); |
1174 |
|
char *date= get_date(); |
1175 |
|
char *status_msg= get_status_string(status); |
1176 |
|
|
1177 |
|
snprintf(response, RES_STRLEN, |
1178 |
|
"%s %d %s\r\n" |
1179 |
|
"Date: %s\r\n" |
1180 |
|
"Server: %s\r\n" |
1181 |
|
"Content-Type: text/html\r\n" |
1182 |
|
"Connection: close\r\n" |
1183 |
|
"\r\n" |
1184 |
|
"<html><head><title>%s</title></head>" |
1185 |
|
"<body bgcolor=#FFFFFF><h2>%s</h2>%s<p>" |
1186 |
|
"<hr><a href='%s'><font size=-1>%s</font></a>" |
1187 |
|
"</body></html>\r\n", |
1188 |
|
SERVER_PROTOCOL, status, status_msg, date, server, |
1189 |
|
status_msg, status_msg, msg, SERVER_URL, server); |
1190 |
|
|
1191 |
|
send_ssl_socket(ssl, response, strlen(response)); |
1192 |
|
free(server); |
1193 |
|
free(date); |
1194 |
|
free(status_msg); |
1195 |
|
|
1196 |
} |
} |
1197 |
|
|