Fawkes API Fawkes Development Version
file_reply.cpp
1
2/***************************************************************************
3 * file_reply.cpp - Web request file reply
4 *
5 * Created: Thu Oct 23 14:00:17 2008
6 * Copyright 2006-2009 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * Read the full text in the LICENSE.GPL file in the doc directory.
21 */
22
23#include <core/exceptions/system.h>
24#include <sys/stat.h>
25#include <utils/system/filetype.h>
26#include <webview/file_reply.h>
27
28#include <cerrno>
29#include <unistd.h>
30
31namespace fawkes {
32
33/** @class DynamicFileWebReply <webview/file_reply.h>
34 * Dynamic raw file transfer reply.
35 * This dynamic file transfer reply transmits the given file with a mime type
36 * determined with libmagic.
37 * @author Tim Niemueller
38 */
39
40/** Constructor.
41 * @param filename path and name of the file to transmit
42 * @param content_type content type of file, will try to guess by
43 * magic if not given
44 */
45DynamicFileWebReply::DynamicFileWebReply(const std::string &filename,
46 const std::string &content_type)
47: DynamicWebReply(WebReply::HTTP_OK), close_when_done_(true)
48{
49 if (access(filename.c_str(), R_OK) != 0 || ((file_ = fopen(filename.c_str(), "r")) == NULL)) {
50 throw fawkes::CouldNotOpenFileException(filename.c_str(), errno);
51 }
52
53 determine_file_size();
54
55 if (content_type.empty()) {
56 add_header("Content-type", fawkes::mimetype_file(filename.c_str()));
57 } else {
58 add_header("Content-type", content_type);
59 }
60}
61
62/** Constructor.
63 * @param filename path and name of the file to transmit
64 */
66: DynamicWebReply(WebReply::HTTP_OK), close_when_done_(true)
67{
68 if (access(filename, R_OK) != 0 || ((file_ = fopen(filename, "r")) == NULL)) {
69 throw fawkes::CouldNotOpenFileException(filename, errno);
70 }
71
72 determine_file_size();
73
74 add_header("Content-type", fawkes::mimetype_file(filename));
75}
76
77/** Constructor.
78 * @param file file handle of file to transmit
79 * @param close_when_done true to close file after transmission is completed
80 */
81DynamicFileWebReply::DynamicFileWebReply(FILE *file, bool close_when_done)
82: DynamicWebReply(WebReply::HTTP_OK), file_(file), close_when_done_(close_when_done)
83{
84 fseek(file_, 0, SEEK_SET);
85 determine_file_size();
86 try {
87 add_header("Content-type", fawkes::mimetype_file(dup(fileno(file_))));
88 } catch (Exception &e) {
89 } // ignored
90 fseek(file_, 0, SEEK_SET);
91}
92
93/** Destructor. */
95{
96 if (close_when_done_)
97 fclose(file_);
98 file_ = NULL;
99}
100
101void
102DynamicFileWebReply::determine_file_size()
103{
104 struct stat sbuf;
105 fstat(fileno(file_), &sbuf);
106
107 if (S_ISDIR(sbuf.st_mode)) {
108 throw fawkes::Exception("Cannot send directory\n");
109 }
110 size_ = sbuf.st_size;
111}
112
113size_t
115{
116 return size_;
117}
118
119size_t
120DynamicFileWebReply::next_chunk(size_t pos, char *buffer, size_t buf_max_size)
121{
122 if ((fseek(file_, pos, SEEK_SET) == -1) || feof(file_)) {
123 return (size_t)-1;
124 }
125 return fread(buffer, 1, buf_max_size, file_);
126}
127
128} // end namespace fawkes
File could not be opened.
Definition: system.h:53
DynamicFileWebReply(const std::string &filename, const std::string &content_type="")
Constructor.
Definition: file_reply.cpp:45
virtual size_t next_chunk(size_t pos, char *buffer, size_t buf_max_size)
Get data of next chunk.
Definition: file_reply.cpp:120
virtual size_t size()
Total size of the web reply.
Definition: file_reply.cpp:114
virtual ~DynamicFileWebReply()
Destructor.
Definition: file_reply.cpp:94
Dynamic web reply.
Definition: reply.h:126
Base class for exceptions in Fawkes.
Definition: exception.h:36
Basic web reply.
Definition: reply.h:34
void add_header(const std::string &header, const std::string &content)
Add a HTTP header.
Definition: reply.cpp:123
Fawkes library namespace.
std::string mimetype_file(const char *filename)
Get mime-type of file.
Definition: filetype.cpp:111