Skip to content

Commit 8cf7203

Browse files
liulanzhenglihuiba
authored andcommitted
add set body buffer for http client
Signed-off-by: liulanzheng <[email protected]>
1 parent 50c0cb0 commit 8cf7203

File tree

4 files changed

+41
-6
lines changed

4 files changed

+41
-6
lines changed

net/http/client.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,14 @@ class ClientImpl : public Client {
222222
LOG_ERROR_RETURN(0, ROUNDTRIP_NEED_RETRY, "send header failed, retry");
223223
}
224224
sock->timeout(tmo.timeout());
225-
if (op->body_stream) {
225+
if (op->body_buffer_size > 0) {
226+
// send body_buffer
227+
if (req.write(op->body_buffer, op->body_buffer_size) < 0) {
228+
sock->close();
229+
req.reset_status();
230+
LOG_ERROR_RETURN(0, ROUNDTRIP_NEED_RETRY, "send body buffer failed, retry");
231+
}
232+
} else if (op->body_stream) {
226233
// send body_stream
227234
if (req.write_stream(op->body_stream) < 0) {
228235
sock->close();

net/http/client.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ class Client : public Object {
6262
bool enable_proxy = false;
6363
std::string_view uds_path; // If set, Unix Domain Socket will be used instead of TCP.
6464
// URL should still be the format of http://localhost/xxx
65-
IStream* body_stream = nullptr; // use body_stream as body
66-
using BodyWriter = Delegate<ssize_t, Request*>; // or call body_writer if body_stream
67-
BodyWriter body_writer = {}; // is not set
65+
66+
IStream* body_stream = nullptr; // priority: set_body > body_stream > body_writer
67+
using BodyWriter = Delegate<ssize_t, Request*>;
68+
BodyWriter body_writer = {};
6869

6970
static Operation* create(Client* c, Verb v, std::string_view url,
7071
uint16_t buf_size = 64 * 1024 - 1) {
@@ -91,9 +92,22 @@ class Client : public Object {
9192
uds_path = unix_socket_path;
9293
return _client->call(this);
9394
}
95+
// set body buffer and set content length automatically
96+
void set_body(const void *buf, size_t size) {
97+
body_buffer = buf;
98+
body_buffer_size = size;
99+
req.headers.content_length(size);
100+
}
101+
void set_body(std::string_view buf) {
102+
set_body(buf.data(), buf.length());
103+
}
104+
94105

95106
protected:
96107
Client* _client;
108+
const void *body_buffer = nullptr;
109+
size_t body_buffer_size = 0;
110+
97111
char _buf[0];
98112
Operation(Client* c, Verb v, std::string_view url, uint16_t buf_size)
99113
: req(_buf, buf_size, v, url, c->has_proxy()),
@@ -106,6 +120,8 @@ class Client : public Object {
106120
explicit Operation(uint16_t buf_size) : req(_buf, buf_size), _client(nullptr) {}
107121
Operation() = delete;
108122
~Operation() = default;
123+
124+
friend class ClientImpl;
109125
};
110126

111127
template<uint16_t BufferSize = UINT16_MAX>

net/http/message.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ class Message : public IStream {
9898
ssize_t write_stream(IStream *stream, size_t size_limit = -1);
9999
int close() override { return 0; }
100100

101-
// size of body
101+
// size of body: infer from Content-Range/Content-Length in response header
102102
size_t body_size() const;
103-
// size of origin resource
103+
// size of origin resource: infer from Content-Range/Content-Length in response header
104104
ssize_t resource_size() const;
105105

106106
// in general, it is called automatically

net/http/test/client_function_test.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,18 @@ TEST(http_client, post) {
213213
ret = op2->resp.read(buf, 4096);
214214
EXPECT_EQ(ret, 7);
215215
EXPECT_EQ(0, strncmp(buf, "success", ret));
216+
217+
// body buffer test
218+
auto op3 = client->new_operation(Verb::POST, target);
219+
DEFER(client->destroy_operation(op3));
220+
void *body_buf = malloc(st.st_size);
221+
EXPECT_EQ(st.st_size, file->pread(body_buf, st.st_size, 0));
222+
op3->set_body(body_buf, st.st_size);
223+
client->call(op3);
224+
EXPECT_EQ(200, op3->resp.status_code());
225+
ret = op3->resp.read(buf, 4096);
226+
EXPECT_EQ(ret, 7);
227+
EXPECT_EQ(0, strncmp(buf, "success", ret));
216228
}
217229

218230

0 commit comments

Comments
 (0)