]>
git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/src/http/file_handler.cc
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.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
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
19 * Copyright 2015 Cloudius Systems
22 #include <seastar/http/file_handler.hh>
23 #include <seastar/core/seastar.hh>
26 #include <seastar/core/reactor.hh>
27 #include <seastar/core/fstream.hh>
28 #include <seastar/core/shared_ptr.hh>
29 #include <seastar/core/app-template.hh>
30 #include <seastar/http/exception.hh>
36 directory_handler::directory_handler(const sstring
& doc_root
,
37 file_transformer
* transformer
)
38 : file_interaction_handler(transformer
), doc_root(doc_root
) {
41 future
<std::unique_ptr
<reply
>> directory_handler::handle(const sstring
& path
,
42 std::unique_ptr
<request
> req
, std::unique_ptr
<reply
> rep
) {
43 sstring full_path
= doc_root
+ req
->param
["path"];
45 return engine().file_type(full_path
).then(
46 [h
, full_path
, req
= std::move(req
), rep
= std::move(rep
)](auto val
) mutable {
48 if (val
.value() == directory_entry_type::directory
) {
49 if (h
->redirect_if_needed(*req
.get(), *rep
.get())) {
50 return make_ready_future
<std::unique_ptr
<reply
>>(std::move(rep
));
52 full_path
+= "/index.html";
54 return h
->read(full_path
, std::move(req
), std::move(rep
));
56 rep
->set_status(reply::status_type::not_found
).done();
57 return make_ready_future
<std::unique_ptr
<reply
>>(std::move(rep
));
62 file_interaction_handler::~file_interaction_handler() {
66 sstring
file_interaction_handler::get_extension(const sstring
& file
) {
67 size_t last_slash_pos
= file
.find_last_of('/');
68 size_t last_dot_pos
= file
.find_last_of('.');
70 if (last_dot_pos
!= sstring::npos
&& last_dot_pos
> last_slash_pos
) {
71 extension
= file
.substr(last_dot_pos
+ 1);
73 // normalize file extension for mime type
74 std::transform(extension
.begin(), extension
.end(), extension
.begin(), ::tolower
);
78 output_stream
<char> file_interaction_handler::get_stream(std::unique_ptr
<request
> req
,
79 const sstring
& extension
, output_stream
<char>&& s
) {
81 return transformer
->transform(std::move(req
), extension
, std::move(s
));
86 future
<std::unique_ptr
<reply
>> file_interaction_handler::read(
87 sstring file_name
, std::unique_ptr
<request
> req
,
88 std::unique_ptr
<reply
> rep
) {
89 sstring extension
= get_extension(file_name
);
90 rep
->write_body(extension
, [req
= std::move(req
), extension
, file_name
, this] (output_stream
<char>&& s
) mutable {
91 return do_with(output_stream
<char>(get_stream(std::move(req
), extension
, std::move(s
))),
92 [file_name
] (output_stream
<char>& os
) {
93 return open_file_dma(file_name
, open_flags::ro
).then([&os
] (file f
) {
94 return do_with(input_stream
<char>(make_file_input_stream(std::move(f
))), [&os
](input_stream
<char>& is
) {
95 return copy(is
, os
).then([&os
] {
104 return make_ready_future
<std::unique_ptr
<reply
>>(std::move(rep
));
107 bool file_interaction_handler::redirect_if_needed(const request
& req
,
109 if (req
._url
.length() == 0 || req
._url
.back() != '/') {
110 rep
.set_status(reply::status_type::moved_permanently
);
111 rep
._headers
["Location"] = req
.get_url() + "/";
118 future
<std::unique_ptr
<reply
>> file_handler::handle(const sstring
& path
,
119 std::unique_ptr
<request
> req
, std::unique_ptr
<reply
> rep
) {
120 if (force_path
&& redirect_if_needed(*req
.get(), *rep
.get())) {
121 return make_ready_future
<std::unique_ptr
<reply
>>(std::move(rep
));
123 return read(file
, std::move(req
), std::move(rep
));