Skip to content

Commit f1a82c7

Browse files
committed
[k2] add support multipart/form-data to HTTP server
1 parent 0bb1456 commit f1a82c7

5 files changed

Lines changed: 391 additions & 3 deletions

File tree

runtime-light/server/http/http-server-state.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ inline constexpr std::string_view CONTENT_LENGTH = "content-length";
4646
inline constexpr std::string_view AUTHORIZATION = "authorization";
4747
inline constexpr std::string_view ACCEPT_ENCODING = "accept-encoding";
4848
inline constexpr std::string_view CONTENT_ENCODING = "content-encoding";
49+
inline constexpr std::string_view CONTENT_DISPOSITION = "content-disposition";
4950

5051
} // namespace headers
5152

runtime-light/server/http/init-functions.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@
2626
#include "runtime-light/core/globals/php-script-globals.h"
2727
#include "runtime-light/k2-platform/k2-api.h"
2828
#include "runtime-light/server/http/http-server-state.h"
29+
#include "runtime-light/server/http/multipart.h"
2930
#include "runtime-light/state/instance-state.h"
3031
#include "runtime-light/stdlib/component/component-api.h"
3132
#include "runtime-light/stdlib/diagnostics/logs.h"
3233
#include "runtime-light/stdlib/output/output-state.h"
3334
#include "runtime-light/stdlib/server/http-functions.h"
3435
#include "runtime-light/stdlib/zlib/zlib-functions.h"
36+
#include "runtime-light/stdlib/file/file-system-functions.h"
3537
#include "runtime-light/streams/stream.h"
3638
#include "runtime-light/tl/tl-core.h"
3739
#include "runtime-light/tl/tl-functions.h"
@@ -319,14 +321,16 @@ void init_server(kphp::component::stream&& request_stream, kphp::stl::vector<std
319321
break;
320322
}
321323
case kphp::http::method::post: {
324+
string body{reinterpret_cast<const char*>(invoke_http.body.data()), static_cast<string::size_type>(invoke_http.body.size())};
322325
if (!std::ranges::search(content_type, CONTENT_TYPE_APP_FORM_URLENCODED).empty()) {
323-
string body{reinterpret_cast<const char*>(invoke_http.body.data()), static_cast<string::size_type>(invoke_http.body.size())};
324326
f$parse_str(body, superglobals.v$_POST);
325327
http_server_instance_st.opt_raw_post_data.emplace(std::move(body));
326328
} else if (!std::ranges::search(content_type, CONTENT_TYPE_MULTIPART_FORM_DATA).empty()) {
327-
kphp::log::error("unsupported content-type: {}", CONTENT_TYPE_MULTIPART_FORM_DATA);
329+
std::string_view boundary{parse_boundary(content_type)};
330+
if (!boundary.empty()) {
331+
kphp::http::parse_multipart({body.c_str(), body.size()}, boundary, superglobals.v$_POST, superglobals.v$_FILES);
332+
}
328333
} else {
329-
string body{reinterpret_cast<const char*>(invoke_http.body.data()), static_cast<string::size_type>(invoke_http.body.size())};
330334
http_server_instance_st.opt_raw_post_data.emplace(std::move(body));
331335
}
332336

@@ -378,6 +382,7 @@ void init_server(kphp::component::stream&& request_stream, kphp::stl::vector<std
378382

379383
kphp::coro::task<> finalize_server() noexcept {
380384
auto& http_server_instance_st{HttpServerInstanceState::get()};
385+
auto& superglobals{InstanceState::get().php_script_mutable_globals_singleton.get_superglobals()};
381386

382387
string response_body{};
383388
tl::HttpResponse http_response{};
@@ -431,6 +436,18 @@ kphp::coro::task<> finalize_server() noexcept {
431436
[[fallthrough]];
432437
}
433438
case kphp::http::response_state::completed:
439+
const array<mixed> files = superglobals.v$_FILES.to_array();
440+
for (array<mixed>::const_iterator it = files.begin(); it != files.end(); ++it) {
441+
const mixed& file = it.get_value();
442+
443+
if (!file.is_array()) {
444+
kphp::log::error("$_FILES contains a value that is not an array");
445+
continue;
446+
}
447+
448+
const mixed tmp_filename = file.get_value(string("tmp_name"));
449+
f$unlink(tmp_filename.to_string());
450+
}
434451
co_return;
435452
}
436453
}

0 commit comments

Comments
 (0)