Fawkes API  Fawkes Development Version
file_reply.cpp
00001 
00002 /***************************************************************************
00003  *  file_reply.cpp - Web request file reply
00004  *
00005  *  Created: Thu Oct 23 14:00:17 2008
00006  *  Copyright  2006-2009  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 #include <webview/file_reply.h>
00024 
00025 #include <core/exceptions/system.h>
00026 #include <utils/system/filetype.h>
00027 
00028 #include <cerrno>
00029 #include <sys/stat.h>
00030 #include <unistd.h>
00031 
00032 namespace fawkes {
00033 #if 0 /* just to make Emacs auto-indent happy */
00034 }
00035 #endif
00036 
00037 /** @class DynamicFileWebReply <webview/file_reply.h>
00038  * Dynamic raw file transfer reply.
00039  * This dynamic file transfer reply transmits the given file with a mime type
00040  * determined with libmagic.
00041  * @author Tim Niemueller
00042  */
00043 
00044 /** Constructor.
00045  * @param filename path and name of the file to transmit
00046  */
00047 DynamicFileWebReply::DynamicFileWebReply(const char *filename)
00048   : DynamicWebReply(WebReply::HTTP_OK)
00049 {
00050   if (access(filename, R_OK) != 0 || ((__file = fopen(filename, "r")) == NULL)) {
00051     throw fawkes::CouldNotOpenFileException(filename, errno);
00052   }
00053 
00054   struct stat sbuf;
00055   fstat(fileno(__file), &sbuf);
00056 
00057   if ( S_ISDIR(sbuf.st_mode) ) {
00058     throw fawkes::Exception("Cannot send directory\n");
00059   }
00060   __size = sbuf.st_size;
00061 
00062   add_header("Content-type", fawkes::mimetype_file(filename));
00063 }
00064 
00065 /** Destructor. */
00066 DynamicFileWebReply::~DynamicFileWebReply()
00067 {
00068   fclose(__file);
00069 }
00070 
00071 size_t
00072 DynamicFileWebReply::size()
00073 {
00074   return __size;
00075 }
00076 
00077 size_t
00078 DynamicFileWebReply::next_chunk(size_t pos, char *buffer, size_t buf_max_size)
00079 {
00080   if ( (fseek(__file, pos, SEEK_SET) == -1) || feof(__file) ) {
00081     return (size_t)-1;
00082   }
00083   return fread(buffer, 1, buf_max_size, __file);
00084 }
00085 
00086 } // end namespace fawkes