-
-
Notifications
You must be signed in to change notification settings - Fork 191
Expand file tree
/
Copy pathupload_pipeline.hpp
More file actions
113 lines (91 loc) · 4.7 KB
/
Copy pathupload_pipeline.hpp
File metadata and controls
113 lines (91 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
This file is part of libhttpserver
Copyright (C) 2011-2026 Sebastiano Merlino
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
*/
// upload_pipeline -- behavior service (DR-014, §4.11) owning multipart /
// file-upload handling: the MHD post-iterator body (no-file form args and
// file chunks), the on-disk destination selection, and the per-(key,
// filename) output-stream lifecycle. Holds only const webserver_config&
// (file_upload_target / file_upload_dir / generate_random_filename_on_upload)
// and operates on conn->request / conn->upload_* fields.
//
// The webserver_impl::post_iterator static MHD trampoline forwards here:
// the no-file branch calls the static handle_post_form_arg (safe without an
// owning webserver -- see post_iterator_null_key_test), the file branch
// calls iterate_file on the owning webserver's upload_ instance.
//
// Internal header; only reachable when compiling libhttpserver.
#if !defined(HTTPSERVER_COMPILATION)
#error "upload_pipeline.hpp is internal; only reachable when compiling libhttpserver."
#endif
#ifndef SRC_HTTPSERVER_DETAIL_UPLOAD_PIPELINE_HPP_
#define SRC_HTTPSERVER_DETAIL_UPLOAD_PIPELINE_HPP_
#include <microhttpd.h>
#include <cstddef>
#include <cstdint>
#if MHD_VERSION < 0x00097002
typedef int MHD_Result;
#endif
namespace httpserver {
struct webserver_config;
namespace http { class file_info; }
namespace detail {
struct connection_context;
class upload_pipeline {
public:
explicit upload_pipeline(const webserver_config& config) noexcept
: config_(config) {}
upload_pipeline(const upload_pipeline&) = delete;
upload_pipeline& operator=(const upload_pipeline&) = delete;
upload_pipeline(upload_pipeline&&) = delete;
upload_pipeline& operator=(upload_pipeline&&) = delete;
~upload_pipeline() = default;
// No-file form arg: set (or, on a continuation chunk with off>0, append
// to) the request arg keyed by @p key. Static and config-free so the
// post_iterator trampoline can reach it without an owning webserver
// (MHD may hand a null key on a continuation chunk; guarded, issue #375).
static MHD_Result handle_post_form_arg(connection_context* conn, const char* key,
const char* data, size_t size,
uint64_t off);
// File-upload branch of the post iterator: mirror the value into the
// request args (unless disk-only), then stream the chunk to disk (unless
// memory-only), per config_.file_upload_target. Contains the
// generateFilenameException guard.
MHD_Result iterate_file(connection_context* conn, const char* key,
const char* filename, const char* content_type,
const char* transfer_encoding, const char* data,
size_t size);
private:
// First chunk for a (key, filename) pair: choose the on-disk destination
// (random or sanitized client name) and prime the file_info. Returns
// false if the sanitized name is empty.
bool setup_new_upload_file_info(http::file_info& file, const char* filename,
const char* content_type,
const char* transfer_encoding) const;
// Open/rotate the per-(filename,key) output stream on conn as MHD feeds
// chunks.
static void manage_upload_stream(connection_context* conn, const char* filename,
const char* key, http::file_info& file);
// Stream one upload chunk to disk, setting up the file_info + stream on
// the first chunk.
MHD_Result process_file_upload(connection_context* conn, const char* key,
const char* filename, const char* content_type,
const char* transfer_encoding,
const char* data, size_t size) const;
const webserver_config& config_;
};
} // namespace detail
} // namespace httpserver
#endif // SRC_HTTPSERVER_DETAIL_UPLOAD_PIPELINE_HPP_