]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include "rgw_fcgi.h" | |
5 | #include "acconfig.h" | |
6 | ||
7 | size_t RGWFCGX::write_data(const char* const buf, const size_t len) | |
8 | { | |
9 | /* According to the documentation of FCGX_PutStr if there is no error | |
10 | * (signalised by negative return value), then always ret == len. */ | |
11 | const auto ret = FCGX_PutStr(buf, len, fcgx->out); | |
12 | if (ret < 0) { | |
13 | throw rgw::io::Exception(-ret, std::system_category()); | |
14 | } | |
15 | return ret; | |
16 | } | |
17 | ||
18 | size_t RGWFCGX::read_data(char* const buf, const size_t len) | |
19 | { | |
20 | const auto ret = FCGX_GetStr(buf, len, fcgx->in); | |
21 | if (ret < 0) { | |
22 | throw rgw::io::Exception(-ret, std::system_category()); | |
23 | } | |
24 | return ret; | |
25 | } | |
26 | ||
27 | void RGWFCGX::flush() | |
28 | { | |
29 | txbuf.pubsync(); | |
30 | FCGX_FFlush(fcgx->out); | |
31 | } | |
32 | ||
3a9019d9 | 33 | int RGWFCGX::init_env(CephContext* const cct) |
7c673cae FG |
34 | { |
35 | env.init(cct, (char **)fcgx->envp); | |
3a9019d9 | 36 | return 0; |
7c673cae FG |
37 | } |
38 | ||
39 | size_t RGWFCGX::send_status(const int status, const char* const status_name) | |
40 | { | |
41 | static constexpr size_t STATUS_BUF_SIZE = 128; | |
42 | ||
43 | char statusbuf[STATUS_BUF_SIZE]; | |
44 | const auto statuslen = snprintf(statusbuf, sizeof(statusbuf), | |
45 | "Status: %d %s\r\n", status, status_name); | |
46 | ||
47 | return txbuf.sputn(statusbuf, statuslen); | |
48 | } | |
49 | ||
50 | size_t RGWFCGX::send_100_continue() | |
51 | { | |
52 | const auto sent = send_status(100, "Continue"); | |
53 | flush(); | |
54 | return sent; | |
55 | } | |
56 | ||
57 | size_t RGWFCGX::send_header(const boost::string_ref& name, | |
58 | const boost::string_ref& value) | |
59 | { | |
60 | static constexpr char HEADER_SEP[] = ": "; | |
61 | static constexpr char HEADER_END[] = "\r\n"; | |
62 | ||
63 | size_t sent = 0; | |
64 | ||
65 | sent += txbuf.sputn(name.data(), name.length()); | |
66 | sent += txbuf.sputn(HEADER_SEP, sizeof(HEADER_SEP) - 1); | |
67 | sent += txbuf.sputn(value.data(), value.length()); | |
68 | sent += txbuf.sputn(HEADER_END, sizeof(HEADER_END) - 1); | |
69 | ||
70 | return sent; | |
71 | } | |
72 | ||
73 | size_t RGWFCGX::send_content_length(const uint64_t len) | |
74 | { | |
75 | static constexpr size_t CONLEN_BUF_SIZE = 128; | |
76 | ||
77 | char sizebuf[CONLEN_BUF_SIZE]; | |
78 | const auto sizelen = snprintf(sizebuf, sizeof(sizebuf), | |
79 | "Content-Length: %" PRIu64 "\r\n", len); | |
80 | ||
81 | return txbuf.sputn(sizebuf, sizelen); | |
82 | } | |
83 | ||
84 | size_t RGWFCGX::complete_header() | |
85 | { | |
86 | static constexpr char HEADER_END[] = "\r\n"; | |
87 | const size_t sent = txbuf.sputn(HEADER_END, sizeof(HEADER_END) - 1); | |
88 | ||
89 | flush(); | |
90 | return sent; | |
91 | } |