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