nghttp: Use nghttp2_session_mem_recv
This commit is contained in:
parent
bc2b941866
commit
68059ccda9
130
src/nghttp.cc
130
src/nghttp.cc
|
@ -529,7 +529,8 @@ void settings_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
||||||
|
|
||||||
HttpClient::HttpClient(const nghttp2_session_callbacks *callbacks,
|
HttpClient::HttpClient(const nghttp2_session_callbacks *callbacks,
|
||||||
struct ev_loop *loop, SSL_CTX *ssl_ctx)
|
struct ev_loop *loop, SSL_CTX *ssl_ctx)
|
||||||
: session(nullptr),
|
: wb(&mcpool),
|
||||||
|
session(nullptr),
|
||||||
callbacks(callbacks),
|
callbacks(callbacks),
|
||||||
loop(loop),
|
loop(loop),
|
||||||
ssl_ctx(ssl_ctx),
|
ssl_ctx(ssl_ctx),
|
||||||
|
@ -744,29 +745,32 @@ int HttpClient::read_clear() {
|
||||||
int HttpClient::write_clear() {
|
int HttpClient::write_clear() {
|
||||||
ev_timer_again(loop, &rt);
|
ev_timer_again(loop, &rt);
|
||||||
|
|
||||||
|
std::array<struct iovec, 2> iov;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (wb.rleft() > 0) {
|
|
||||||
ssize_t nwrite;
|
|
||||||
while ((nwrite = write(fd, wb.pos, wb.rleft())) == -1 && errno == EINTR)
|
|
||||||
;
|
|
||||||
if (nwrite == -1) {
|
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
|
||||||
ev_io_start(loop, &wev);
|
|
||||||
ev_timer_again(loop, &wt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
wb.drain(nwrite);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
wb.reset();
|
|
||||||
if (on_writefn(*this) != 0) {
|
if (on_writefn(*this) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (wb.rleft() == 0) {
|
|
||||||
|
auto iovcnt = wb.riovec(iov.data(), iov.size());
|
||||||
|
|
||||||
|
if (iovcnt == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t nwrite;
|
||||||
|
while ((nwrite = writev(fd, iov.data(), iovcnt)) == -1 && errno == EINTR)
|
||||||
|
;
|
||||||
|
if (nwrite == -1) {
|
||||||
|
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||||
|
ev_io_start(loop, &wev);
|
||||||
|
ev_timer_again(loop, &wt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wb.drain(nwrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
ev_io_stop(loop, &wev);
|
ev_io_stop(loop, &wev);
|
||||||
|
@ -946,7 +950,7 @@ int HttpClient::on_upgrade_connect() {
|
||||||
}
|
}
|
||||||
req += "\r\n";
|
req += "\r\n";
|
||||||
|
|
||||||
wb.write(req.c_str(), req.size());
|
wb.append(req);
|
||||||
|
|
||||||
if (config.verbose) {
|
if (config.verbose) {
|
||||||
print_timer();
|
print_timer();
|
||||||
|
@ -1193,11 +1197,24 @@ int HttpClient::on_read(const uint8_t *data, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int HttpClient::on_write() {
|
int HttpClient::on_write() {
|
||||||
auto rv = nghttp2_session_send(session);
|
for (;;) {
|
||||||
if (rv != 0) {
|
if (wb.rleft() >= 16384) {
|
||||||
std::cerr << "[ERROR] nghttp2_session_send() returned error: "
|
return 0;
|
||||||
<< nghttp2_strerror(rv) << std::endl;
|
}
|
||||||
return -1;
|
|
||||||
|
const uint8_t *data;
|
||||||
|
auto len = nghttp2_session_mem_send(session, &data);
|
||||||
|
if (len < 0) {
|
||||||
|
std::cerr << "[ERROR] nghttp2_session_send() returned error: "
|
||||||
|
<< nghttp2_strerror(len) << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
wb.append(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nghttp2_session_want_read(session) == 0 &&
|
if (nghttp2_session_want_read(session) == 0 &&
|
||||||
|
@ -1277,36 +1294,37 @@ int HttpClient::write_tls() {
|
||||||
|
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
|
|
||||||
|
struct iovec iov;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (wb.rleft() > 0) {
|
|
||||||
auto rv = SSL_write(ssl, wb.pos, wb.rleft());
|
|
||||||
|
|
||||||
if (rv <= 0) {
|
|
||||||
auto err = SSL_get_error(ssl, rv);
|
|
||||||
switch (err) {
|
|
||||||
case SSL_ERROR_WANT_READ:
|
|
||||||
// renegotiation started
|
|
||||||
return -1;
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
|
||||||
ev_io_start(loop, &wev);
|
|
||||||
ev_timer_again(loop, &wt);
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wb.drain(rv);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
wb.reset();
|
|
||||||
if (on_writefn(*this) != 0) {
|
if (on_writefn(*this) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (wb.rleft() == 0) {
|
|
||||||
|
auto iovcnt = wb.riovec(&iov, 1);
|
||||||
|
|
||||||
|
if (iovcnt == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto rv = SSL_write(ssl, iov.iov_base, iov.iov_len);
|
||||||
|
|
||||||
|
if (rv <= 0) {
|
||||||
|
auto err = SSL_get_error(ssl, rv);
|
||||||
|
switch (err) {
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
// renegotiation started
|
||||||
|
return -1;
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
ev_io_start(loop, &wev);
|
||||||
|
ev_timer_again(loop, &wt);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wb.drain(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
ev_io_stop(loop, &wev);
|
ev_io_stop(loop, &wev);
|
||||||
|
@ -2339,20 +2357,6 @@ ssize_t file_read_callback(nghttp2_session *session, int32_t stream_id,
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
|
||||||
ssize_t send_callback(nghttp2_session *session, const uint8_t *data,
|
|
||||||
size_t length, int flags, void *user_data) {
|
|
||||||
auto client = static_cast<HttpClient *>(user_data);
|
|
||||||
auto &wb = client->wb;
|
|
||||||
|
|
||||||
if (wb.wleft() == 0) {
|
|
||||||
return NGHTTP2_ERR_WOULDBLOCK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wb.write(data, length);
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int run(char **uris, int n) {
|
int run(char **uris, int n) {
|
||||||
nghttp2_session_callbacks *callbacks;
|
nghttp2_session_callbacks *callbacks;
|
||||||
|
@ -2392,8 +2396,6 @@ int run(char **uris, int n) {
|
||||||
nghttp2_session_callbacks_set_on_frame_not_send_callback(
|
nghttp2_session_callbacks_set_on_frame_not_send_callback(
|
||||||
callbacks, on_frame_not_send_callback);
|
callbacks, on_frame_not_send_callback);
|
||||||
|
|
||||||
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
|
|
||||||
|
|
||||||
if (config.padding) {
|
if (config.padding) {
|
||||||
nghttp2_session_callbacks_set_select_padding_callback(
|
nghttp2_session_callbacks_set_select_padding_callback(
|
||||||
callbacks, select_padding_callback);
|
callbacks, select_padding_callback);
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
#include "http-parser/http_parser.h"
|
#include "http-parser/http_parser.h"
|
||||||
|
|
||||||
#include "buffer.h"
|
#include "memchunk.h"
|
||||||
#include "http2.h"
|
#include "http2.h"
|
||||||
#include "nghttp2_gzip.h"
|
#include "nghttp2_gzip.h"
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
|
@ -241,6 +241,8 @@ struct HttpClient {
|
||||||
void output_har(FILE *outfile);
|
void output_har(FILE *outfile);
|
||||||
#endif // HAVE_JANSSON
|
#endif // HAVE_JANSSON
|
||||||
|
|
||||||
|
MemchunkPool mcpool;
|
||||||
|
DefaultMemchunks wb;
|
||||||
std::vector<std::unique_ptr<Request>> reqvec;
|
std::vector<std::unique_ptr<Request>> reqvec;
|
||||||
// Insert path already added in reqvec to prevent multiple request
|
// Insert path already added in reqvec to prevent multiple request
|
||||||
// for 1 resource.
|
// for 1 resource.
|
||||||
|
@ -281,7 +283,6 @@ struct HttpClient {
|
||||||
// true if the response message of HTTP Upgrade request is fully
|
// true if the response message of HTTP Upgrade request is fully
|
||||||
// received. It is not relevant the upgrade succeeds, or not.
|
// received. It is not relevant the upgrade succeeds, or not.
|
||||||
bool upgrade_response_complete;
|
bool upgrade_response_complete;
|
||||||
Buffer<64_k> wb;
|
|
||||||
// SETTINGS payload sent as token68 in HTTP Upgrade
|
// SETTINGS payload sent as token68 in HTTP Upgrade
|
||||||
std::array<uint8_t, 128> settings_payload;
|
std::array<uint8_t, 128> settings_payload;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue