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 <fcntl.h>
00016 #include <klone/supplier.h>
00017 #include <klone/io.h>
00018 #include <klone/utils.h>
00019
00020 static int fs_is_valid_uri(http_t *h, request_t *rq, const char *uri,
00021 size_t len, time_t *mtime)
00022 {
00023 struct stat st;
00024 char fqn[1+U_FILENAME_MAX];
00025
00026 dbg_return_if (uri == NULL, 0);
00027 dbg_return_if (mtime == NULL, 0);
00028 dbg_return_if (len > U_FILENAME_MAX, 0);
00029
00030 u_unused_args(h);
00031
00032 memcpy(fqn, uri, len);
00033 fqn[len] = 0;
00034
00035
00036 if(strstr(fqn, ".."))
00037 return 0;
00038
00039 if(stat(fqn, &st) == 0 && S_ISREG(st.st_mode))
00040 {
00041 *mtime = st.st_mtime;
00042
00043 return 1;
00044 } else
00045 return 0;
00046 }
00047
00048 static int fs_serve(request_t *rq, response_t *rs)
00049 {
00050 enum { BUFSZ = 4096 };
00051 io_t *io = NULL, *out = NULL;;
00052 const char *mime_type, *fqn;
00053 size_t c;
00054 char buf[BUFSZ];
00055 struct stat st;
00056
00057 dbg_err_if (rq == NULL);
00058 dbg_err_if (rs == NULL);
00059
00060
00061 out = response_io(rs);
00062 dbg_err_if(out == NULL);
00063
00064 fqn = request_get_resolved_filename(rq);
00065
00066
00067 dbg_err_if(stat(fqn, &st));
00068 dbg_err_if(response_set_content_length(rs, st.st_size));
00069
00070
00071 mime_type = u_guess_mime_type(fqn);
00072 dbg_err_if(response_set_content_type(rs, mime_type));
00073
00074
00075 dbg_err_if(response_set_last_modified(rs, st.st_mtime));
00076
00077
00078 dbg_err_if(response_print_header_to_io(rs, out));
00079
00080
00081 if(response_get_method(rs) == HM_HEAD)
00082 return 0;
00083
00084
00085 dbg_err_if(u_file_open(request_get_resolved_filename(rq), O_RDONLY, &io));
00086
00087 while((c = io_read(io, buf, BUFSZ)) > 0)
00088 dbg_err_if(io_write(out, buf, c) < 0);
00089
00090 io_free(io);
00091
00092 return 0;
00093 err:
00094 if(io)
00095 io_free(io);
00096 return ~0;
00097 }
00098
00099 static int fs_init(void)
00100 {
00101 return 0;
00102 }
00103
00104 static void fs_term(void)
00105 {
00106 return;
00107 }
00108
00109 supplier_t sup_fs = {
00110 "fs supplier",
00111 fs_init,
00112 fs_term,
00113 fs_is_valid_uri,
00114 fs_serve
00115 };
00116