pion  5.0.6
FileService.hpp
1 // ---------------------------------------------------------------------
2 // pion: a Boost C++ framework for building lightweight HTTP interfaces
3 // ---------------------------------------------------------------------
4 // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion)
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
8 //
9 
10 #ifndef __PION_FILESERVICE_HEADER__
11 #define __PION_FILESERVICE_HEADER__
12 
13 #include <boost/shared_ptr.hpp>
14 #include <boost/functional/hash.hpp>
15 #include <boost/filesystem/path.hpp>
16 #include <boost/thread/once.hpp>
17 #include <boost/thread/mutex.hpp>
18 #include <boost/shared_array.hpp>
19 #include <pion/config.hpp>
20 #include <pion/logger.hpp>
21 #include <pion/hash_map.hpp>
22 #include <pion/http/plugin_service.hpp>
23 #include <pion/http/request.hpp>
24 #include <pion/http/response_writer.hpp>
25 #include <pion/http/server.hpp>
26 #include <string>
27 #include <map>
28 
29 
30 namespace pion { // begin namespace pion
31 namespace plugins { // begin namespace plugins
32 
33 
37 class DiskFile {
38 public:
40  DiskFile(void)
41  : m_file_size(0), m_last_modified(0) {}
42 
44  DiskFile(const boost::filesystem::path& path,
45  char *content, unsigned long size,
46  std::time_t modified, const std::string& mime)
47  : m_file_path(path), m_file_content(content), m_file_size(size),
48  m_last_modified(modified), m_mime_type(mime)
49  {}
50 
52  DiskFile(const DiskFile& f)
56  {}
57 
59  void update(void);
60 
62  void read(void);
63 
69  bool checkUpdated(void);
70 
72  inline const boost::filesystem::path& getFilePath(void) const { return m_file_path; }
73 
75  inline char *getFileContent(void) { return m_file_content.get(); }
76 
78  inline bool hasFileContent(void) const { return static_cast<bool>(m_file_content); }
79 
81  inline unsigned long getFileSize(void) const { return m_file_size; }
82 
84  inline std::time_t getLastModified(void) const { return m_last_modified; }
85 
87  inline const std::string& getLastModifiedString(void) const { return m_last_modified_string; }
88 
90  inline const std::string& getMimeType(void) const { return m_mime_type; }
91 
93  inline void setFilePath(const boost::filesystem::path& p) { m_file_path = p; }
94 
96  inline void appendFilePath(const std::string& p) { m_file_path /= p; }
97 
99  inline void setMimeType(const std::string& t) { m_mime_type = t; }
100 
102  inline void resetFileContent(unsigned long n = 0) {
103  if (n == 0) m_file_content.reset();
104  else m_file_content.reset(new char[n]);
105  }
106 
107 
108 protected:
109 
111  boost::filesystem::path m_file_path;
112 
114  boost::shared_array<char> m_file_content;
115 
117  std::streamsize m_file_size;
118 
120  std::time_t m_last_modified;
121 
124 
126  std::string m_mime_type;
127 };
128 
129 
134  public boost::enable_shared_from_this<DiskFileSender>,
135  private boost::noncopyable
136 {
137 public:
146  static inline boost::shared_ptr<DiskFileSender>
148  const pion::http::request_ptr& http_request_ptr,
149  const pion::tcp::connection_ptr& tcp_conn,
150  unsigned long max_chunk_size = 0)
151  {
152  return boost::shared_ptr<DiskFileSender>(new DiskFileSender(file, http_request_ptr,
153  tcp_conn, max_chunk_size));
154  }
155 
157  virtual ~DiskFileSender() {}
158 
162  void send(void);
163 
165  inline void set_logger(logger log_ptr) { m_logger = log_ptr; }
166 
168  inline logger get_logger(void) { return m_logger; }
169 
170 
171 protected:
172 
181  DiskFileSender(DiskFile& file,
182  const pion::http::request_ptr& http_request_ptr,
183  const pion::tcp::connection_ptr& tcp_conn,
184  unsigned long max_chunk_size);
185 
192  void handle_write(const boost::system::error_code& write_error,
193  std::size_t bytes_written);
194 
195 
198 
199 
200 private:
201 
203  DiskFile m_disk_file;
204 
206  pion::http::response_writer_ptr m_writer;
207 
209  boost::filesystem::ifstream m_file_stream;
210 
212  boost::shared_array<char> m_content_buf;
213 
219  unsigned long m_max_chunk_size;
220 
222  unsigned long m_file_bytes_to_send;
223 
225  unsigned long m_bytes_sent;
226 };
227 
229 typedef boost::shared_ptr<DiskFileSender> DiskFileSenderPtr;
230 
231 
235 class FileService :
237 {
238 public:
239 
240  // default constructor and destructor
241  FileService(void);
242  virtual ~FileService() {}
243 
254  virtual void set_option(const std::string& name, const std::string& value);
255 
257  virtual void operator()(const pion::http::request_ptr& http_request_ptr,
258  const pion::tcp::connection_ptr& tcp_conn);
259 
261  virtual void start(void);
262 
264  virtual void stop(void);
265 
267  inline void set_logger(logger log_ptr) { m_logger = log_ptr; }
268 
270  inline logger get_logger(void) { return m_logger; }
271 
272 
273 protected:
274 
276  typedef PION_HASH_MAP<std::string, DiskFile, PION_HASH_STRING > CacheMap;
277 
279  typedef PION_HASH_MAP<std::string, std::string, PION_HASH_STRING > MIMETypeMap;
280 
286  void scanDirectory(const boost::filesystem::path& dir_path);
287 
298  std::pair<CacheMap::iterator, bool>
299  addCacheEntry(const std::string& relative_path,
300  const boost::filesystem::path& file_path,
301  const bool placeholder);
302 
309  static std::string findMIMEType(const std::string& file_name);
310 
311  void sendNotFoundResponse(const pion::http::request_ptr& http_request_ptr,
312  const pion::tcp::connection_ptr& tcp_conn);
313 
316 
317 
318 private:
319 
321  static void createMIMETypes(void);
322 
323 
325  static const std::string DEFAULT_MIME_TYPE;
326 
328  static const unsigned int DEFAULT_CACHE_SETTING;
329 
331  static const unsigned int DEFAULT_SCAN_SETTING;
332 
334  static const unsigned long DEFAULT_MAX_CACHE_SIZE;
335 
337  static const unsigned long DEFAULT_MAX_CHUNK_SIZE;
338 
340  static boost::once_flag m_mime_types_init_flag;
341 
343  static MIMETypeMap * m_mime_types_ptr;
344 
345 
347  boost::filesystem::path m_directory;
348 
350  boost::filesystem::path m_file;
351 
353  CacheMap m_cache_map;
354 
356  boost::mutex m_cache_mutex;
357 
364  unsigned int m_cache_setting;
365 
373  unsigned int m_scan_setting;
374 
379  unsigned long m_max_cache_size;
380 
386  unsigned long m_max_chunk_size;
387 
391  bool m_writable;
392 };
393 
394 
395 } // end namespace plugins
396 } // end namespace pion
397 
398 #endif
DiskFile(void)
default constructor
Definition: FileService.hpp:40
std::streamsize m_file_size
size of the file&#39;s content
virtual ~DiskFileSender()
default virtual destructor
void setFilePath(const boost::filesystem::path &p)
sets the path to the cached file
Definition: FileService.hpp:93
void setMimeType(const std::string &t)
sets the mime type for the cached file
Definition: FileService.hpp:99
std::string m_last_modified_string
timestamp that the cached file was last modified (string format)
void read(void)
reads content from disk into file_content buffer (may throw)
DiskFile(const boost::filesystem::path &path, char *content, unsigned long size, std::time_t modified, const std::string &mime)
used to construct new disk file objects
Definition: FileService.hpp:44
void update(void)
updates the file_size and last_modified timestamp to disk
std::time_t getLastModified(void) const
returns timestamp that the cached file was last modified (0 = cache disabled)
Definition: FileService.hpp:84
const boost::filesystem::path & getFilePath(void) const
return path to the cached file
Definition: FileService.hpp:72
const std::string & getLastModifiedString(void) const
returns timestamp that the cached file was last modified (string format)
Definition: FileService.hpp:87
DiskFile(const DiskFile &f)
copy constructor
Definition: FileService.hpp:52
const std::string & getMimeType(void) const
returns mime type for the cached file
Definition: FileService.hpp:90
void set_logger(logger log_ptr)
sets the logger to be used
logger m_logger
primary logging interface used by this class
logger m_logger
primary logging interface used by this class
void resetFileContent(unsigned long n=0)
resets the size of the file content buffer
unsigned long getFileSize(void) const
returns size of the file&#39;s content
Definition: FileService.hpp:81
logger get_logger(void)
returns the logger currently in use
PION_HASH_MAP< std::string, DiskFile, PION_HASH_STRING > CacheMap
data type for map of file names to cache entries
boost::filesystem::path m_file_path
path to the cached file
void set_logger(logger log_ptr)
sets the logger to be used
std::time_t m_last_modified
timestamp that the cached file was last modified (0 = cache disabled)
logger get_logger(void)
returns the logger currently in use
bool hasFileContent(void) const
returns true if there is cached file content
Definition: FileService.hpp:78
static boost::shared_ptr< DiskFileSender > create(DiskFile &file, const pion::http::request_ptr &http_request_ptr, const pion::tcp::connection_ptr &tcp_conn, unsigned long max_chunk_size=0)
char * getFileContent(void)
returns content of the cached file
Definition: FileService.hpp:75
void appendFilePath(const std::string &p)
appends to the path of the cached file
Definition: FileService.hpp:96
boost::shared_array< char > m_file_content
content of the cached file
PION_HASH_MAP< std::string, std::string, PION_HASH_STRING > MIMETypeMap
data type for map of file extensions to MIME types
std::string m_mime_type
mime type for the cached file