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