src,http2: DRY header/trailer handling code up
Remove duplicate code through minor refactoring. PR-URL: https://github.com/nodejs/node/pull/14688 Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
parent
c7a9a2edd4
commit
d98606f968
@ -104,47 +104,6 @@ Http2Options::Http2Options(Environment* env) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CopyHeaders(Isolate* isolate,
|
|
||||||
Local<Context> context,
|
|
||||||
MaybeStackBuffer<nghttp2_nv>* list,
|
|
||||||
Local<Array> headers) {
|
|
||||||
Local<Value> item;
|
|
||||||
Local<Array> header;
|
|
||||||
|
|
||||||
for (size_t n = 0; n < headers->Length(); n++) {
|
|
||||||
item = headers->Get(context, n).ToLocalChecked();
|
|
||||||
header = item.As<Array>();
|
|
||||||
Local<Value> key = header->Get(context, 0).ToLocalChecked();
|
|
||||||
Local<Value> value = header->Get(context, 1).ToLocalChecked();
|
|
||||||
CHECK(key->IsString());
|
|
||||||
CHECK(value->IsString());
|
|
||||||
size_t keylen = StringBytes::StorageSize(isolate, key, ASCII);
|
|
||||||
size_t valuelen = StringBytes::StorageSize(isolate, value, ASCII);
|
|
||||||
nghttp2_nv& nv = (*list)[n];
|
|
||||||
nv.flags = NGHTTP2_NV_FLAG_NONE;
|
|
||||||
Local<Value> flag = header->Get(context, 2).ToLocalChecked();
|
|
||||||
if (flag->BooleanValue(context).ToChecked())
|
|
||||||
nv.flags |= NGHTTP2_NV_FLAG_NO_INDEX;
|
|
||||||
nv.name = Malloc<uint8_t>(keylen);
|
|
||||||
nv.value = Malloc<uint8_t>(valuelen);
|
|
||||||
nv.namelen =
|
|
||||||
StringBytes::Write(isolate,
|
|
||||||
reinterpret_cast<char*>(nv.name),
|
|
||||||
keylen, key, ASCII);
|
|
||||||
nv.valuelen =
|
|
||||||
StringBytes::Write(isolate,
|
|
||||||
reinterpret_cast<char*>(nv.value),
|
|
||||||
valuelen, value, ASCII);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void FreeHeaders(MaybeStackBuffer<nghttp2_nv>* list) {
|
|
||||||
for (size_t n = 0; n < list->length(); n++) {
|
|
||||||
free((*list)[n].name);
|
|
||||||
free((*list)[n].value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Http2Session::OnFreeSession() {
|
void Http2Session::OnFreeSession() {
|
||||||
::delete this;
|
::delete this;
|
||||||
}
|
}
|
||||||
@ -860,7 +819,7 @@ void Http2Session::Send(uv_buf_t* buf, size_t length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Http2Session::OnTrailers(Nghttp2Stream* stream,
|
void Http2Session::OnTrailers(Nghttp2Stream* stream,
|
||||||
MaybeStackBuffer<nghttp2_nv>* trailers) {
|
const SubmitTrailers& submit_trailers) {
|
||||||
DEBUG_HTTP2("Http2Session: prompting for trailers on stream %d\n",
|
DEBUG_HTTP2("Http2Session: prompting for trailers on stream %d\n",
|
||||||
stream->id());
|
stream->id());
|
||||||
Local<Context> context = env()->context();
|
Local<Context> context = env()->context();
|
||||||
@ -879,8 +838,8 @@ void Http2Session::OnTrailers(Nghttp2Stream* stream,
|
|||||||
if (ret->IsArray()) {
|
if (ret->IsArray()) {
|
||||||
Local<Array> headers = ret.As<Array>();
|
Local<Array> headers = ret.As<Array>();
|
||||||
if (headers->Length() > 0) {
|
if (headers->Length() > 0) {
|
||||||
trailers->AllocateSufficientStorage(headers->Length());
|
Headers trailers(isolate, context, headers);
|
||||||
CopyHeaders(isolate, context, trailers, headers);
|
submit_trailers.Submit(*trailers, trailers.length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,7 +387,7 @@ class Http2Session : public AsyncWrap,
|
|||||||
size_t length) override;
|
size_t length) override;
|
||||||
void OnFrameError(int32_t id, uint8_t type, int error_code) override;
|
void OnFrameError(int32_t id, uint8_t type, int error_code) override;
|
||||||
void OnTrailers(Nghttp2Stream* stream,
|
void OnTrailers(Nghttp2Stream* stream,
|
||||||
MaybeStackBuffer<nghttp2_nv>* trailers) override;
|
const SubmitTrailers& submit_trailers) override;
|
||||||
void AllocateSend(size_t recommended, uv_buf_t* buf) override;
|
void AllocateSend(size_t recommended, uv_buf_t* buf) override;
|
||||||
|
|
||||||
int DoWrite(WriteWrap* w, uv_buf_t* bufs, size_t count,
|
int DoWrite(WriteWrap* w, uv_buf_t* bufs, size_t count,
|
||||||
|
@ -605,6 +605,12 @@ Nghttp2Session::Callbacks::~Callbacks() {
|
|||||||
nghttp2_session_callbacks_del(callbacks);
|
nghttp2_session_callbacks_del(callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Nghttp2Session::SubmitTrailers::SubmitTrailers(
|
||||||
|
Nghttp2Session* handle,
|
||||||
|
Nghttp2Stream* stream,
|
||||||
|
uint32_t* flags)
|
||||||
|
: handle_(handle), stream_(stream), flags_(flags) { }
|
||||||
|
|
||||||
} // namespace http2
|
} // namespace http2
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
|
||||||
|
@ -172,23 +172,22 @@ void Nghttp2Session::GetTrailers(nghttp2_session* session,
|
|||||||
// any trailing headers that are to be sent. This is the only opportunity
|
// any trailing headers that are to be sent. This is the only opportunity
|
||||||
// we have to make this check. If there are trailers, then the
|
// we have to make this check. If there are trailers, then the
|
||||||
// NGHTTP2_DATA_FLAG_NO_END_STREAM flag must be set.
|
// NGHTTP2_DATA_FLAG_NO_END_STREAM flag must be set.
|
||||||
MaybeStackBuffer<nghttp2_nv> trailers;
|
SubmitTrailers submit_trailers { handle, stream, flags };
|
||||||
handle->OnTrailers(stream, &trailers);
|
handle->OnTrailers(stream, submit_trailers);
|
||||||
if (trailers.length() > 0) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nghttp2Session::SubmitTrailers::Submit(nghttp2_nv* trailers,
|
||||||
|
size_t length) const {
|
||||||
|
if (length == 0) return;
|
||||||
DEBUG_HTTP2("Nghttp2Session %d: sending trailers for stream %d, "
|
DEBUG_HTTP2("Nghttp2Session %d: sending trailers for stream %d, "
|
||||||
"count: %d\n", handle->session_type_, stream->id(),
|
"count: %d\n", handle_->session_type_, stream_->id(),
|
||||||
trailers.length());
|
length);
|
||||||
*flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
|
*flags_ |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
|
||||||
nghttp2_submit_trailer(session,
|
nghttp2_submit_trailer(handle_->session_,
|
||||||
stream->id(),
|
stream_->id(),
|
||||||
*trailers,
|
trailers,
|
||||||
trailers.length());
|
length);
|
||||||
}
|
|
||||||
for (size_t n = 0; n < trailers.length(); n++) {
|
|
||||||
free(trailers[n].name);
|
|
||||||
free(trailers[n].value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by nghttp2 to collect the data while a file response is sent.
|
// Called by nghttp2 to collect the data while a file response is sent.
|
||||||
|
@ -166,13 +166,30 @@ class Nghttp2Session {
|
|||||||
int error_code) {}
|
int error_code) {}
|
||||||
virtual ssize_t GetPadding(size_t frameLength,
|
virtual ssize_t GetPadding(size_t frameLength,
|
||||||
size_t maxFrameLength) { return 0; }
|
size_t maxFrameLength) { return 0; }
|
||||||
virtual void OnTrailers(Nghttp2Stream* stream,
|
|
||||||
MaybeStackBuffer<nghttp2_nv>* nva) {}
|
|
||||||
virtual void OnFreeSession() {}
|
virtual void OnFreeSession() {}
|
||||||
virtual void AllocateSend(size_t suggested_size, uv_buf_t* buf) = 0;
|
virtual void AllocateSend(size_t suggested_size, uv_buf_t* buf) = 0;
|
||||||
|
|
||||||
virtual bool HasGetPaddingCallback() { return false; }
|
virtual bool HasGetPaddingCallback() { return false; }
|
||||||
|
|
||||||
|
class SubmitTrailers {
|
||||||
|
public:
|
||||||
|
void Submit(nghttp2_nv* trailers, size_t length) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline SubmitTrailers(Nghttp2Session* handle,
|
||||||
|
Nghttp2Stream* stream,
|
||||||
|
uint32_t* flags);
|
||||||
|
|
||||||
|
Nghttp2Session* const handle_;
|
||||||
|
Nghttp2Stream* const stream_;
|
||||||
|
uint32_t* const flags_;
|
||||||
|
|
||||||
|
friend class Nghttp2Session;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void OnTrailers(Nghttp2Stream* stream,
|
||||||
|
const SubmitTrailers& submit_trailers) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline void SendPendingData();
|
inline void SendPendingData();
|
||||||
inline void HandleHeadersFrame(const nghttp2_frame* frame);
|
inline void HandleHeadersFrame(const nghttp2_frame* frame);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user