sup_fs.c

00001 /*
00002  * Copyright (c) 2005-2012 by KoanLogic s.r.l. <http://www.koanlogic.com>
00003  * All rights reserved.
00004  *
00005  * This file is part of KLone, and as such it is subject to the license stated
00006  * in the LICENSE file which you have received as part of this distribution.
00007  *
00008  * $Id: sup_fs.c,v 1.14 2008/10/27 21:28:04 tat Exp $
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     /* fqn must be already normalized */
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     /* output stream */
00062     out = response_io(rs);
00063     dbg_err_if(out == NULL);
00064 
00065     fqn = request_get_resolved_filename(rq);
00066 
00067     /* we need file size */
00068     dbg_err_if(stat(fqn, &st));
00069     dbg_err_if(response_set_content_length(rs, st.st_size));
00070 
00071     /* guess the mime type append a Content-Type field to the response*/
00072     mime_type = u_guess_mime_type(fqn);
00073     dbg_err_if(response_set_content_type(rs, mime_type));
00074 
00075     /* add a Last-Modified field */
00076     dbg_err_if(response_set_last_modified(rs, st.st_mtime));
00077 
00078     /* print the reponse header */
00079     dbg_err_if(response_print_header_to_io(rs, out));
00080 
00081     /* if this's a HEAD request don't print the file content */
00082     if(response_get_method(rs) == HM_HEAD)
00083         return 0;
00084 
00085     /* open and write out the whole file */
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 

←Products
Copyright © 2005-2012 - KoanLogic S.r.l. - All rights reserved