1 #ifndef SRC_NODE_HTTP2_H_ 2 #define SRC_NODE_HTTP2_H_ 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 15 using v8::EscapableHandleScope;
19 #define HTTP_KNOWN_METHODS(V) \ 21 V(BASELINE_CONTROL, "BASELINE-CONTROL") \ 23 V(CHECKIN, "CHECKIN") \ 24 V(CHECKOUT, "CHECKOUT") \ 25 V(CONNECT, "CONNECT") \ 34 V(MKACTIVITY, "MKACTIVITY") \ 35 V(MKCALENDAR, "MKCALENDAR") \ 37 V(MKREDIRECTREF, "MKREDIRECTREF") \ 38 V(MKWORKSPACE, "MKWORKSPACE") \ 40 V(OPTIONS, "OPTIONS") \ 41 V(ORDERPATCH, "ORDERPATCH") \ 45 V(PROPFIND, "PROPFIND") \ 46 V(PROPPATCH, "PROPPATCH") \ 53 V(UNCHECKOUT, "UNCHECKOUT") \ 57 V(UPDATEREDIRECTREF, "UPDATEREDIRECTREF") \ 58 V(VERSION_CONTROL, "VERSION-CONTROL") 60 #define HTTP_KNOWN_HEADERS(V) \ 61 V(STATUS, ":status") \ 62 V(METHOD, ":method") \ 63 V(AUTHORITY, ":authority") \ 64 V(SCHEME, ":scheme") \ 66 V(ACCEPT_CHARSET, "accept-charset") \ 67 V(ACCEPT_ENCODING, "accept-encoding") \ 68 V(ACCEPT_LANGUAGE, "accept-language") \ 69 V(ACCEPT_RANGES, "accept-ranges") \ 71 V(ACCESS_CONTROL_ALLOW_ORIGIN, "access-control-allow-origin") \ 74 V(AUTHORIZATION, "authorization") \ 75 V(CACHE_CONTROL, "cache-control") \ 76 V(CONNECTION, "connection") \ 77 V(CONTENT_DISPOSITION, "content-disposition") \ 78 V(CONTENT_ENCODING, "content-encoding") \ 79 V(CONTENT_LANGUAGE, "content-language") \ 80 V(CONTENT_LENGTH, "content-length") \ 81 V(CONTENT_LOCATION, "content-location") \ 82 V(CONTENT_MD5, "content-md5") \ 83 V(CONTENT_RANGE, "content-range") \ 84 V(CONTENT_TYPE, "content-type") \ 89 V(EXPIRES, "expires") \ 92 V(IF_MATCH, "if-match") \ 93 V(IF_MODIFIED_SINCE, "if-modified-since") \ 94 V(IF_NONE_MATCH, "if-none-match") \ 95 V(IF_RANGE, "if-range") \ 96 V(IF_UNMODIFIED_SINCE, "if-unmodified-since") \ 97 V(LAST_MODIFIED, "last-modified") \ 99 V(LOCATION, "location") \ 100 V(MAX_FORWARDS, "max-forwards") \ 101 V(PREFER, "prefer") \ 102 V(PROXY_AUTHENTICATE, "proxy-authenticate") \ 103 V(PROXY_AUTHORIZATION, "proxy-authorization") \ 105 V(REFERER, "referer") \ 106 V(REFRESH, "refresh") \ 107 V(RETRY_AFTER, "retry-after") \ 108 V(SERVER, "server") \ 109 V(SET_COOKIE, "set-cookie") \ 110 V(STRICT_TRANSPORT_SECURITY, "strict-transport-security") \ 111 V(TRANSFER_ENCODING, "transfer-encoding") \ 113 V(UPGRADE, "upgrade") \ 114 V(USER_AGENT, "user-agent") \ 117 V(WWW_AUTHENTICATE, "www-authenticate") \ 118 V(HTTP2_SETTINGS, "http2-settings") \ 119 V(KEEP_ALIVE, "keep-alive") \ 120 V(PROXY_CONNECTION, "proxy-connection") 122 enum http_known_headers {
123 HTTP_KNOWN_HEADER_MIN,
124 #define V(name, value) HTTP_HEADER_##name, 125 HTTP_KNOWN_HEADERS(
V)
127 HTTP_KNOWN_HEADER_MAX
130 #define HTTP_STATUS_CODES(V) \ 132 V(SWITCHING_PROTOCOLS, 101) \ 137 V(NON_AUTHORITATIVE_INFORMATION, 203) \ 139 V(RESET_CONTENT, 205) \ 140 V(PARTIAL_CONTENT, 206) \ 141 V(MULTI_STATUS, 207) \ 142 V(ALREADY_REPORTED, 208) \ 144 V(MULTIPLE_CHOICES, 300) \ 145 V(MOVED_PERMANENTLY, 301) \ 148 V(NOT_MODIFIED, 304) \ 150 V(TEMPORARY_REDIRECT, 307) \ 151 V(PERMANENT_REDIRECT, 308) \ 152 V(BAD_REQUEST, 400) \ 153 V(UNAUTHORIZED, 401) \ 154 V(PAYMENT_REQUIRED, 402) \ 157 V(METHOD_NOT_ALLOWED, 405) \ 158 V(NOT_ACCEPTABLE, 406) \ 159 V(PROXY_AUTHENTICATION_REQUIRED, 407) \ 160 V(REQUEST_TIMEOUT, 408) \ 163 V(LENGTH_REQUIRED, 411) \ 164 V(PRECONDITION_FAILED, 412) \ 165 V(PAYLOAD_TOO_LARGE, 413) \ 166 V(URI_TOO_LONG, 414) \ 167 V(UNSUPPORTED_MEDIA_TYPE, 415) \ 168 V(RANGE_NOT_SATISFIABLE, 416) \ 169 V(EXPECTATION_FAILED, 417) \ 171 V(MISDIRECTED_REQUEST, 421) \ 172 V(UNPROCESSABLE_ENTITY, 422) \ 174 V(FAILED_DEPENDENCY, 424) \ 175 V(UNORDERED_COLLECTION, 425) \ 176 V(UPGRADE_REQUIRED, 426) \ 177 V(PRECONDITION_REQUIRED, 428) \ 178 V(TOO_MANY_REQUESTS, 429) \ 179 V(REQUEST_HEADER_FIELDS_TOO_LARGE, 431) \ 180 V(UNAVAILABLE_FOR_LEGAL_REASONS, 451) \ 181 V(INTERNAL_SERVER_ERROR, 500) \ 182 V(NOT_IMPLEMENTED, 501) \ 183 V(BAD_GATEWAY, 502) \ 184 V(SERVICE_UNAVAILABLE, 503) \ 185 V(GATEWAY_TIMEOUT, 504) \ 186 V(HTTP_VERSION_NOT_SUPPORTED, 505) \ 187 V(VARIANT_ALSO_NEGOTIATES, 506) \ 188 V(INSUFFICIENT_STORAGE, 507) \ 189 V(LOOP_DETECTED, 508) \ 190 V(BANDWIDTH_LIMIT_EXCEEDED, 509) \ 191 V(NOT_EXTENDED, 510) \ 192 V(NETWORK_AUTHENTICATION_REQUIRED, 511) 194 enum http_status_codes {
195 #define V(name, code) HTTP_STATUS_##name = code, 200 enum padding_strategy_type {
202 PADDING_STRATEGY_NONE,
204 PADDING_STRATEGY_MAX,
206 PADDING_STRATEGY_CALLBACK
209 #define NGHTTP2_ERROR_CODES(V) \ 210 V(NGHTTP2_ERR_INVALID_ARGUMENT) \ 211 V(NGHTTP2_ERR_BUFFER_ERROR) \ 212 V(NGHTTP2_ERR_UNSUPPORTED_VERSION) \ 213 V(NGHTTP2_ERR_WOULDBLOCK) \ 214 V(NGHTTP2_ERR_PROTO) \ 215 V(NGHTTP2_ERR_INVALID_FRAME) \ 217 V(NGHTTP2_ERR_DEFERRED) \ 218 V(NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE) \ 219 V(NGHTTP2_ERR_STREAM_CLOSED) \ 220 V(NGHTTP2_ERR_STREAM_CLOSING) \ 221 V(NGHTTP2_ERR_STREAM_SHUT_WR) \ 222 V(NGHTTP2_ERR_INVALID_STREAM_ID) \ 223 V(NGHTTP2_ERR_INVALID_STREAM_STATE) \ 224 V(NGHTTP2_ERR_DEFERRED_DATA_EXIST) \ 225 V(NGHTTP2_ERR_START_STREAM_NOT_ALLOWED) \ 226 V(NGHTTP2_ERR_GOAWAY_ALREADY_SENT) \ 227 V(NGHTTP2_ERR_INVALID_HEADER_BLOCK) \ 228 V(NGHTTP2_ERR_INVALID_STATE) \ 229 V(NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) \ 230 V(NGHTTP2_ERR_FRAME_SIZE_ERROR) \ 231 V(NGHTTP2_ERR_HEADER_COMP) \ 232 V(NGHTTP2_ERR_FLOW_CONTROL) \ 233 V(NGHTTP2_ERR_INSUFF_BUFSIZE) \ 234 V(NGHTTP2_ERR_PAUSE) \ 235 V(NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS) \ 236 V(NGHTTP2_ERR_PUSH_DISABLED) \ 237 V(NGHTTP2_ERR_DATA_EXIST) \ 238 V(NGHTTP2_ERR_SESSION_CLOSING) \ 239 V(NGHTTP2_ERR_HTTP_HEADER) \ 240 V(NGHTTP2_ERR_HTTP_MESSAGING) \ 241 V(NGHTTP2_ERR_REFUSED_STREAM) \ 242 V(NGHTTP2_ERR_INTERNAL) \ 243 V(NGHTTP2_ERR_CANCEL) \ 244 V(NGHTTP2_ERR_FATAL) \ 245 V(NGHTTP2_ERR_NOMEM) \ 246 V(NGHTTP2_ERR_CALLBACK_FAILURE) \ 247 V(NGHTTP2_ERR_BAD_CLIENT_MAGIC) \ 248 V(NGHTTP2_ERR_FLOODED) 250 const char* nghttp2_errname(
int rv) {
252 #define V(code) case code: return #code; 253 NGHTTP2_ERROR_CODES(
V)
256 return "NGHTTP2_UNKNOWN_ERROR";
260 #define DEFAULT_SETTINGS_HEADER_TABLE_SIZE 4096 261 #define DEFAULT_SETTINGS_ENABLE_PUSH 1 262 #define DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE 65535 263 #define DEFAULT_SETTINGS_MAX_FRAME_SIZE 16384 264 #define MAX_MAX_FRAME_SIZE 16777215 265 #define MIN_MAX_FRAME_SIZE DEFAULT_SETTINGS_MAX_FRAME_SIZE 266 #define MAX_INITIAL_WINDOW_SIZE 2147483647 270 explicit Http2Options(Environment* env);
273 nghttp2_option_del(options_);
276 nghttp2_option* operator*()
const {
280 void SetPaddingStrategy(padding_strategy_type val) {
281 CHECK_LE(val, PADDING_STRATEGY_CALLBACK);
282 padding_strategy_ =
static_cast<padding_strategy_type
>(val);
285 padding_strategy_type GetPaddingStrategy() {
286 return padding_strategy_;
290 nghttp2_option* options_;
291 padding_strategy_type padding_strategy_ = PADDING_STRATEGY_NONE;
294 static const size_t kAllocBufferSize = 64 * 1024;
297 typedef uint32_t(*get_setting)(nghttp2_session* session,
298 nghttp2_settings_id id);
300 class Http2Session :
public AsyncWrap,
302 public Nghttp2Session {
304 Http2Session(Environment* env,
306 nghttp2_session_type type) :
307 AsyncWrap(env, wrap, AsyncWrap::PROVIDER_HTTP2SESSION),
309 Wrap(
object(),
this);
311 Http2Options opts(env);
313 padding_strategy_ = opts.GetPaddingStrategy();
315 Init(env->event_loop(), type, *opts);
318 ~Http2Session()
override {
319 CHECK_EQ(
false, persistent().IsEmpty());
321 persistent().Reset();
322 CHECK_EQ(
true, persistent().IsEmpty());
325 static void OnStreamAllocImpl(
size_t suggested_size,
328 static void OnStreamReadImpl(ssize_t nread,
329 const uv_buf_t* bufs,
330 uv_handle_type pending,
333 void OnFreeSession()
override;
335 ssize_t OnMaxFrameSizePadding(
size_t frameLength,
336 size_t maxPayloadLen);
338 ssize_t OnCallbackPadding(
size_t frame,
339 size_t maxPayloadLen);
341 bool HasGetPaddingCallback()
override {
342 return padding_strategy_ == PADDING_STRATEGY_MAX ||
343 padding_strategy_ == PADDING_STRATEGY_CALLBACK;
346 ssize_t GetPadding(
size_t frameLength,
size_t maxPayloadLen)
override {
347 if (padding_strategy_ == PADDING_STRATEGY_MAX) {
348 return OnMaxFrameSizePadding(frameLength, maxPayloadLen);
351 CHECK_EQ(padding_strategy_, PADDING_STRATEGY_CALLBACK);
353 return OnCallbackPadding(frameLength, maxPayloadLen);
356 void OnHeaders(Nghttp2Stream* stream,
357 nghttp2_header_list* headers,
358 nghttp2_headers_category cat,
359 uint8_t flags)
override;
360 void OnStreamClose(int32_t
id, uint32_t code)
override;
361 void Send(uv_buf_t* bufs,
size_t total)
override;
362 void OnDataChunk(Nghttp2Stream* stream, nghttp2_data_chunk_t* chunk)
override;
363 void OnSettings(
bool ack)
override;
364 void OnPriority(int32_t stream,
367 int8_t exclusive)
override;
368 void OnGoAway(int32_t lastStreamID,
371 size_t length)
override;
372 void OnFrameError(int32_t
id, uint8_t type,
int error_code)
override;
373 void OnTrailers(Nghttp2Stream* stream,
374 const SubmitTrailers& submit_trailers)
override;
375 void AllocateSend(
size_t recommended, uv_buf_t*
buf)
override;
377 int DoWrite(WriteWrap* w, uv_buf_t* bufs,
size_t count,
378 uv_stream_t* send_handle)
override;
380 AsyncWrap* GetAsyncWrap()
override {
381 return static_cast<AsyncWrap*
>(
this);
384 void* Cast()
override {
385 return reinterpret_cast<void*
>(
this);
389 bool IsAlive()
override {
394 bool IsClosing()
override {
399 int ReadStart()
override {
return 0; }
402 int ReadStop()
override {
return 0; }
405 int DoShutdown(ShutdownWrap* req_wrap)
override {
410 void Consume(Local<External> external);
413 static void New(
const FunctionCallbackInfo<Value>& args);
414 static void Consume(
const FunctionCallbackInfo<Value>& args);
415 static void Unconsume(
const FunctionCallbackInfo<Value>& args);
416 static void Destroying(
const FunctionCallbackInfo<Value>& args);
417 static void Destroy(
const FunctionCallbackInfo<Value>& args);
418 static void SubmitSettings(
const FunctionCallbackInfo<Value>& args);
419 static void SubmitRstStream(
const FunctionCallbackInfo<Value>& args);
420 static void SubmitResponse(
const FunctionCallbackInfo<Value>& args);
421 static void SubmitFile(
const FunctionCallbackInfo<Value>& args);
422 static void SubmitRequest(
const FunctionCallbackInfo<Value>& args);
423 static void SubmitPushPromise(
const FunctionCallbackInfo<Value>& args);
424 static void SubmitPriority(
const FunctionCallbackInfo<Value>& args);
425 static void SendHeaders(
const FunctionCallbackInfo<Value>& args);
426 static void ShutdownStream(
const FunctionCallbackInfo<Value>& args);
427 static void StreamWrite(
const FunctionCallbackInfo<Value>& args);
428 static void StreamReadStart(
const FunctionCallbackInfo<Value>& args);
429 static void StreamReadStop(
const FunctionCallbackInfo<Value>& args);
430 static void SetNextStreamID(
const FunctionCallbackInfo<Value>& args);
431 static void SendShutdownNotice(
const FunctionCallbackInfo<Value>& args);
432 static void SubmitGoaway(
const FunctionCallbackInfo<Value>& args);
433 static void DestroyStream(
const FunctionCallbackInfo<Value>& args);
435 template <get_setting fn>
436 static void GetSettings(
const FunctionCallbackInfo<Value>& args);
438 size_t self_size()
const override {
439 return sizeof(*this);
442 char* stream_alloc() {
449 StreamResource::Callback<StreamResource::ReadCb>
prev_read_cb_;
450 padding_strategy_type padding_strategy_ = PADDING_STRATEGY_NONE;
452 char stream_buf_[kAllocBufferSize];
455 class ExternalHeader :
456 public String::ExternalOneByteStringResource {
458 explicit ExternalHeader(nghttp2_rcbuf*
buf)
459 : buf_(buf), vec_(nghttp2_rcbuf_get_buf(buf)) {
462 ~ExternalHeader()
override {
463 nghttp2_rcbuf_decref(buf_);
467 const char*
data()
const override {
468 return const_cast<const char*
>(
reinterpret_cast<char*
>(vec_.base));
471 size_t length()
const override {
476 MaybeLocal<String> GetInternalizedString(Environment* env,
477 const nghttp2_vec& vec) {
478 return String::NewFromOneByte(env->isolate(),
480 v8::NewStringType::kInternalized,
484 template<
bool may_
internalize>
485 static MaybeLocal<String>
New(Environment* env, nghttp2_rcbuf*
buf) {
486 if (nghttp2_rcbuf_is_static(buf)) {
487 auto& static_str_map = env->isolate_data()->http2_static_strs;
488 v8::Eternal<v8::String>& eternal = static_str_map[
buf];
489 if (eternal.IsEmpty()) {
491 GetInternalizedString(env, nghttp2_rcbuf_get_buf(buf))
493 eternal.Set(env->isolate(), str);
496 return eternal.Get(env->isolate());
499 nghttp2_vec vec = nghttp2_rcbuf_get_buf(buf);
501 nghttp2_rcbuf_decref(buf);
502 return String::Empty(env->isolate());
505 if (may_internalize && vec.len < 64) {
508 return GetInternalizedString(env, vec);
511 ExternalHeader* h_str =
new ExternalHeader(buf);
512 MaybeLocal<String> str = String::NewExternalOneByte(env->isolate(), h_str);
526 Headers(Isolate* isolate, Local<Context> context, Local<Array> headers);
529 nghttp2_nv* operator*() {
530 return reinterpret_cast<nghttp2_nv*
>(*buf_);
533 size_t length()
const {
539 MaybeStackBuffer<char, 3000> buf_;
545 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 547 #endif // SRC_NODE_HTTP2_H_ StreamResource::Callback< StreamResource::AllocCb > prev_alloc_cb_
union node::cares_wrap::@8::CaresAsyncData::@0 data
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
void Init(int *argc, const char **argv, int *exec_argc, const char ***exec_argv)
StreamResource::Callback< StreamResource::ReadCb > prev_read_cb_