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-2008  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 "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 
00031 /** @class DynamicFileWebReply "file_reply.h"
00032  * Dynamic raw file transfer reply.
00033  * This dynamic file transfer reply transmits the given file with a mime type
00034  * determined with libmagic.
00035  * @author Tim Niemueller
00036  */
00037 
00038 /** Constructor.
00039  * @param filename path and name of the file to transmit
00040  */
00041 DynamicFileWebReply::DynamicFileWebReply(const char *filename)
00042   : DynamicWebReply(WebReply::HTTP_OK)
00043 {
00044   if (access(filename, R_OK) != 0 || ((__file = fopen(filename, "r")) == NULL)) {
00045     throw fawkes::CouldNotOpenFileException(filename, errno);
00046   }
00047
00048   struct stat sbuf;
00049   fstat(fileno(__file), &sbuf);
00050
00051   if ( S_ISDIR(sbuf.st_mode) ) {
00052     throw fawkes::Exception("Cannot send directory\n");
00053   }
00054   __size = sbuf.st_size;
00055
00056   add_header("Content-type", fawkes::mimetype_file(filename));
00057 }
00058 
00059 /** Destructor. */
00060 DynamicFileWebReply::~DynamicFileWebReply()
00061 {
00062   fclose(__file);
00063 }
00064
00065 size_t
00066 DynamicFileWebReply::size()
00067 {
00068   return __size;
00069 }
00070
00071 size_t
00072 DynamicFileWebReply::next_chunk(size_t pos, char *buffer, size_t buf_max_size)
00073 {
00074   if ( (fseek(__file, pos, SEEK_SET) == -1) || feof(__file) ) {
00075     return (size_t)-1;
00076   }
00077   return fread(buffer, 1, buf_max_size, __file);
00078 }