00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "http.h"
00036 #include "settings.h"
00037 #include "service.h"
00038 #include <copy.h>
00039 #include <xml.h>
00040
00041 #include <apr_strings.h>
00042 #include <string.h>
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045
00046
00047 static char *get_remote_endpoint(apr_socket_t *sock, apr_pool_t *mp)
00048 {
00049 char *remote_ipaddr;
00050
00051 apr_sockaddr_t *remote_sa;
00052
00053 apr_socket_addr_get(&remote_sa, APR_REMOTE, sock);
00054 apr_sockaddr_ip_get(&remote_ipaddr, remote_sa);
00055
00056
00057
00058 return remote_ipaddr;
00059 }
00060
00061
00062 bs_status handle_http_get(apr_socket_t *sock, apr_pool_t *mp)
00063 {
00064 apr_status_t rv;
00065 bs_status rv2;
00066 bs_definition *def;
00067 char *contentbuf, *headerbuf, timebuf[APR_RFC822_DATE_LEN + 1];
00068 char *remote_client;
00069 apr_size_t len;
00070 bs_uint64 size;
00071
00072
00073 remote_client = get_remote_endpoint(sock, mp);
00074 printf("Handling incoming HTTP GET request from %s\n", remote_client);
00075 rv2 = get_services(&def, mp);
00076 if (rv2 != BS_OK){
00077 send_http_error(sock, "HTTP/1.0 500 Internal Server Error", mp);
00078 fprintf(stderr, "%d Error while gathering services\n", rv2);
00079 return BS_ERROR;
00080 }
00081 rv2 = xlate_definition_to_xml(&contentbuf, &size, def, mp);
00082 if (rv2 != BS_OK){
00083 send_http_error(sock, "HTTP/1.0 500 Internal Server Error", mp);
00084 fprintf(stderr, "%d Error while creating WSDL of services\n", rv2);
00085 return BS_ERROR;
00086 }
00087
00088
00089 apr_rfc822_date(timebuf, apr_time_now());
00090 headerbuf = apr_psprintf(mp,
00091 "HTTP/1.0 200 OK\r\n"
00092 "Date: %s\r\n"
00093 "Server: " BIOSPHERE_VERSION_STRING "\r\n"
00094 "Content-Length: %" BS_UINT64_FMT "\r\n"
00095 "Content-Type: application/wsdl+xml\r\n"
00096 "Content-Disposition: attachment; filename=\"services.wsdl\"\r\n\r\n",
00097 timebuf, size);
00098 headerbuf = apr_pstrcat(mp, headerbuf, contentbuf, NULL);
00099 len = strlen(headerbuf);
00100 rv = apr_socket_send(sock, headerbuf, &len);
00101 if (rv != APR_SUCCESS || len == 0) {
00102 char err[256];
00103 apr_strerror(rv, err, sizeof(err));
00104 fprintf(stderr, "Error while sending data: %s\n", err);
00105 return BS_ERROR;
00106 }
00107
00108 return BS_OK;
00109 }
00110
00111
00119 static bs_status get_remaining_content(apr_socket_t *sock, char **result,
00120 const char *initial, unsigned size, bs_uint64 remaining,
00121 apr_pool_t *mp)
00122 {
00123 char *collect;
00124 char buf[HTTP_BUFFER_SIZE];
00125 apr_size_t buflen;
00126
00127
00128 collect = apr_pstrndup(mp, initial, size);
00129 while (remaining > 0) {
00130 apr_status_t rv;
00131
00132 buflen = sizeof(buf) - 1;
00133 memset(buf, '\0', sizeof(buf));
00134 rv = apr_socket_recv(sock, buf, &buflen);
00135 if (rv == APR_EOF || buflen == 0) {
00136 apr_socket_close(sock);
00137 return BS_ERROR;
00138 }
00139
00140
00141 if (buflen > remaining) {
00142 char *tmp;
00143 tmp = apr_pstrndup(mp, buf, remaining);
00144 collect = apr_pstrcat(mp, collect, tmp, NULL);
00145 break;
00146 }
00147 else collect = apr_pstrcat(mp, collect, buf, NULL);
00148
00149 remaining -= buflen;
00150 }
00151
00152 *result = collect;
00153 return BS_OK;
00154 }
00155
00156
00162 static bs_status check_for_http_errors(apr_socket_t *sock,
00163 http_header_info *info, apr_pool_t *mp)
00164 {
00165 if (info->content_length == 0) {
00166 send_http_error(sock, "HTTP/1.0 411 Length Required", mp);
00167 return BS_ERROR;
00168 }
00169 else if (info->content_length > BIOSPHERED_MAX_CONTENT_LENGTH) {
00170 send_http_error(sock, "HTTP/1.0 413 Request Entity Too Large", mp);
00171 return BS_ERROR;
00172 }
00173 else if (info->content_type == NULL ||
00174 apr_strnatcmp(info->content_type, "text/xml") != 0) {
00175 send_http_error(sock, "HTTP/1.0 415 Unsupported Media Type", mp);
00176 return BS_ERROR;
00177 }
00178
00179 return BS_OK;
00180 }
00181
00182
00183 bs_status handle_http_post(apr_socket_t *sock, const char *headerbuf,
00184 apr_size_t headerlen, apr_pool_t *mp)
00185 {
00186 http_header_info *hinfo;
00187 bs_status rv;
00188 apr_status_t rv2;
00189 apr_size_t len;
00190 char *content_buf, *hbuf, *remote_client, timebuf[APR_RFC822_DATE_LEN + 1];
00191 bs_service_request *request = NULL;
00192 bs_service_response *response = NULL;
00193 unsigned type;
00194 bs_uint64 size;
00195
00196
00197 remote_client = get_remote_endpoint(sock, mp);
00198
00199 rv = parse_http_headers(headerbuf, headerlen, &hinfo, mp);
00200 if (rv != BS_OK) {
00201 fprintf(stderr, "%d Error while parsing HTTP headers\n", rv);
00202 return rv;
00203 }
00204 rv = check_for_http_errors(sock, hinfo, mp);
00205 if (rv != BS_OK) {
00206 fprintf(stderr, "%d Error while checking for HTTP errors\n", rv);
00207 return rv;
00208 }
00209 headerbuf += hinfo->content_offset;
00210
00211
00212 if (hinfo->content_length < headerlen - hinfo->content_offset)
00213 content_buf = apr_pstrndup(mp, headerbuf, hinfo->content_length);
00214 else {
00215 bs_uint64 remaining;
00216 content_buf = apr_pstrndup(mp, headerbuf, headerlen - hinfo->content_offset);
00217 remaining = hinfo->content_length - headerlen + hinfo->content_offset;
00218 rv = get_remaining_content(sock, &content_buf, content_buf,
00219 headerlen - hinfo->content_offset, remaining, mp);
00220 if (rv != BS_OK) {
00221 fprintf(stderr, "%d Unable to receive remaining content\n", rv);
00222 return rv;
00223 }
00224 }
00225
00226
00227 rv = xlate_from_xml(content_buf, strlen(content_buf), (void **) &request, &type, mp);
00228 if (rv != BS_OK || type != SERVICE_REQUEST_FROM_XML) {
00229 send_http_error(sock, "HTTP/1.0 406 Not Acceptable", mp);
00230 fprintf(stderr, "%d Error while translating XML service request\n", rv);
00231 return rv;
00232 }
00233
00234
00235
00236 rv = handle_service_request(request, &response, mp);
00237 if (rv != BS_OK) {
00238 send_http_error(sock, "HTTP/1.0 503 Service Unavailable", mp);
00239 fprintf(stderr, "%d Error while handling service request\n", rv);
00240 delete_response(response);
00241 return rv;
00242 }
00243
00244
00245 rv = xlate_response_to_xml(&content_buf, &size, response, mp);
00246 delete_response(response);
00247 if (rv != BS_OK) {
00248 send_http_error(sock, "HTTP/1.0 500 Internal Server Error", mp);
00249 fprintf(stderr, "%d Error while translating service response to XML\n", rv);
00250 return rv;
00251 }
00252
00253
00254 apr_rfc822_date(timebuf, apr_time_now());
00255 hbuf = apr_psprintf(mp,
00256 "HTTP/1.0 200 OK\r\n"
00257 "Date: %s\r\n"
00258 "Server: " BIOSPHERE_VERSION_STRING "\r\n"
00259 "Content-Length: %" BS_UINT64_FMT "\r\n"
00260 "Content-Type: text/xml\r\n\r\n",
00261 timebuf, size);
00262 hbuf = apr_pstrcat(mp, hbuf, content_buf, NULL);
00263 len = strlen(hbuf);
00264 rv2 = apr_socket_send(sock, hbuf, &len);
00265 if (rv2 != APR_SUCCESS || len == 0) {
00266 fprintf(stderr, "%d Error while sending service response\n", rv);
00267 return BS_ERROR;
00268 }
00269
00270 return BS_OK;
00271 }
00272
00273
00274 bs_status send_http_error(apr_socket_t *sock, const char *errstring, apr_pool_t *mp)
00275 {
00276 apr_status_t rv;
00277 char *buf, timebuf[APR_RFC822_DATE_LEN + 1];
00278 apr_size_t len;
00279
00280 apr_rfc822_date(timebuf, apr_time_now());
00281 buf = apr_psprintf(mp,
00282 "%s\r\n"
00283 "Date: %s\r\n"
00284 "Server: " BIOSPHERE_VERSION_STRING "\r\n\r\n",
00285 errstring,
00286 timebuf);
00287 len = strlen(buf);
00288 rv = apr_socket_send(sock, buf, &len);
00289 if (rv != APR_SUCCESS) return BS_ERROR;
00290
00291 return BS_OK;
00292 }