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