00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "klone_conf.h"
00012 #include <sys/types.h>
00013 #include <stdlib.h>
00014 #include <unistd.h>
00015 #ifdef SSL_ON
00016 #include <openssl/ssl.h>
00017 #include <openssl/err.h>
00018 #endif
00019 #include <u/libu.h>
00020 #include <klone/utils.h>
00021 #include <klone/os.h>
00022 #include <klone/server.h>
00023 #include <klone/context.h>
00024 #include <klone/broker.h>
00025 #include <klone/request.h>
00026 #include <klone/ses_prv.h>
00027 #include <klone/response.h>
00028 #include <klone/backend.h>
00029 #include <klone/io.h>
00030 #include <klone/timer.h>
00031 #include <klone/tls.h>
00032 #include <klone/ses_prv.h>
00033 #include <klone/hook.h>
00034 #include <klone/hookprv.h>
00035 #include <klone/access.h>
00036 #include <klone/vhost.h>
00037 #include <klone/supplier.h>
00038 #include "http_s.h"
00039
00040 struct http_status_map_s
00041 {
00042 int status;
00043 const char *desc;
00044 } http_status_map[] = {
00045 { HTTP_STATUS_OK , "OK" },
00046 { HTTP_STATUS_NOT_MODIFIED , "Not Modified" },
00047 { HTTP_STATUS_NOT_FOUND , "Not Found" },
00048 { HTTP_STATUS_INTERNAL_SERVER_ERROR , "Internal Server Error" },
00049 { HTTP_STATUS_MOVED_PERMANENTLY , "Moved Permanently" },
00050 { HTTP_STATUS_MOVED_TEMPORARILY , "Moved Temporarily" },
00051 { HTTP_STATUS_CREATED , "Created" },
00052 { HTTP_STATUS_ACCEPTED , "Accepted" },
00053 { HTTP_STATUS_NO_CONTENT , "No Content" },
00054 { HTTP_STATUS_BAD_REQUEST , "Bad Request" },
00055 { HTTP_STATUS_UNAUTHORIZED , "Unauthorized" },
00056 { HTTP_STATUS_FORBIDDEN , "Forbidden" },
00057 { HTTP_STATUS_LENGTH_REQUIRED , "Content-Length required" },
00058 { HTTP_STATUS_REQUEST_TOO_LARGE , "Request data too big" },
00059 { HTTP_STATUS_EXT_KEY_NEEDED , "Key needed" },
00060 { HTTP_STATUS_NOT_IMPLEMENTED , "Not Implemented" },
00061 { HTTP_STATUS_BAD_GATEWAY , "Bad Gateway" },
00062 { HTTP_STATUS_SERVICE_UNAVAILABLE , "Service Unavailable" },
00063 { 0 , NULL }
00064 };
00065
00066 enum { URI_MAX = 2048 };
00067
00068
00069 int cgi_set_request(request_t *rq);
00070
00071 session_opt_t *http_get_session_opt(http_t *http)
00072 {
00073 dbg_return_if (http == NULL, NULL);
00074
00075 return http->sess_opt;
00076 }
00077
00078 u_config_t *http_get_config(http_t* http)
00079 {
00080 dbg_return_if (http == NULL, NULL);
00081
00082 return http->config;
00083 }
00084
00085 const char *http_get_status_desc(int status)
00086 {
00087 struct http_status_map_s *map = http_status_map;
00088 const char *msg = "Unknown Status Code";
00089
00090 for( ; map->status; ++map)
00091 if(map->status == status)
00092 {
00093 msg = map->desc;
00094 break;
00095 }
00096
00097 return msg;
00098 }
00099
00100 static int http_try_resolv(const char *alias, char *dst, const char *uri,
00101 size_t sz)
00102 {
00103 static const char *WP = " \t";
00104 char *src, *res, *pp = NULL;
00105 char v[1024];
00106
00107 dbg_err_if(dst == NULL);
00108 dbg_err_if(uri == NULL);
00109 dbg_err_if(alias == NULL);
00110
00111
00112 dbg_err_if(u_strlcpy(v, alias, sizeof(v)));
00113
00114
00115 src = strtok_r(v, WP, &pp);
00116 dbg_err_if(src == NULL);
00117
00118
00119 nop_err_if(strncmp(src, uri, strlen(src)));
00120
00121
00122 if(src[strlen(src)-1] != '/')
00123 nop_err_if(uri[strlen(src)] != '/');
00124
00125
00126 res = strtok_r(NULL, WP, &pp);
00127 dbg_err_if(res == NULL);
00128
00129
00130 dbg_err_if(u_path_snprintf(dst, sz, '/', "%s/%s", res, uri + strlen(src)));
00131
00132 return 0;
00133 err:
00134 return ~0;
00135 }
00136
00137 vhost_list_t* http_get_vhost_list(http_t *http)
00138 {
00139 dbg_err_if(http == NULL);
00140
00141 return http->vhosts;
00142 err:
00143 return NULL;
00144 }
00145
00146 vhost_t* http_get_vhost(http_t *h, request_t *rq)
00147 {
00148 const char *host;
00149 char *p, hostcp[128];
00150 vhost_t *vh = NULL;
00151
00152 dbg_err_if (h == NULL);
00153 dbg_err_if (rq == NULL);
00154
00155 if((vh = request_get_vhost(rq)) != NULL)
00156 return vh;
00157
00158 if((host = request_get_field_value(rq, "Host")) != NULL)
00159 {
00160 dbg_err_if(u_strlcpy(hostcp, host, sizeof(hostcp)));
00161
00162
00163 if((p = strrchr(hostcp, ':')) != NULL)
00164 *p = 0;
00165
00166 vh = vhost_list_get(h->vhosts, hostcp);
00167 }
00168
00169 if(vh == NULL)
00170 {
00171
00172 vh = vhost_list_get_n(h->vhosts, 0);
00173 dbg_err_if(vh == NULL);
00174 }
00175
00176 return vh;
00177 err:
00178 return NULL;
00179 }
00180
00181 int http_alias_resolv(http_t *h, request_t *rq, char *dst, const char *uri,
00182 size_t sz)
00183 {
00184 u_config_t *config, *cgi;
00185 vhost_t *vhost;
00186 int i;
00187
00188 dbg_err_if (h == NULL);
00189 dbg_err_if (dst == NULL);
00190 dbg_err_if (uri == NULL);
00191
00192 dbg_err_if((vhost = http_get_vhost(h, rq)) == NULL);
00193
00194
00195 for(i = 0; !u_config_get_subkey_nth(vhost->config,"dir_alias", i, &config);
00196 ++i)
00197 {
00198 if(!http_try_resolv(u_config_get_value(config), dst, uri, sz))
00199 return 0;
00200 }
00201
00202
00203 if(!u_config_get_subkey(vhost->config, "cgi", &cgi))
00204 {
00205 for(i = 0; !u_config_get_subkey_nth(cgi, "script_alias", i, &config);
00206 ++i)
00207 {
00208 if(!http_try_resolv(u_config_get_value(config), dst, uri, sz))
00209 return 0;
00210 }
00211 }
00212
00213
00214 dbg_err_if(u_path_snprintf(dst, sz, '/', "%s/%s", vhost->dir_root, uri));
00215
00216 return 0;
00217 err:
00218 return ~0;
00219 }
00220
00221 static int http_is_valid_uri(request_t *rq, const char *buf, size_t len)
00222 {
00223 char resolved[U_FILENAME_MAX], uri[URI_MAX];
00224 http_t *h = NULL;
00225
00226 dbg_err_if (rq == NULL);
00227 dbg_err_if (buf == NULL);
00228 dbg_err_if (len + 1 > URI_MAX);
00229
00230 dbg_err_if ((h = request_get_http(rq)) == NULL);
00231
00232 memcpy(uri, buf, len);
00233 uri[len] = '\0';
00234
00235
00236 if(broker_is_valid_uri(h->broker, h, rq, uri, strlen(uri)))
00237 return 1;
00238
00239
00240 dbg_err_if(http_alias_resolv(h, rq, resolved, uri, sizeof resolved));
00241
00242 return broker_is_valid_uri(h->broker, h, rq, resolved, strlen(resolved));
00243 err:
00244 return 0;
00245 }
00246
00247 static int http_resolv_request(http_t *h, request_t *rq)
00248 {
00249 const char *cstr;
00250 char resolved[U_FILENAME_MAX];
00251
00252 dbg_err_if(h == NULL);
00253 dbg_err_if(rq == NULL);
00254
00255
00256 if((cstr = request_get_filename(rq)) != NULL)
00257 {
00258 dbg_err_if(http_alias_resolv(h, rq, resolved, cstr, U_FILENAME_MAX));
00259
00260 dbg_err_if(request_set_resolved_filename(rq, resolved));
00261 }
00262
00263
00264 if((cstr = request_get_path_info(rq)) != NULL)
00265 {
00266 dbg_err_if(http_alias_resolv(h, rq, resolved, cstr, U_FILENAME_MAX));
00267
00268 dbg_err_if(request_set_resolved_path_info(rq, resolved));
00269 }
00270
00271 return 0;
00272 err:
00273 return ~0;
00274 }
00275
00276 static int http_is_valid_index(http_t *h, request_t *rq, const char *uri)
00277 {
00278 char resolved[U_FILENAME_MAX] = { 0 };
00279
00280 dbg_err_if(u_path_snprintf(resolved, U_FILENAME_MAX, '/', "%s/%s",
00281 request_get_resolved_filename(rq), uri));
00282
00283 if(broker_is_valid_uri(h->broker, h, rq, resolved, strlen(resolved)))
00284 return 1;
00285
00286 err:
00287 return 0;
00288 }
00289
00290 static int http_get_config_index(http_t *h, request_t *rq, char *idx, size_t sz)
00291 {
00292 vhost_t *vhost;
00293 char buf[256], *tok, *src, *pp = NULL;
00294 const char *cindex = NULL;
00295
00296 dbg_err_if (h == NULL);
00297 dbg_err_if (rq == NULL);
00298
00299 dbg_err_if((vhost = http_get_vhost(h, rq)) == NULL);
00300
00301 if((cindex = u_config_get_subkey_value(vhost->config, "index")) == NULL)
00302 return ~0;
00303
00304
00305 dbg_err_if(u_strlcpy(buf, cindex, sizeof(buf)));
00306
00307 for(src = buf; (tok = strtok_r(src, " \t", &pp)) != NULL; src = NULL)
00308 {
00309 if(!strcmp(tok, ""))
00310 continue;
00311
00312 if(http_is_valid_index(h, rq, tok))
00313 {
00314 dbg_err_if(u_strlcpy(idx, tok, sz));
00315 return 0;
00316 }
00317 }
00318
00319
00320 err:
00321 return ~0;
00322 }
00323
00324 static int http_get_default_index(http_t *h, request_t *rq, char *cindex,
00325 size_t sz)
00326 {
00327 const char **pg;
00328 static const char *indexes[] =
00329 {
00330 "/index.kl1",
00331 "/index.html",
00332 "/index.htm",
00333 "/index.klx",
00334 "/index.klone",
00335 "/index.klc",
00336 NULL
00337 };
00338
00339 dbg_err_if (h == NULL);
00340 dbg_err_if (rq == NULL);
00341 dbg_err_if (cindex == NULL);
00342
00343
00344 for(pg = indexes; *pg; ++pg)
00345 {
00346 if(http_is_valid_index(h, rq, *pg))
00347 {
00348 dbg_err_if(u_strlcpy(cindex, *pg, sz));
00349 return 0;
00350 }
00351 }
00352
00353
00354 err:
00355 return ~0;
00356 }
00357
00358 static int http_set_index_request(http_t *h, request_t *rq)
00359 {
00360 char idx[128], uri[1024];
00361
00362 dbg_err_if (h == NULL);
00363 dbg_err_if (rq == NULL);
00364
00365
00366 nop_err_if(http_get_config_index(h, rq, idx, sizeof(idx)) &&
00367 http_get_default_index(h, rq, idx, sizeof(idx)));
00368
00369 dbg_err_if(u_snprintf(uri, sizeof(uri), "%s%s",
00370 request_get_filename(rq), idx));
00371
00372 dbg_if(request_set_filename(rq, uri));
00373
00374 dbg_err_if(http_resolv_request(h, rq));
00375
00376 return 0;
00377 err:
00378 return ~0;
00379 }
00380
00381 static int http_add_default_header(http_t *h, request_t *rq, response_t *rs)
00382 {
00383 vhost_t *vhost;
00384 time_t now;
00385
00386 dbg_err_if (h == NULL);
00387 dbg_err_if (rs == NULL);
00388
00389 dbg_err_if((vhost = http_get_vhost(h, rq)) == NULL);
00390
00391
00392 dbg_err_if(response_set_field(rs, "Server", vhost->server_sig));
00393
00394 now = time(NULL);
00395 dbg_err_if(response_set_date(rs, now));
00396
00397 return 0;
00398 err:
00399 return ~0;
00400 }
00401
00402 static int http_print_error_page(http_t *h, request_t *rq, response_t *rs,
00403 int http_status)
00404 {
00405 enum { BUFSZ = 64 };
00406 const char *err_page;
00407 char s[URI_MAX], *sp = NULL;
00408 char buf[BUFSZ], *pp = NULL;
00409 vhost_t *vhost;
00410
00411 dbg_err_if (h == NULL);
00412 dbg_err_if (rq == NULL);
00413 dbg_err_if (rs == NULL);
00414 dbg_err_if (http_status == 0);
00415
00416
00417 if(http_status != 302)
00418 dbg_err_if(header_clear(response_get_header(rs)));
00419
00420
00421 dbg_err_if(http_add_default_header(h, rq, rs));
00422
00423
00424 dbg_err_if(response_disable_caching(rs));
00425
00426
00427 dbg_err_if(u_snprintf(buf, BUFSZ, "error.%d", http_status));
00428 if((vhost = http_get_vhost(h, rq)) == NULL)
00429 err_page = u_config_get_subkey_value(h->config, buf);
00430 else
00431 err_page = u_config_get_subkey_value(vhost->config, buf);
00432
00433 if(err_page && !request_set_uri(rq, err_page, NULL, NULL))
00434 {
00435 dbg_err_if(http_resolv_request(h, rq));
00436
00437
00438 dbg_err_if (u_strlcpy(s, err_page, sizeof s));
00439
00440 sp = strtok_r(s, "?", &pp);
00441 dbg_err_if (sp == NULL);
00442
00443 if(http_is_valid_uri(rq, sp, strlen(sp)))
00444 {
00445
00446 broker_serve(h->broker, h, rq, rs);
00447 return 0;
00448 }
00449
00450
00451 warn("%d handler page (%s) not found", http_status, sp);
00452 }
00453
00454
00455 response_set_status(rs, http_status);
00456
00457 response_print_header(rs);
00458
00459 if(request_get_method(rq) == HM_HEAD)
00460 return 0;
00461
00462
00463 dbg_err_if(io_printf(response_io(rs),
00464 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">"
00465 "<html><head><title>%d %s</title></head>\n"
00466 "<body><h1>%s</h1><p>URL: %s</p><hr>"
00467 "<address>KLone/%s web server - www.koanlogic.com</address>"
00468 "</body></html>",
00469 http_status, http_get_status_desc(http_status),
00470 http_get_status_desc(http_status),
00471 (request_get_uri(rq) ? request_get_uri(rq) : ""),
00472 KLONE_VERSION
00473 ) < 0);
00474
00475 return 0;
00476 err:
00477 return ~0;
00478 }
00479
00480 static int http_serve(http_t *h, int fd)
00481 {
00482 request_t *rq = NULL;
00483 response_t *rs = NULL;
00484 io_t *in = NULL, *out = NULL;
00485 int cgi = 0, rc = HTTP_STATUS_INTERNAL_SERVER_ERROR;
00486 const char *gwi = NULL, *cstr;
00487 talarm_t *al = NULL;
00488 char addr[128] = { '\0' };
00489 vhost_t *vhost;
00490 struct sockaddr_storage ss;
00491 socklen_t slen;
00492 char *uri, nuri[URI_MAX];
00493 const char *port;
00494 supplier_t *sup;
00495
00496 u_unused_args(al);
00497
00498 dbg_err_if (h == NULL);
00499 dbg_err_if (fd < 0);
00500
00501 if(fd == 0 && (gwi = getenv("GATEWAY_INTERFACE")) != NULL)
00502 cgi++;
00503
00504
00505 dbg_err_if(request_create(h, &rq));
00506 request_set_cgi(rq, cgi);
00507
00508
00509 if (cgi)
00510 {
00511 if (getenv("REMOTE_ADDR") && getenv("REMOTE_PORT"))
00512 {
00513 (void) u_addr_fmt(getenv("REMOTE_ADDR"), getenv("REMOTE_PORT"),
00514 addr, sizeof addr);
00515
00516 dbg_err_if(request_set_addr(rq, addr));
00517 }
00518
00519 if (getenv("SERVER_ADDR"))
00520 {
00521 if ((port = getenv("SERVER_PORT")) == NULL)
00522 port = "80";
00523
00524 (void) u_addr_fmt(getenv("SERVER_ADDR"), port, addr, sizeof addr);
00525
00526 dbg_err_if(request_set_peer_addr(rq, addr));
00527 }
00528 }
00529 else
00530 {
00531 slen = sizeof ss;
00532
00533
00534 dbg_err_if(getsockname(fd, (struct sockaddr *) &ss, &slen) == -1);
00535 dbg_err_if(request_set_addr(rq,
00536 u_sa_ntop((struct sockaddr *) &ss, addr, sizeof addr)));
00537
00538
00539 dbg_err_if(getpeername(fd, (struct sockaddr *) &ss, &slen) == -1);
00540 dbg_err_if(request_set_peer_addr(rq,
00541 u_sa_ntop((struct sockaddr *) &ss, addr, sizeof addr)));
00542 }
00543
00544 #ifdef SSL_ON
00545
00546 if(h->ssl && !cgi)
00547 dbg_err_if(io_ssl_create(fd, IO_FD_CLOSE, 0, h->ssl_ctx, &in));
00548 else
00549 dbg_err_if(io_fd_create(fd, IO_FD_CLOSE, &in));
00550 #else
00551
00552 dbg_err_if(io_fd_create(fd, IO_FD_CLOSE, &in));
00553 #endif
00554
00555
00556 dbg_err_if(request_bind(rq, in));
00557 in = NULL;
00558
00559
00560 dbg_err_if(response_create(h, &rs));
00561
00562 response_set_cgi(rs, cgi);
00563
00564 if(cgi)
00565 dbg_err_if(cgi_set_request(rq));
00566
00567
00568 if(cgi)
00569 dbg_err_if(io_fd_create((cgi ? 1 : dup(fd)), IO_FD_CLOSE, &out));
00570 else {
00571
00572 dbg_err_if(io_dup(request_io(rq), &out));
00573 }
00574
00575
00576 response_set_method(rs, HM_GET);
00577
00578
00579 dbg_err_if(response_bind(rs, out));
00580 out = NULL;
00581
00582
00583 dbg_err_if(response_set_status(rs, HTTP_STATUS_BAD_REQUEST));
00584 rc = HTTP_STATUS_BAD_REQUEST;
00585
00586
00587 dbg_err_if(request_parse_header(rq, http_is_valid_uri, rq));
00588
00589 response_set_method(rs, request_get_method(rq));
00590
00591
00592 dbg_err_if((vhost = http_get_vhost(h, rq)) == NULL);
00593 request_set_vhost(rq, vhost);
00594
00595
00596 dbg_err_if(http_resolv_request(h, rq));
00597
00598
00599 request_get_sup_info(rq, &sup, NULL, NULL);
00600 if(sup == NULL && (cstr = request_get_filename(rq)) != NULL &&
00601 cstr[strlen(cstr)-1] == '/')
00602 dbg_if(http_set_index_request(h, rq));
00603
00604
00605 dbg_err_if(http_add_default_header(h, rq, rs));
00606
00607
00608 dbg_err_if(response_set_status(rs, HTTP_STATUS_OK));
00609
00610
00611 rc = broker_serve(h->broker, h, rq, rs);
00612
00613
00614
00615 if(response_get_status(rs) == 404 && (uri = request_get_uri(rq)) != NULL &&
00616 uri[strlen(uri)-1] != '/')
00617 {
00618 if(!http_set_index_request(h, rq))
00619 {
00620 (void) u_strlcpy(nuri, request_get_uri(rq), sizeof(nuri));
00621 (void) u_strlcat(nuri, "/", sizeof(nuri));
00622
00623 if(request_get_path_info(rq))
00624 (void) u_strlcat(nuri, request_get_path_info(rq), sizeof(nuri));
00625
00626 if(request_get_query_string(rq))
00627 {
00628 (void) u_strlcat(nuri, "?", sizeof(nuri));
00629 (void) u_strlcat(nuri, request_get_query_string(rq),
00630 sizeof(nuri));
00631 }
00632
00633 response_redirect(rs, nuri);
00634 rc = HTTP_STATUS_MOVED_TEMPORARILY;
00635 }
00636 }
00637
00638
00639 if(vhost->klog)
00640 dbg_if(access_log(h, vhost->al_config, rq, rs));
00641
00642
00643 hook_call(request, rq, rs);
00644
00645
00646 nop_err_if(rc != 0);
00647
00648
00649
00650 request_free(rq);
00651 response_free(rs);
00652
00653
00654
00655 return 0;
00656 err:
00657
00658 if(rq && rs)
00659 hook_call(request, rq, rs);
00660
00661 if(rc && rq && rs && response_io(rs))
00662 http_print_error_page(h, rq, rs, rc);
00663 if(in)
00664 io_free(in);
00665 if(out)
00666 io_free(out);
00667 if(rq)
00668 request_free(rq);
00669 if(rs)
00670 response_free(rs);
00671 return ~0;
00672 }
00673
00674 static int http_free(http_t *h)
00675 {
00676 dbg_return_if (h == NULL, 0);
00677
00678 if(h->broker)
00679 broker_free(h->broker);
00680
00681 if(h->vhosts)
00682 vhost_list_free(h->vhosts);
00683
00684 U_FREE(h);
00685
00686 return 0;
00687 }
00688
00689 static int http_add_vhost(http_t *http, const char *host, u_config_t *c)
00690 {
00691 vhost_t *top, *vhost = NULL;
00692 u_config_t *child;
00693 const char *v;
00694
00695 dbg_err_if (http == NULL);
00696 dbg_err_if (host == NULL);
00697 dbg_err_if (c == NULL);
00698
00699 dbg_err_if(vhost_create(&vhost));
00700
00701 vhost->host = host;
00702 vhost->config = c;
00703 vhost->http = http;
00704
00705
00706 vhost->server_sig = "klone/" KLONE_VERSION;
00707 vhost->dir_root = "";
00708 vhost->index = NULL;
00709 vhost->send_enc_deflate = 0;
00710
00711
00712
00713 if((child = u_config_get_child(c, "access_log")) != NULL)
00714 {
00715 v = u_config_get_value(child);
00716
00717
00718 if(v == NULL || strcasecmp(v, "no"))
00719 dbg_err_if(klog_open_from_config(child, &vhost->klog));
00720
00721 vhost->al_config = child;
00722 } else {
00723
00724 if((top = vhost_list_get_n(http->vhosts, 0)) != NULL)
00725 {
00726
00727 vhost->klog = top->klog;
00728 vhost->al_config = top->al_config;
00729 }
00730 }
00731
00732
00733 dbg_err_if(u_config_get_subkey_value_b(c, "send_enc_deflate", 0,
00734 &vhost->send_enc_deflate));
00735
00736
00737 if((v = u_config_get_subkey_value(c, "server_sig")) != NULL)
00738 vhost->server_sig = v;
00739
00740
00741 if((v = u_config_get_subkey_value(c, "dir_root")) != NULL)
00742 vhost->dir_root = v;
00743 else
00744 crit_err("dir_root must be set (vhost: %s)", vhost->host);
00745
00746
00747 if((v = u_config_get_subkey_value(c, "index")) != NULL)
00748 vhost->index = v;
00749
00750 dbg_err_if(vhost_list_add(http->vhosts, vhost));
00751
00752 return 0;
00753 err:
00754 if(vhost)
00755 vhost_free(vhost);
00756 return ~0;
00757 }
00758
00759 static int config_inherit(u_config_t *dst, u_config_t *from)
00760 {
00761 static const char *dont_inherit[] = {
00762 "addr", "model", "type", "dir_root", "dir_alias", "script_alias",
00763 "access_log", NULL
00764 };
00765 u_config_t *config, *child = NULL;
00766 const char **di, *key, *value;
00767 int n;
00768
00769 dbg_err_if (dst == NULL);
00770 dbg_err_if (from == NULL);
00771
00772 for(n = 0; (config = u_config_get_child_n(from, NULL, n)); ++n)
00773 {
00774 if(u_config_get_child(config, "dir_root"))
00775 continue;
00776
00777 key = u_config_get_key(config);
00778 value = u_config_get_value(config);
00779
00780
00781 for(di = dont_inherit; *di; ++di)
00782 if(strcasecmp(*di, key) == 0)
00783 goto next;
00784
00785 dbg_err_if(u_config_add_child(dst, key, &child));
00786 dbg_err_if(u_config_set_value(child, value));
00787
00788 dbg_err_if(config_inherit(child, config));
00789
00790 next:;
00791 }
00792
00793 return 0;
00794 err:
00795 return ~0;
00796 }
00797
00798 static int http_set_vhost_list(http_t *http)
00799 {
00800 u_config_t *config;
00801 int n;
00802
00803 dbg_err_if (http == NULL);
00804
00805
00806 dbg_err_if(http_add_vhost(http, "", http->config));
00807
00808
00809 for(n = 0; (config = u_config_get_child_n(http->config, NULL, n)); ++n)
00810 {
00811 if(u_config_get_child(config, "dir_root") == NULL)
00812 continue;
00813
00814 dbg_err_if(u_config_get_key(config) == NULL);
00815
00816 u_info("configuring virtual host [%s]", u_config_get_key(config));
00817
00818
00819 dbg_err_if(config_inherit(config, http->config));
00820
00821 dbg_err_if(http_add_vhost(http, u_config_get_key(config), config));
00822 }
00823
00824 return 0;
00825 err:
00826 return ~0;
00827 }
00828
00829 static int http_create(u_config_t *config, http_t **ph)
00830 {
00831 http_t *h = NULL;
00832
00833 dbg_err_if (config == NULL);
00834 dbg_err_if (ph == NULL);
00835
00836 h = u_zalloc(sizeof(http_t));
00837 dbg_err_if(h == NULL);
00838
00839 h->config = config;
00840
00841 dbg_err_if(vhost_list_create(&h->vhosts));
00842
00843
00844 dbg_err_if(broker_create(&h->broker));
00845
00846
00847 dbg_err_if(http_set_vhost_list(h));
00848
00849
00850 if(ctx->debug > 1)
00851 u_config_print(ctx->config, 0);
00852
00853 *ph = h;
00854
00855 return 0;
00856 err:
00857 if(h)
00858 http_free(h);
00859 return ~0;
00860 }
00861
00862 static int http_backend_serve(struct backend_s *be, int fd)
00863 {
00864 http_t *h;
00865 int rc;
00866
00867 dbg_err_if (be == NULL);
00868 dbg_err_if (be->arg == NULL);
00869 dbg_err_if (fd < 0);
00870
00871 h = (http_t *) be->arg;
00872
00873
00874 rc = http_serve(h, fd);
00875
00876 return rc;
00877 err:
00878 return ~0;
00879 }
00880
00881 static int http_backend_term(struct backend_s *be)
00882 {
00883 http_t *http;
00884
00885 dbg_return_if (be == NULL, 0);
00886 dbg_return_if (be->arg == NULL, 0);
00887
00888 http = (http_t *) be->arg;
00889
00890 dbg_err_if(session_module_term(http->sess_opt));
00891
00892 http_free(http);
00893
00894 return 0;
00895 err:
00896 return ~0;
00897 }
00898
00899 static int http_backend_init(struct backend_s *be)
00900 {
00901 http_t *http = NULL;
00902 broker_t *broker = NULL;
00903
00904 dbg_err_if (be == NULL);
00905
00906 dbg_err_if(http_create(be->config, &http));
00907
00908 be->arg = http;
00909
00910 dbg_err_if(session_module_init(http->config, &http->sess_opt));
00911
00912 return 0;
00913 err:
00914 if(http)
00915 http_free(http);
00916 if(broker)
00917 broker_free(broker);
00918 return ~0;
00919 }
00920
00921 #ifdef SSL_ON
00922 static int https_backend_init(struct backend_s *be)
00923 {
00924 http_t *https;
00925
00926 dbg_err_if (be == NULL);
00927
00928 dbg_err_if(http_backend_init(be));
00929
00930 https = (http_t *) be->arg;
00931
00932
00933 https->ssl = 1;
00934
00935
00936 https->ssl_ctx = tls_load_init_ctx(http_get_config(https));
00937 warn_err_ifm (https->ssl_ctx == NULL, "bad or missing HTTPS credentials");
00938
00939 dbg_err_if(session_module_init(https->config, &https->sess_opt));
00940
00941 return 0;
00942 err:
00943 return ~0;
00944 }
00945
00946 static int https_backend_term(struct backend_s *be)
00947 {
00948 http_t *https;
00949
00950 dbg_err_if (be == NULL);
00951
00952 https = (http_t *) be->arg;
00953 if (https == NULL)
00954 return 0;
00955
00956 SSL_CTX_free(https->ssl_ctx);
00957
00958 return http_backend_term(be);
00959 err:
00960 return ~0;
00961 }
00962
00963
00964 backend_t be_https =
00965 BACKEND_STATIC_INITIALIZER( "https",
00966 https_backend_init,
00967 http_backend_serve,
00968 https_backend_term );
00969 #endif
00970
00971 backend_t be_http =
00972 BACKEND_STATIC_INITIALIZER( "http",
00973 http_backend_init,
00974 http_backend_serve,
00975 http_backend_term );
00976