1 #ifndef SRC_NODE_HTTP2_CORE_INL_H_ 2 #define SRC_NODE_HTTP2_CORE_INL_H_ 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 13 #define FREELIST_MAX 1024 15 #define LINKED_LIST_ADD(list, item) \ 17 if (list ## _tail_ == nullptr) { \ 18 list ## _head_ = item; \ 19 list ## _tail_ = item; \ 21 list ## _tail_->next = item; \ 22 list ## _tail_ = item; \ 26 extern Freelist<nghttp2_data_chunk_t, FREELIST_MAX>
33 extern Freelist<nghttp2_data_chunks_t, FREELIST_MAX>
36 #ifdef NODE_DEBUG_HTTP2 37 inline int Nghttp2Session::OnNghttpError(nghttp2_session* session,
41 Nghttp2Session* handle =
static_cast<Nghttp2Session*
>(user_data);
42 DEBUG_HTTP2(
"Nghttp2Session %s: Error '%.*s'\n",
43 handle->TypeName(handle->type()), len, message);
51 inline int Nghttp2Session::OnBeginHeadersCallback(nghttp2_session* session,
52 const nghttp2_frame* frame,
54 Nghttp2Session* handle =
static_cast<Nghttp2Session*
>(user_data);
55 int32_t
id = (frame->hd.type == NGHTTP2_PUSH_PROMISE) ?
56 frame->push_promise.promised_stream_id :
58 DEBUG_HTTP2(
"Nghttp2Session %s: beginning headers for stream %d\n",
59 handle->TypeName(handle->type()),
id);
61 Nghttp2Stream* stream = handle->FindStream(
id);
62 if (stream ==
nullptr) {
65 stream->StartHeaders(frame->headers.cat);
73 inline int Nghttp2Session::OnHeaderCallback(nghttp2_session* session,
74 const nghttp2_frame* frame,
79 Nghttp2Session* handle =
static_cast<Nghttp2Session*
>(user_data);
80 int32_t
id = (frame->hd.type == NGHTTP2_PUSH_PROMISE) ?
81 frame->push_promise.promised_stream_id :
83 Nghttp2Stream* stream = handle->FindStream(
id);
84 nghttp2_header_list* header = header_free_list.pop();
86 header->value = value;
87 nghttp2_rcbuf_incref(name);
88 nghttp2_rcbuf_incref(value);
89 LINKED_LIST_ADD(stream->current_headers, header);
97 inline int Nghttp2Session::OnFrameReceive(nghttp2_session* session,
98 const nghttp2_frame* frame,
100 Nghttp2Session* handle =
static_cast<Nghttp2Session*
>(user_data);
101 DEBUG_HTTP2(
"Nghttp2Session %s: complete frame received: type: %d\n",
102 handle->TypeName(handle->type()), frame->hd.type);
104 switch (frame->hd.type) {
106 handle->HandleDataFrame(frame);
108 case NGHTTP2_PUSH_PROMISE:
109 case NGHTTP2_HEADERS:
110 handle->HandleHeadersFrame(frame);
112 case NGHTTP2_SETTINGS:
113 ack = (frame->hd.flags & NGHTTP2_FLAG_ACK) == NGHTTP2_FLAG_ACK;
114 handle->OnSettings(ack);
116 case NGHTTP2_PRIORITY:
117 handle->HandlePriorityFrame(frame);
120 handle->HandleGoawayFrame(frame);
128 inline int Nghttp2Session::OnFrameNotSent(nghttp2_session *session,
129 const nghttp2_frame *frame,
132 Nghttp2Session *handle =
static_cast<Nghttp2Session *
>(user_data);
133 DEBUG_HTTP2(
"Nghttp2Session %s: frame type %d was not sent, code: %d\n",
134 handle->TypeName(handle->type()), frame->hd.type, error_code);
136 if (error_code != NGHTTP2_ERR_SESSION_CLOSING &&
137 error_code != NGHTTP2_ERR_STREAM_CLOSED &&
138 error_code != NGHTTP2_ERR_STREAM_CLOSING)
139 handle->OnFrameError(frame->hd.stream_id, frame->hd.type, error_code);
143 inline int Nghttp2Session::OnInvalidHeader(nghttp2_session* session,
144 const nghttp2_frame* frame,
146 nghttp2_rcbuf* value,
155 inline int Nghttp2Session::OnStreamClose(nghttp2_session *session,
159 Nghttp2Session *handle =
static_cast<Nghttp2Session *
>(user_data);
160 DEBUG_HTTP2(
"Nghttp2Session %s: stream %d closed, code: %d\n",
161 handle->TypeName(handle->type()),
id, code);
162 Nghttp2Stream *stream = handle->FindStream(
id);
164 if (stream !=
nullptr)
172 inline ssize_t Nghttp2Session::OnStreamReadFD(nghttp2_session *session,
177 nghttp2_data_source *
source,
179 Nghttp2Session *handle =
static_cast<Nghttp2Session *
>(user_data);
180 DEBUG_HTTP2(
"Nghttp2Session %s: reading outbound file data for stream %d\n",
181 handle->TypeName(handle->type()),
id);
182 Nghttp2Stream *stream = handle->FindStream(
id);
185 int64_t offset = stream->fd_offset_;
186 ssize_t numchars = 0;
188 if (stream->fd_length_ >= 0 &&
189 stream->fd_length_ < static_cast<int64_t>(length))
190 length = stream->fd_length_;
193 data.base =
reinterpret_cast<char *
>(
buf);
199 numchars = uv_fs_read(handle->loop_,
203 uv_fs_req_cleanup(&read_req);
208 return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
211 stream->fd_offset_ += numchars;
212 stream->fd_length_ -= numchars;
215 if (static_cast<size_t>(numchars) < length || length <= 0) {
216 DEBUG_HTTP2(
"Nghttp2Session %s: no more data for stream %d\n",
217 handle->TypeName(handle->type()),
id);
218 *flags |= NGHTTP2_DATA_FLAG_EOF;
219 GetTrailers(session, handle, stream, flags);
228 inline ssize_t Nghttp2Session::OnStreamRead(nghttp2_session *session,
233 nghttp2_data_source *source,
235 Nghttp2Session *handle =
static_cast<Nghttp2Session *
>(user_data);
236 DEBUG_HTTP2(
"Nghttp2Session %s: reading outbound data for stream %d\n",
237 handle->TypeName(handle->type()),
id);
238 Nghttp2Stream *stream = handle->FindStream(
id);
239 size_t remaining = length;
245 while (stream->queue_head_ !=
nullptr) {
246 DEBUG_HTTP2(
"Nghttp2Session %s: processing outbound data chunk\n",
247 handle->TypeName(handle->type()));
248 nghttp2_stream_write_queue *head = stream->queue_head_;
249 while (stream->queue_head_index_ < head->nbufs) {
253 unsigned int n = stream->queue_head_index_;
255 size_t len = head->bufs[
n].len - stream->queue_head_offset_;
256 size_t bytes_to_write = len < remaining ?
len : remaining;
258 head->bufs[n].base + stream->queue_head_offset_,
260 offset += bytes_to_write;
261 remaining -= bytes_to_write;
262 if (bytes_to_write < len) {
263 stream->queue_head_offset_ += bytes_to_write;
265 stream->queue_head_index_++;
266 stream->queue_head_offset_ = 0;
269 stream->queue_head_offset_ = 0;
270 stream->queue_head_index_ = 0;
271 stream->queue_head_ = head->next;
272 head->cb(head->req, 0);
275 stream->queue_tail_ =
nullptr;
285 int writable = stream->queue_head_ !=
nullptr || stream->IsWritable();
286 if (offset == 0 && writable && stream->queue_head_ ==
nullptr) {
287 DEBUG_HTTP2(
"Nghttp2Session %s: deferring stream %d\n",
288 handle->TypeName(handle->type()),
id);
289 return NGHTTP2_ERR_DEFERRED;
292 DEBUG_HTTP2(
"Nghttp2Session %s: no more data for stream %d\n",
293 handle->TypeName(handle->type()),
id);
294 *flags |= NGHTTP2_DATA_FLAG_EOF;
296 GetTrailers(session, handle, stream, flags);
298 CHECK(offset <= length);
304 inline ssize_t Nghttp2Session::OnSelectPadding(nghttp2_session *session,
305 const nghttp2_frame *frame,
306 size_t maxPayloadLen,
308 Nghttp2Session *handle =
static_cast<Nghttp2Session *
>(user_data);
309 CHECK(handle->HasGetPaddingCallback());
310 ssize_t padding = handle->GetPadding(frame->hd.length, maxPayloadLen);
311 DEBUG_HTTP2(
"Nghttp2Session %s: using padding, size: %d\n",
312 handle->TypeName(handle->type()), padding);
317 inline int Nghttp2Session::OnDataChunkReceived(nghttp2_session *session,
323 Nghttp2Session *handle =
static_cast<Nghttp2Session *
>(user_data);
324 DEBUG_HTTP2(
"Nghttp2Session %s: buffering data chunk for stream %d, size: " 325 "%d, flags: %d\n", handle->TypeName(handle->type()),
327 Nghttp2Stream *stream = handle->FindStream(
id);
328 nghttp2_data_chunk_t *chunk = data_chunk_free_list.pop();
329 chunk->buf = uv_buf_init(
new char[len], len);
330 memcpy(chunk->buf.base, data, len);
331 if (stream->data_chunks_tail_ ==
nullptr) {
332 stream->data_chunks_head_ =
333 stream->data_chunks_tail_ = chunk;
335 stream->data_chunks_tail_->next = chunk;
336 stream->data_chunks_tail_ = chunk;
341 inline void Nghttp2Session::GetTrailers(nghttp2_session *session,
342 Nghttp2Session *handle,
343 Nghttp2Stream *stream,
345 if (stream->GetTrailers()) {
350 SubmitTrailers submit_trailers{handle, stream, flags};
351 handle->OnTrailers(stream, submit_trailers);
355 inline void Nghttp2Session::SubmitTrailers::Submit(nghttp2_nv *trailers,
356 size_t length)
const {
359 DEBUG_HTTP2(
"Nghttp2Session %s: sending trailers for stream %d, " 360 "count: %d\n", handle_->TypeName(handle_->type()),
361 stream_->id(), length);
362 *flags_ |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
363 nghttp2_submit_trailer(handle_->session_,
370 inline void Nghttp2Session::SubmitShutdownNotice() {
371 DEBUG_HTTP2(
"Nghttp2Session %s: submitting shutdown notice\n",
373 nghttp2_submit_shutdown_notice(session_);
379 inline int Nghttp2Session::SubmitSettings(
const nghttp2_settings_entry iv[],
381 DEBUG_HTTP2(
"Nghttp2Session %s: submitting settings, count: %d\n",
382 TypeName(type()), niv);
383 return nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, iv, niv);
387 inline Nghttp2Stream* Nghttp2Session::FindStream(int32_t
id) {
388 auto s = streams_.find(
id);
389 if (
s != streams_.end()) {
390 DEBUG_HTTP2(
"Nghttp2Session %s: stream %d found\n",
391 TypeName(type()),
id);
394 DEBUG_HTTP2(
"Nghttp2Session %s: stream %d not found\n",
395 TypeName(type()),
id);
401 inline void Nghttp2Stream::FlushDataChunks(
bool done) {
402 while (data_chunks_head_ !=
nullptr) {
403 DEBUG_HTTP2(
"Nghttp2Stream %d: emitting data chunk\n", id_);
404 nghttp2_data_chunk_t* item = data_chunks_head_;
405 data_chunks_head_ = item->next;
407 session_->OnDataChunk(
this, item);
409 data_chunks_tail_ =
nullptr;
411 session_->OnDataChunk(
this,
nullptr);
417 inline void Nghttp2Session::HandleDataFrame(
const nghttp2_frame* frame) {
418 int32_t
id = frame->hd.stream_id;
419 DEBUG_HTTP2(
"Nghttp2Session %s: handling data frame for stream %d\n",
420 TypeName(type()),
id);
421 Nghttp2Stream* stream = this->FindStream(
id);
423 CHECK_NE(stream,
nullptr);
424 bool done = (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) ==
425 NGHTTP2_FLAG_END_STREAM;
426 stream->FlushDataChunks(done);
432 inline void Nghttp2Session::HandleHeadersFrame(
const nghttp2_frame* frame) {
433 int32_t
id = (frame->hd.type == NGHTTP2_PUSH_PROMISE) ?
434 frame->push_promise.promised_stream_id : frame->hd.stream_id;
435 DEBUG_HTTP2(
"Nghttp2Session %s: handling headers frame for stream %d\n",
436 TypeName(type()), id);
437 Nghttp2Stream* stream = FindStream(
id);
439 CHECK_NE(stream,
nullptr);
442 stream->headers_category(),
444 stream->FreeHeaders();
448 inline void Nghttp2Session::HandlePriorityFrame(
const nghttp2_frame* frame) {
449 nghttp2_priority priority_frame = frame->priority;
450 int32_t
id = frame->hd.stream_id;
451 DEBUG_HTTP2(
"Nghttp2Session %s: handling priority frame for stream %d\n",
452 TypeName(type()),
id);
457 nghttp2_priority_spec spec = priority_frame.pri_spec;
458 OnPriority(
id, spec.stream_id, spec.weight, spec.exclusive);
463 inline void Nghttp2Session::HandleGoawayFrame(
const nghttp2_frame* frame) {
464 nghttp2_goaway goaway_frame = frame->goaway;
465 DEBUG_HTTP2(
"Nghttp2Session %s: handling goaway frame\n", TypeName(type()));
467 OnGoAway(goaway_frame.last_stream_id,
468 goaway_frame.error_code,
469 goaway_frame.opaque_data,
470 goaway_frame.opaque_data_len);
474 inline void Nghttp2Session::SendPendingData() {
475 DEBUG_HTTP2(
"Nghttp2Session %s: Sending pending data\n", TypeName(type()));
485 AllocateSend(SEND_BUFFER_RECOMMENDED_SIZE, &buf);
486 while (nghttp2_session_want_write(session_)) {
487 len = nghttp2_session_mem_send(session_, &data);
494 memcpy(buf.base, data, ncopy);
506 const nghttp2_session_type type,
507 nghttp2_option* options,
509 DEBUG_HTTP2(
"Nghttp2Session %s: initializing session\n",
512 session_type_ = type;
516 nghttp2_session_callbacks* callbacks
517 = callback_struct_saved[HasGetPaddingCallback() ? 1 : 0].callbacks;
519 nghttp2_option* opts;
520 if (options !=
nullptr) {
523 nghttp2_option_new(&opts);
527 case NGHTTP2_SESSION_SERVER:
528 ret = nghttp2_session_server_new3(&session_,
534 case NGHTTP2_SESSION_CLIENT:
535 ret = nghttp2_session_client_new3(&session_,
542 if (opts != options) {
543 nghttp2_option_del(opts);
549 uv_prepare_init(loop_, &prep_);
550 uv_prepare_start(&prep_, [](uv_prepare_t*
t) {
551 Nghttp2Session* session = ContainerOf(&Nghttp2Session::prep_, t);
552 session->SendPendingData();
558 inline void Nghttp2Session::MarkDestroying() {
562 inline int Nghttp2Session::Free() {
563 CHECK(session_ !=
nullptr);
564 DEBUG_HTTP2(
"Nghttp2Session %s: freeing session\n", TypeName(type()));
566 uv_prepare_stop(&prep_);
567 auto PrepClose = [](uv_handle_t* handle) {
568 Nghttp2Session* session =
569 ContainerOf(&Nghttp2Session::prep_,
570 reinterpret_cast<uv_prepare_t*>(handle));
571 session->OnFreeSession();
573 uv_close(reinterpret_cast<uv_handle_t*>(&prep_), PrepClose);
574 nghttp2_session_terminate_session(session_, NGHTTP2_NO_ERROR);
575 nghttp2_session_del(session_);
578 DEBUG_HTTP2(
"Nghttp2Session %s: session freed\n", TypeName(type()));
583 inline ssize_t Nghttp2Session::Write(
const uv_buf_t* bufs,
unsigned int nbufs) {
585 for (
unsigned int n = 0; n < nbufs; n++) {
587 nghttp2_session_mem_recv(session_,
588 reinterpret_cast<uint8_t*>(bufs[n].base),
600 inline void Nghttp2Session::AddStream(Nghttp2Stream* stream) {
601 streams_[stream->id()] = stream;
605 inline void Nghttp2Session::RemoveStream(int32_t
id) {
613 Nghttp2Session* session,
614 nghttp2_headers_category category,
616 DEBUG_HTTP2(
"Nghttp2Stream %d: initializing stream\n",
id);
617 Nghttp2Stream* stream = stream_free_list.pop();
618 stream->ResetState(
id, session, category, getTrailers);
619 session->AddStream(stream);
625 inline void Nghttp2Stream::ResetState(
627 Nghttp2Session* session,
628 nghttp2_headers_category category,
630 DEBUG_HTTP2(
"Nghttp2Stream %d: resetting stream state\n",
id);
632 queue_head_ =
nullptr;
633 queue_tail_ =
nullptr;
634 data_chunks_head_ =
nullptr;
635 data_chunks_tail_ =
nullptr;
636 current_headers_head_ =
nullptr;
637 current_headers_tail_ =
nullptr;
638 current_headers_category_ = category;
639 flags_ = NGHTTP2_STREAM_FLAG_NONE;
641 code_ = NGHTTP2_NO_ERROR;
642 prev_local_window_size_ = 65535;
643 queue_head_index_ = 0;
644 queue_head_offset_ = 0;
645 getTrailers_ = getTrailers;
649 inline void Nghttp2Stream::Destroy() {
650 DEBUG_HTTP2(
"Nghttp2Stream %d: destroying stream\n", id_);
654 flags_ |= NGHTTP2_STREAM_FLAG_DESTROYED;
655 Nghttp2Session* session = this->session_;
657 if (session !=
nullptr) {
659 session_->RemoveStream(this->
id());
664 while (data_chunks_head_ !=
nullptr) {
665 nghttp2_data_chunk_t* chunk = data_chunks_head_;
666 data_chunks_head_ = chunk->next;
667 delete[] chunk->buf.base;
668 data_chunk_free_list.push(chunk);
670 data_chunks_tail_ =
nullptr;
673 while (queue_head_ !=
nullptr) {
674 nghttp2_stream_write_queue* head = queue_head_;
675 queue_head_ = head->next;
676 head->cb(head->req, UV_ECANCELED);
679 queue_tail_ =
nullptr;
685 stream_free_list.push(
this);
688 inline void Nghttp2Stream::FreeHeaders() {
689 DEBUG_HTTP2(
"Nghttp2Stream %d: freeing headers\n", id_);
690 while (current_headers_head_ !=
nullptr) {
691 DEBUG_HTTP2(
"Nghttp2Stream %d: freeing header item\n", id_);
692 nghttp2_header_list* item = current_headers_head_;
693 current_headers_head_ = item->next;
694 header_free_list.push(item);
696 current_headers_tail_ =
nullptr;
700 inline int Nghttp2Stream::SubmitInfo(nghttp2_nv* nva,
size_t len) {
701 DEBUG_HTTP2(
"Nghttp2Stream %d: sending informational headers, count: %d\n",
704 return nghttp2_submit_headers(session_->session(),
710 inline int Nghttp2Stream::SubmitPriority(nghttp2_priority_spec* prispec,
712 DEBUG_HTTP2(
"Nghttp2Stream %d: sending priority spec\n", id_);
714 nghttp2_session_change_stream_priority(session_->session(),
716 nghttp2_submit_priority(session_->session(),
722 inline int Nghttp2Stream::SubmitRstStream(
const uint32_t code) {
723 DEBUG_HTTP2(
"Nghttp2Stream %d: sending rst-stream, code: %d\n", id_, code);
724 session_->SendPendingData();
725 return nghttp2_submit_rst_stream(session_->session(),
732 inline int32_t Nghttp2Stream::SubmitPushPromise(
735 Nghttp2Stream** assigned,
738 DEBUG_HTTP2(
"Nghttp2Stream %d: sending push promise\n", id_);
739 int32_t ret = nghttp2_submit_push_promise(session_->session(),
745 if (emptyPayload) stream->Shutdown();
746 if (assigned !=
nullptr) *assigned = stream;
755 inline int Nghttp2Stream::SubmitResponse(nghttp2_nv* nva,
760 DEBUG_HTTP2(
"Nghttp2Stream %d: submitting response\n", id_);
761 getTrailers_ = getTrailers;
762 nghttp2_data_provider* provider =
nullptr;
763 nghttp2_data_provider prov;
764 prov.source.ptr =
this;
765 prov.read_callback = Nghttp2Session::OnStreamRead;
766 if (!emptyPayload && IsWritable())
769 return nghttp2_submit_response(session_->session(), id_,
774 inline int Nghttp2Stream::SubmitFile(
int fd,
775 nghttp2_nv* nva,
size_t len,
781 DEBUG_HTTP2(
"Nghttp2Stream %d: submitting file\n", id_);
782 getTrailers_ = getTrailers;
783 nghttp2_data_provider prov;
784 prov.source.ptr =
this;
786 prov.read_callback = Nghttp2Session::OnStreamReadFD;
788 if (offset > 0) fd_offset_ = offset;
789 if (length > -1) fd_length_ = length;
791 return nghttp2_submit_response(session_->session(), id_,
798 inline int32_t Nghttp2Session::SubmitRequest(
799 nghttp2_priority_spec* prispec,
802 Nghttp2Stream** assigned,
806 DEBUG_HTTP2(
"Nghttp2Session: submitting request\n");
807 nghttp2_data_provider* provider =
nullptr;
808 nghttp2_data_provider prov;
809 prov.source.ptr =
this;
810 prov.read_callback = OnStreamRead;
813 int32_t ret = nghttp2_submit_request(session_,
819 NGHTTP2_HCAT_HEADERS,
821 if (emptyPayload) stream->Shutdown();
822 if (assigned !=
nullptr) *assigned = stream;
832 inline int Nghttp2Stream::Write(nghttp2_stream_write_t*
req,
833 const uv_buf_t bufs[],
835 nghttp2_stream_write_cb cb) {
841 DEBUG_HTTP2(
"Nghttp2Stream %d: queuing buffers to send, count: %d\n",
843 nghttp2_stream_write_queue* item =
new nghttp2_stream_write_queue;
847 item->bufs.AllocateSufficientStorage(nbufs);
850 memcpy(*(item->bufs), bufs, nbufs *
sizeof(*bufs));
852 if (queue_head_ ==
nullptr) {
856 queue_tail_->next = item;
859 nghttp2_session_resume_data(session_->session(), id_);
863 inline void Nghttp2Stream::ReadStart() {
867 DEBUG_HTTP2(
"Nghttp2Stream %d: start reading\n", id_);
874 nghttp2_session_set_local_window_size(session_->session(),
877 prev_local_window_size_);
879 flags_ |= NGHTTP2_STREAM_FLAG_READ_START;
880 flags_ &= ~NGHTTP2_STREAM_FLAG_READ_PAUSED;
886 inline void Nghttp2Stream::ReadStop() {
887 DEBUG_HTTP2(
"Nghttp2Stream %d: stop reading\n", id_);
893 flags_ |= NGHTTP2_STREAM_FLAG_READ_PAUSED;
898 nghttp2_session_get_stream_local_window_size(session_->session(), id_);
900 prev_local_window_size_ = ret;
901 nghttp2_session_set_local_window_size(session_->session(),
906 nghttp2_data_chunks_t::~nghttp2_data_chunks_t() {
907 for (
unsigned int n = 0; n < nbufs; n++) {
912 Nghttp2Session::Callbacks::Callbacks(
bool kHasGetPaddingCallback) {
913 nghttp2_session_callbacks_new(&callbacks);
914 nghttp2_session_callbacks_set_on_begin_headers_callback(
915 callbacks, OnBeginHeadersCallback);
916 nghttp2_session_callbacks_set_on_header_callback2(
917 callbacks, OnHeaderCallback);
918 nghttp2_session_callbacks_set_on_frame_recv_callback(
919 callbacks, OnFrameReceive);
920 nghttp2_session_callbacks_set_on_stream_close_callback(
921 callbacks, OnStreamClose);
922 nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
923 callbacks, OnDataChunkReceived);
924 nghttp2_session_callbacks_set_on_frame_not_send_callback(
925 callbacks, OnFrameNotSent);
926 nghttp2_session_callbacks_set_on_invalid_header_callback2(
927 callbacks, OnInvalidHeader);
929 #ifdef NODE_DEBUG_HTTP2 930 nghttp2_session_callbacks_set_error_callback(
931 callbacks, OnNghttpError);
934 if (kHasGetPaddingCallback) {
935 nghttp2_session_callbacks_set_select_padding_callback(
936 callbacks, OnSelectPadding);
940 Nghttp2Session::Callbacks::~Callbacks() {
941 nghttp2_session_callbacks_del(callbacks);
944 Nghttp2Session::SubmitTrailers::SubmitTrailers(
945 Nghttp2Session* handle,
946 Nghttp2Stream* stream,
948 : handle_(handle), stream_(stream), flags_(flags) { }
953 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 955 #endif // SRC_NODE_HTTP2_CORE_INL_H_
Freelist< Nghttp2Stream, FREELIST_MAX > stream_free_list
union node::cares_wrap::@8::CaresAsyncData::@0 data
Freelist< nghttp2_data_chunks_t, FREELIST_MAX > data_chunks_free_list
Freelist< nghttp2_header_list, FREELIST_MAX > header_free_list
void Init(int *argc, const char **argv, int *exec_argc, const char ***exec_argv)
Freelist< nghttp2_data_chunk_t, FREELIST_MAX > data_chunk_free_list