Skip to content

Commit

Permalink
add set body buffer for http client
Browse files Browse the repository at this point in the history
Signed-off-by: liulanzheng <lanzheng.liulz@alibaba-inc.com>
  • Loading branch information
liulanzheng authored and lihuiba committed Dec 18, 2024
1 parent 50c0cb0 commit 8cf7203
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 6 deletions.
9 changes: 8 additions & 1 deletion net/http/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,14 @@ class ClientImpl : public Client {
LOG_ERROR_RETURN(0, ROUNDTRIP_NEED_RETRY, "send header failed, retry");
}
sock->timeout(tmo.timeout());
if (op->body_stream) {
if (op->body_buffer_size > 0) {
// send body_buffer
if (req.write(op->body_buffer, op->body_buffer_size) < 0) {
sock->close();
req.reset_status();
LOG_ERROR_RETURN(0, ROUNDTRIP_NEED_RETRY, "send body buffer failed, retry");
}
} else if (op->body_stream) {
// send body_stream
if (req.write_stream(op->body_stream) < 0) {
sock->close();
Expand Down
22 changes: 19 additions & 3 deletions net/http/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ class Client : public Object {
bool enable_proxy = false;
std::string_view uds_path; // If set, Unix Domain Socket will be used instead of TCP.
// URL should still be the format of http://localhost/xxx
IStream* body_stream = nullptr; // use body_stream as body
using BodyWriter = Delegate<ssize_t, Request*>; // or call body_writer if body_stream
BodyWriter body_writer = {}; // is not set

IStream* body_stream = nullptr; // priority: set_body > body_stream > body_writer
using BodyWriter = Delegate<ssize_t, Request*>;
BodyWriter body_writer = {};

static Operation* create(Client* c, Verb v, std::string_view url,
uint16_t buf_size = 64 * 1024 - 1) {
Expand All @@ -91,9 +92,22 @@ class Client : public Object {
uds_path = unix_socket_path;
return _client->call(this);
}
// set body buffer and set content length automatically
void set_body(const void *buf, size_t size) {
body_buffer = buf;
body_buffer_size = size;
req.headers.content_length(size);
}
void set_body(std::string_view buf) {
set_body(buf.data(), buf.length());
}


protected:
Client* _client;
const void *body_buffer = nullptr;
size_t body_buffer_size = 0;

char _buf[0];
Operation(Client* c, Verb v, std::string_view url, uint16_t buf_size)
: req(_buf, buf_size, v, url, c->has_proxy()),
Expand All @@ -106,6 +120,8 @@ class Client : public Object {
explicit Operation(uint16_t buf_size) : req(_buf, buf_size), _client(nullptr) {}
Operation() = delete;
~Operation() = default;

friend class ClientImpl;
};

template<uint16_t BufferSize = UINT16_MAX>
Expand Down
4 changes: 2 additions & 2 deletions net/http/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ class Message : public IStream {
ssize_t write_stream(IStream *stream, size_t size_limit = -1);
int close() override { return 0; }

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

// in general, it is called automatically
Expand Down
12 changes: 12 additions & 0 deletions net/http/test/client_function_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,18 @@ TEST(http_client, post) {
ret = op2->resp.read(buf, 4096);
EXPECT_EQ(ret, 7);
EXPECT_EQ(0, strncmp(buf, "success", ret));

// body buffer test
auto op3 = client->new_operation(Verb::POST, target);
DEFER(client->destroy_operation(op3));
void *body_buf = malloc(st.st_size);
EXPECT_EQ(st.st_size, file->pread(body_buf, st.st_size, 0));
op3->set_body(body_buf, st.st_size);
client->call(op3);
EXPECT_EQ(200, op3->resp.status_code());
ret = op3->resp.read(buf, 4096);
EXPECT_EQ(ret, 7);
EXPECT_EQ(0, strncmp(buf, "success", ret));
}


Expand Down

0 comments on commit 8cf7203

Please sign in to comment.