00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "klone_conf.h"
00012 #include <sys/stat.h>
00013 #include <sys/types.h>
00014 #include <unistd.h>
00015 #include <u/libu.h>
00016 #include <klone/supplier.h>
00017 #include <klone/io.h>
00018 #include <klone/page.h>
00019 #include <klone/http.h>
00020 #include <klone/emb.h>
00021 #include <klone/codecs.h>
00022 #include <klone/ses_prv.h>
00023 #include <klone/rsfilter.h>
00024 #include "http_s.h"
00025
00026 static int supemb_is_valid_uri(const char *uri, size_t len, time_t *mtime)
00027 {
00028 embres_t *e;
00029 char filename[U_FILENAME_MAX] = { 0 };
00030
00031 dbg_err_if (uri == NULL);
00032 dbg_err_if (mtime == NULL);
00033 dbg_err_if (len >= U_FILENAME_MAX);
00034
00035 strncpy(filename, uri, len);
00036
00037 if(emb_lookup(filename, &e) == 0)
00038 {
00039
00040 if(e->type == ET_FILE)
00041 *mtime = ((embfile_t*)e)->mtime;
00042 else
00043 *mtime = 0;
00044
00045 return 1;
00046 }
00047
00048 err:
00049 return 0;
00050 }
00051
00052 static int supemb_get_cipher_key(request_t *rq, response_t *rs, char *key,
00053 size_t keysz)
00054 {
00055 session_t *ss = NULL;
00056 http_t *http = NULL;
00057 session_opt_t *so;
00058 vars_t *vars;
00059 var_t *v;
00060
00061 dbg_err_if (rq == NULL);
00062 dbg_err_if (rs == NULL);
00063 dbg_err_if (key == NULL);
00064
00065
00066 dbg_err_if((http = request_get_http(rq)) == NULL);
00067 dbg_err_if((so = http_get_session_opt(http)) == NULL);
00068
00069
00070 dbg_err_if(session_create(so, rq, rs, &ss));
00071
00072
00073 vars = session_get_vars(ss);
00074 dbg_err_if(vars == NULL);
00075
00076 v = vars_geti(vars,"KLONE_CIPHER_KEY", 0);
00077 dbg_err_if(v == NULL);
00078
00079 dbg_err_if(var_get_value_size(v) > keysz);
00080
00081
00082 memset(key, 0, keysz);
00083
00084
00085 memcpy(key, var_get_value(v), var_get_value_size(v));
00086
00087 session_free(ss);
00088
00089 return 0;
00090 err:
00091 if(ss)
00092 session_free(ss);
00093 return ~0;
00094 }
00095
00096 static int supemb_static_set_header_fields(request_t *rq, response_t *rs,
00097 embfile_t *e, int *sai)
00098 {
00099 http_t *http;
00100
00101 dbg_err_if (rq == NULL);
00102 dbg_err_if (rs == NULL);
00103 dbg_err_if (e == NULL);
00104 dbg_err_if (sai == NULL);
00105
00106 dbg_err_if((http = request_get_http(rq)) == NULL);
00107
00108
00109
00110
00111 dbg_err_if(response_set_content_type(rs, e->mime_type));
00112 dbg_err_if(response_set_last_modified(rs, e->mtime));
00113 dbg_err_if(response_set_content_length(rs, e->file_size));
00114
00115
00116
00117 if(http->send_enc_deflate)
00118 {
00119 if(e->comp && (*sai = request_is_encoding_accepted(rq, "deflate")) != 0)
00120 {
00121 dbg_err_if(response_set_content_encoding(rs, "deflate"));
00122 dbg_err_if(response_set_content_length(rs, e->size));
00123
00124 }
00125 }
00126
00127 return 0;
00128 err:
00129 return ~0;
00130 }
00131
00132 static int supemb_serve_static(request_t *rq, response_t *rs, embfile_t *e)
00133 {
00134 codec_t *gzip = NULL, *decrypt = NULL;
00135 int sai = 0;
00136 int decrypting = 0;
00137 char key[CODEC_CIPHER_KEY_SIZE];
00138 codec_t *rsf = NULL;
00139
00140 dbg_return_if (rq == NULL, ~0);
00141 dbg_return_if (rs == NULL, ~0);
00142 dbg_return_if (e == NULL, 0);
00143
00144
00145
00146
00147
00148 dbg_err_if(response_filter_create(rq, rs, NULL, &rsf));
00149 dbg_err_if(io_codec_add_tail(response_io(rs), rsf));
00150 rsf = NULL;
00151
00152
00153 dbg_err_if(supemb_static_set_header_fields(rq, rs, e, &sai));
00154
00155
00156 if(request_get_method(rq) == HM_HEAD)
00157 return 0;
00158
00159 #ifdef HAVE_LIBZ
00160
00161 if(e->comp && !sai)
00162 dbg_err_if(codec_gzip_create(GZIP_UNCOMPRESS, &gzip));
00163 #endif
00164
00165 #ifdef HAVE_LIBOPENSSL
00166
00167
00168 if(e->encrypted)
00169 {
00170 if(supemb_get_cipher_key(rq, rs, key, CODEC_CIPHER_KEY_SIZE))
00171 {
00172 dbg_err_if(response_set_status(rs, 401));
00173 dbg_err("cipher key not found, aborting");
00174 }
00175 dbg_err_if(codec_cipher_create(CIPHER_DECRYPT, EVP_aes_256_cbc(),
00176 key, NULL, &decrypt));
00177
00178 memset(key, 0, CODEC_CIPHER_KEY_SIZE);
00179 }
00180 #endif
00181
00182 if(gzip)
00183 {
00184 dbg_err_if(io_codec_add_head(response_io(rs), gzip));
00185 gzip = NULL;
00186 }
00187
00188 if(decrypt)
00189 {
00190 dbg_err_if(io_codec_add_head(response_io(rs), decrypt));
00191 decrypt = NULL;
00192 decrypting = 1;
00193 }
00194
00195
00196
00197 dbg_err_if(!io_write(response_io(rs), (const char*)e->data, e->size));
00198
00199
00200 dbg_err_if(io_codecs_remove(response_io(rs)));
00201
00202 return 0;
00203 err:
00204 if(decrypting)
00205 dbg_if(response_set_status(rs, 401));
00206
00207 dbg_if(io_codecs_remove(response_io(rs)));
00208 if(decrypt)
00209 codec_free(decrypt);
00210 if(gzip)
00211 codec_free(gzip);
00212 return ~0;
00213 }
00214
00215 static int supemb_serve_dynamic(request_t *rq, response_t *rs, embpage_t *e)
00216 {
00217 session_t *ss = NULL;
00218 http_t *http = NULL;
00219 codec_t *filter = NULL;
00220 session_opt_t *so;
00221
00222 dbg_return_if (rq == NULL, ~0);
00223 dbg_return_if (rs == NULL, ~0);
00224 dbg_return_if (e == NULL, ~0);
00225
00226
00227 dbg_err_if((http = request_get_http(rq)) == NULL);
00228 dbg_err_if((so = http_get_session_opt(http)) == NULL);
00229
00230
00231 dbg_err_if(session_create(so, rq, rs, &ss));
00232
00233
00234 dbg_err_if(response_set_content_type(rs, "text/html"));
00235
00236
00237 response_disable_caching(rs);
00238
00239
00240
00241 dbg_err_if(response_filter_create(rq, rs, ss, &filter));
00242 io_codec_add_tail(response_io(rs), filter);
00243
00244
00245 e->run(rq, rs, ss);
00246
00247
00248 io_flush(response_io(rs));
00249
00250
00251 session_free(ss);
00252
00253 return 0;
00254 err:
00255 io_flush(response_io(rs));
00256 if(ss)
00257 session_free(ss);
00258 return ~0;
00259 }
00260
00261 static int supemb_serve(request_t *rq, response_t *rs)
00262 {
00263 const char *file_name;
00264 embres_t *e;
00265
00266 dbg_err_if (rq == NULL);
00267 dbg_err_if (rs == NULL);
00268
00269 file_name = request_get_resolved_filename(rq);
00270 dbg_ifb(file_name == NULL || emb_lookup(file_name, &e))
00271 {
00272 response_set_status(rs, HTTP_STATUS_NOT_FOUND);
00273 return 0;
00274 }
00275
00276
00277
00278 switch(e->type)
00279 {
00280 case ET_FILE:
00281 dbg_err_if(supemb_serve_static(rq, rs, (embfile_t*)e));
00282 break;
00283 case ET_PAGE:
00284 dbg_err_if(supemb_serve_dynamic(rq, rs, (embpage_t*)e));
00285 break;
00286 default:
00287 dbg_err_if("unknown res type");
00288 }
00289
00290 return 0;
00291 err:
00292 return ~0;
00293 }
00294
00295 static int supemb_init(void)
00296 {
00297 return 0;
00298 }
00299
00300 static void supemb_term(void)
00301 {
00302 return;
00303 }
00304
00305 supplier_t sup_emb = {
00306 "embedded content supplier",
00307 supemb_init,
00308 supemb_term,
00309 supemb_is_valid_uri,
00310 supemb_serve
00311 };
00312