broker.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <u/libu.h>
00012 #include <klone/supplier.h>
00013 #include <klone/broker.h>
00014 #include <klone/request.h>
00015 #include <klone/http.h>
00016 #include "klone_conf.h"
00017
00018 enum { MAX_SUP_COUNT = 8 };
00019
00020 extern supplier_t sup_emb;
00021 #ifdef ENABLE_SUP_KILT
00022 extern supplier_t sup_kilt;
00023 #endif
00024 #ifdef ENABLE_SUP_CGI
00025 extern supplier_t sup_cgi;
00026 #endif
00027 #ifdef ENABLE_SUP_FS
00028 extern supplier_t sup_fs;
00029 #endif
00030
00031 struct broker_s
00032 {
00033 supplier_t *sup_list[MAX_SUP_COUNT + 1];
00034 };
00035
00036 int broker_is_valid_uri(broker_t *b, http_t *h, request_t *rq, const char *buf,
00037 size_t len)
00038 {
00039 int i;
00040 time_t mtime;
00041 void *handle;
00042
00043 dbg_goto_if (b == NULL, notfound);
00044 dbg_goto_if (buf == NULL, notfound);
00045
00046 for(i = 0; b->sup_list[i]; ++i)
00047 {
00048 if(b->sup_list[i]->is_valid_uri(h, rq, buf, len, &handle, &mtime))
00049 {
00050 request_set_sup_info(rq, b->sup_list[i], handle, mtime);
00051 return 1;
00052 }
00053 }
00054 notfound:
00055 return 0;
00056 }
00057
00058 int broker_serve(broker_t *b, http_t *h, request_t *rq, response_t *rs)
00059 {
00060 const char *file_name;
00061 supplier_t *sup;
00062 void *handle;
00063 time_t mtime, ims;
00064 int i;
00065 int http_status;
00066
00067 dbg_err_if (b == NULL);
00068 dbg_err_if (rq == NULL);
00069 dbg_err_if (rs == NULL);
00070
00071
00072 request_get_sup_info(rq, &sup, &handle, &mtime);
00073
00074 if(sup == NULL)
00075 {
00076 file_name = request_get_resolved_filename(rq);
00077 for(i = 0; b->sup_list[i]; ++i)
00078 {
00079 if(b->sup_list[i]->is_valid_uri(h, rq, file_name, strlen(file_name),
00080 &handle, &mtime) )
00081 {
00082 sup = b->sup_list[i];
00083 break;
00084 }
00085 }
00086 nop_err_if (sup == NULL);
00087 }
00088
00089 ims = request_get_if_modified_since(rq);
00090 if(ims && mtime && ims >= mtime)
00091 {
00092 response_set_status(rs, HTTP_STATUS_NOT_MODIFIED);
00093 dbg_err_if(response_print_header(rs));
00094 } else {
00095 dbg_err_if(sup->serve(rq, rs));
00096
00097 http_status = response_get_status(rs);
00098
00099 if(http_status == HTTP_STATUS_EXT_KEY_NEEDED)
00100 return http_status;
00101
00102
00103 if(http_status >= 400 && sup != &sup_emb
00104 #ifdef ENABLE_SUP_KILT
00105 && sup!= &sup_kilt
00106 #endif
00107 )
00108 return http_status;
00109 }
00110
00111 return 0;
00112 err:
00113 response_set_status(rs, HTTP_STATUS_NOT_FOUND);
00114 u_dbg("404, file not found: %s", request_get_filename(rq));
00115
00116 return HTTP_STATUS_NOT_FOUND;
00117 }
00118
00119 int broker_create(broker_t **pb)
00120 {
00121 broker_t *b = NULL;
00122 int i;
00123
00124 dbg_err_if (pb == NULL);
00125
00126 b = u_zalloc(sizeof(broker_t));
00127 dbg_err_if(b == NULL);
00128
00129 i = 0;
00130 b->sup_list[i++] = &sup_emb;
00131
00132 #ifdef ENABLE_SUP_KILT
00133 b->sup_list[i++] = &sup_kilt;
00134 #else
00135 warn("Kilt support disabled, use --enable_kilt to enable it");
00136 #endif
00137
00138 #ifdef ENABLE_SUP_CGI
00139 b->sup_list[i++] = &sup_cgi;
00140 #else
00141 #ifndef OS_WIN
00142 warn("CGI support disabled, use --enable_cgi to enable it");
00143 #endif
00144 #endif
00145
00146 #ifdef ENABLE_SUP_FS
00147 b->sup_list[i++] = &sup_fs;
00148 #else
00149 warn("File system support disabled, use --enable_fs to enable it");
00150 #endif
00151
00152 b->sup_list[i++] = NULL;
00153
00154 for(i = 0; b->sup_list[i]; ++i)
00155 dbg_err_if(b->sup_list[i]->init());
00156
00157 *pb = b;
00158
00159 return 0;
00160 err:
00161 if(b)
00162 broker_free(b);
00163 return ~0;
00164 }
00165
00166 int broker_free(broker_t *b)
00167 {
00168 int i;
00169
00170 if (b)
00171 {
00172 for(i = 0; b->sup_list[i]; ++i)
00173 b->sup_list[i]->term();
00174
00175 U_FREE(b);
00176 }
00177
00178 return 0;
00179 }
00180