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