]>
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 | ||
33 | void RGWFCGX::init_env(CephContext* const cct) | |
34 | { | |
35 | env.init(cct, (char **)fcgx->envp); | |
36 | } | |
37 | ||
38 | size_t RGWFCGX::send_status(const int status, const char* const status_name) | |
39 | { | |
40 | static constexpr size_t STATUS_BUF_SIZE = 128; | |
41 | ||
42 | char statusbuf[STATUS_BUF_SIZE]; | |
43 | const auto statuslen = snprintf(statusbuf, sizeof(statusbuf), | |
44 | "Status: %d %s\r\n", status, status_name); | |
45 | ||
46 | return txbuf.sputn(statusbuf, statuslen); | |
47 | } | |
48 | ||
49 | size_t RGWFCGX::send_100_continue() | |
50 | { | |
51 | const auto sent = send_status(100, "Continue"); | |
52 | flush(); | |
53 | return sent; | |
54 | } | |
55 | ||
56 | size_t RGWFCGX::send_header(const boost::string_ref& name, | |
57 | const boost::string_ref& value) | |
58 | { | |
59 | static constexpr char HEADER_SEP[] = ": "; | |
60 | static constexpr char HEADER_END[] = "\r\n"; | |
61 | ||
62 | size_t sent = 0; | |
63 | ||
64 | sent += txbuf.sputn(name.data(), name.length()); | |
65 | sent += txbuf.sputn(HEADER_SEP, sizeof(HEADER_SEP) - 1); | |
66 | sent += txbuf.sputn(value.data(), value.length()); | |
67 | sent += txbuf.sputn(HEADER_END, sizeof(HEADER_END) - 1); | |
68 | ||
69 | return sent; | |
70 | } | |
71 | ||
72 | size_t RGWFCGX::send_content_length(const uint64_t len) | |
73 | { | |
74 | static constexpr size_t CONLEN_BUF_SIZE = 128; | |
75 | ||
76 | char sizebuf[CONLEN_BUF_SIZE]; | |
77 | const auto sizelen = snprintf(sizebuf, sizeof(sizebuf), | |
78 | "Content-Length: %" PRIu64 "\r\n", len); | |
79 | ||
80 | return txbuf.sputn(sizebuf, sizelen); | |
81 | } | |
82 | ||
83 | size_t RGWFCGX::complete_header() | |
84 | { | |
85 | static constexpr char HEADER_END[] = "\r\n"; | |
86 | const size_t sent = txbuf.sputn(HEADER_END, sizeof(HEADER_END) - 1); | |
87 | ||
88 | flush(); | |
89 | return sent; | |
90 | } |