comparison Core/HttpServer/FilesystemHttpHandler.cpp @ 0:3959d33612cc

initial commit
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 19 Jul 2012 14:32:22 +0200
parents
children 9be852ad33d2
comparison
equal deleted inserted replaced
-1:000000000000 0:3959d33612cc
1 /**
2 * Palantir - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012 Medical Physics Department, CHU of Liege,
4 * Belgium
5 *
6 * This program is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 **/
19
20
21 #include "FilesystemHttpHandler.h"
22
23 #include "../PalantirException.h"
24
25 #include <boost/filesystem.hpp>
26
27
28 namespace Palantir
29 {
30 struct FilesystemHttpHandler::PImpl
31 {
32 UriComponents baseUri_;
33 boost::filesystem::path root_;
34 };
35
36
37
38 static void OutputDirectoryContent(HttpOutput& output,
39 const UriComponents& uri,
40 const boost::filesystem::path& p)
41 {
42 namespace fs = boost::filesystem;
43
44 output.SendOkHeader("text/html");
45 output.SendString("<html>");
46 output.SendString(" <body>");
47 output.SendString(" <h1>Subdirectories</h1>");
48 output.SendString(" <ul>");
49
50 if (uri.size() > 0)
51 {
52 std::string h = Toolbox::FlattenUri(uri) + "/..";
53 output.SendString("<li><a href=\"" + h + "\">..</a></li>");
54 }
55
56 fs::directory_iterator end;
57 for (fs::directory_iterator it(p) ; it != end; ++it)
58 {
59 std::string f = it->path().filename().string();
60 std::string h = Toolbox::FlattenUri(uri) + "/" + f;
61 if (fs::is_directory(it->status()))
62 output.SendString("<li><a href=\"" + h + "\">" + f + "</a></li>");
63 }
64
65 output.SendString(" </ul>");
66 output.SendString(" <h1>Files</h1>");
67 output.SendString(" <ul>");
68
69 for (fs::directory_iterator it(p) ; it != end; ++it)
70 {
71 std::string f = it->path().filename().string();
72 std::string h = Toolbox::FlattenUri(uri) + "/" + f;
73 if (fs::is_regular_file(it->status()))
74 output.SendString("<li><a href=\"" + h + "\">" + f + "</a></li>");
75 }
76
77 output.SendString(" </ul>");
78 output.SendString(" </body>");
79 output.SendString("</html>");
80 }
81
82
83 FilesystemHttpHandler::FilesystemHttpHandler(const std::string& baseUri,
84 const std::string& root) : pimpl_(new PImpl)
85 {
86 Toolbox::SplitUriComponents(pimpl_->baseUri_, baseUri);
87 pimpl_->root_ = root;
88 listDirectoryContent_ = false;
89
90 namespace fs = boost::filesystem;
91 if (!fs::exists(pimpl_->root_) ||
92 !fs::is_directory(pimpl_->root_))
93 {
94 throw PalantirException("The path does not point to a directory");
95 }
96 }
97
98
99 bool FilesystemHttpHandler::IsServedUri(const UriComponents& uri)
100 {
101 return Toolbox::IsChildUri(pimpl_->baseUri_, uri);
102 }
103
104
105 void FilesystemHttpHandler::Handle(
106 HttpOutput& output,
107 const std::string& method,
108 const UriComponents& uri,
109 const Arguments& headers,
110 const Arguments& arguments,
111 const std::string&)
112 {
113 if (method != "GET")
114 {
115 output.SendMethodNotAllowedError("GET");
116 return;
117 }
118
119 namespace fs = boost::filesystem;
120
121 fs::path p = pimpl_->root_;
122 for (size_t i = pimpl_->baseUri_.size(); i < uri.size(); i++)
123 {
124 p /= uri[i];
125 }
126
127 if (fs::exists(p) && fs::is_regular_file(p))
128 {
129 output.AnswerFileAutodetectContentType(p.string());
130 }
131 else if (listDirectoryContent_ &&
132 fs::exists(p) &&
133 fs::is_directory(p))
134 {
135 OutputDirectoryContent(output, uri, p);
136 }
137 else
138 {
139 output.SendHeader(HttpStatus_404_NotFound);
140 }
141 }
142 }