]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | /* |
2 | * This file is open source software, licensed to you under the terms | |
3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file | |
4 | * distributed with this work for additional information regarding copyright | |
5 | * ownership. You may not use this file except in compliance with the License. | |
6 | * | |
7 | * You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, | |
12 | * software distributed under the License is distributed on an | |
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
14 | * KIND, either express or implied. See the License for the | |
15 | * specific language governing permissions and limitations | |
16 | * under the License. | |
17 | */ | |
18 | /* | |
19 | * Copyright 2015 Cloudius Systems | |
20 | */ | |
21 | ||
22 | #pragma once | |
23 | ||
24 | #include <seastar/http/handlers.hh> | |
25 | #include <seastar/core/iostream.hh> | |
26 | ||
27 | namespace seastar { | |
28 | ||
29 | namespace httpd { | |
30 | ||
31 | /** | |
32 | * This is a base class for file transformer. | |
33 | * | |
34 | * File transformer adds the ability to modify a file content before returning | |
35 | * the results, it acts as a factory class for output_stream. | |
36 | * | |
37 | * The transformer decides according to the file extension if transforming is | |
38 | * needed. | |
39 | * | |
40 | * If a transformation is needed it would create a new output stream from the given stream. | |
41 | */ | |
42 | class file_transformer { | |
43 | public: | |
44 | /** | |
45 | * Any file transformer should implement this method. | |
46 | * @param req the request | |
47 | * @param extension the file extension originating the content | |
48 | * returns a new output stream to be used when writing the file to the reply | |
49 | */ | |
1e59de90 | 50 | virtual output_stream<char> transform(std::unique_ptr<http::request> req, |
11fdf7f2 TL |
51 | const sstring& extension, output_stream<char>&& s) = 0; |
52 | ||
53 | virtual ~file_transformer() = default; | |
54 | }; | |
55 | ||
56 | /** | |
57 | * A base class for handlers that interact with files. | |
58 | * directory and file handlers both share some common logic | |
59 | * with regards to file handling. | |
60 | * they both needs to read a file from the disk, optionally transform it, | |
61 | * and return the result or page not found on error | |
62 | */ | |
63 | class file_interaction_handler : public handler_base { | |
64 | public: | |
65 | file_interaction_handler(file_transformer* p = nullptr) | |
66 | : transformer(p) { | |
67 | ||
68 | } | |
69 | ||
70 | ~file_interaction_handler(); | |
71 | ||
72 | /** | |
73 | * Allows setting a transformer to be used with the files returned. | |
74 | * @param t the file transformer to use | |
75 | * @return this | |
76 | */ | |
77 | file_interaction_handler* set_transformer(file_transformer* t) { | |
78 | transformer = t; | |
79 | return this; | |
80 | } | |
81 | ||
82 | /** | |
83 | * if the url ends without a slash redirect | |
84 | * @param req the request | |
85 | * @param rep the reply | |
86 | * @return true on redirect | |
87 | */ | |
1e59de90 | 88 | bool redirect_if_needed(const http::request& req, http::reply& rep) const; |
11fdf7f2 TL |
89 | |
90 | /** | |
91 | * A helper method that returns the file extension. | |
92 | * @param file the file to check | |
93 | * @return the file extension | |
94 | */ | |
95 | static sstring get_extension(const sstring& file); | |
96 | ||
97 | protected: | |
98 | ||
99 | /** | |
100 | * read a file from the disk and return it in the replay. | |
101 | * @param file the full path to a file on the disk | |
102 | * @param req the reuest | |
103 | * @param rep the reply | |
104 | */ | |
1e59de90 TL |
105 | future<std::unique_ptr<http::reply> > read(sstring file, |
106 | std::unique_ptr<http::request> req, std::unique_ptr<http::reply> rep); | |
11fdf7f2 TL |
107 | file_transformer* transformer; |
108 | ||
1e59de90 | 109 | output_stream<char> get_stream(std::unique_ptr<http::request> req, |
11fdf7f2 TL |
110 | const sstring& extension, output_stream<char>&& s); |
111 | }; | |
112 | ||
113 | /** | |
114 | * The directory handler get a disk path in the | |
115 | * constructor. | |
116 | * and expect a path parameter in the handle method. | |
117 | * it would concatenate the two and return the file | |
118 | * e.g. if the path is /usr/mgmt/public in the path | |
119 | * parameter is index.html | |
120 | * handle will return the content of /usr/mgmt/public/index.html | |
121 | */ | |
122 | class directory_handler : public file_interaction_handler { | |
123 | public: | |
124 | ||
125 | /** | |
126 | * The directory handler map a base path and a path parameter to a file | |
127 | * @param doc_root the root directory to search the file from. | |
f67539c2 | 128 | * @param transformer an optional file transformer |
11fdf7f2 TL |
129 | * For example if the root is '/usr/mgmt/public' and the path parameter |
130 | * will be '/css/style.css' the file wil be /usr/mgmt/public/css/style.css' | |
131 | */ | |
132 | explicit directory_handler(const sstring& doc_root, | |
133 | file_transformer* transformer = nullptr); | |
134 | ||
1e59de90 TL |
135 | future<std::unique_ptr<http::reply>> handle(const sstring& path, |
136 | std::unique_ptr<http::request> req, std::unique_ptr<http::reply> rep) override; | |
11fdf7f2 TL |
137 | |
138 | private: | |
139 | sstring doc_root; | |
140 | }; | |
141 | ||
142 | /** | |
143 | * The file handler get a path to a file on the disk | |
144 | * in the constructor. | |
145 | * it will always return the content of the file. | |
146 | */ | |
147 | class file_handler : public file_interaction_handler { | |
148 | public: | |
149 | ||
150 | /** | |
151 | * The file handler map a file to a url | |
152 | * @param file the full path to the file on the disk | |
f67539c2 TL |
153 | * @param transformer an optional file transformer |
154 | * @param force_path check if redirect is needed upon `handle` | |
11fdf7f2 TL |
155 | */ |
156 | explicit file_handler(const sstring& file, file_transformer* transformer = | |
157 | nullptr, bool force_path = true) | |
158 | : file_interaction_handler(transformer), file(file), force_path( | |
159 | force_path) { | |
160 | } | |
161 | ||
1e59de90 TL |
162 | future<std::unique_ptr<http::reply>> handle(const sstring& path, |
163 | std::unique_ptr<http::request> req, std::unique_ptr<http::reply> rep) override; | |
11fdf7f2 TL |
164 | |
165 | private: | |
166 | sstring file; | |
167 | bool force_path; | |
168 | }; | |
169 | ||
170 | } | |
171 | ||
172 | } |