// Flags: --expose-http2 'use strict'; const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); assert.doesNotThrow(() => process.binding('http2')); const binding = process.binding('http2'); const http2 = require('http2'); assert(binding.Http2Session); assert.strictEqual(typeof binding.Http2Session, 'function'); const settings = http2.getDefaultSettings(); assert.strictEqual(settings.headerTableSize, 4096); assert.strictEqual(settings.enablePush, true); assert.strictEqual(settings.initialWindowSize, 65535); assert.strictEqual(settings.maxFrameSize, 16384); assert.strictEqual(binding.nghttp2ErrorString(-517), 'GOAWAY has already been sent'); // assert constants are present assert(binding.constants); assert.strictEqual(typeof binding.constants, 'object'); const constants = binding.constants; const expectedStatusCodes = { HTTP_STATUS_CONTINUE: 100, HTTP_STATUS_SWITCHING_PROTOCOLS: 101, HTTP_STATUS_PROCESSING: 102, HTTP_STATUS_OK: 200, HTTP_STATUS_CREATED: 201, HTTP_STATUS_ACCEPTED: 202, HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION: 203, HTTP_STATUS_NO_CONTENT: 204, HTTP_STATUS_RESET_CONTENT: 205, HTTP_STATUS_PARTIAL_CONTENT: 206, HTTP_STATUS_MULTI_STATUS: 207, HTTP_STATUS_ALREADY_REPORTED: 208, HTTP_STATUS_IM_USED: 226, HTTP_STATUS_MULTIPLE_CHOICES: 300, HTTP_STATUS_MOVED_PERMANENTLY: 301, HTTP_STATUS_FOUND: 302, HTTP_STATUS_SEE_OTHER: 303, HTTP_STATUS_NOT_MODIFIED: 304, HTTP_STATUS_USE_PROXY: 305, HTTP_STATUS_TEMPORARY_REDIRECT: 307, HTTP_STATUS_PERMANENT_REDIRECT: 308, HTTP_STATUS_BAD_REQUEST: 400, HTTP_STATUS_UNAUTHORIZED: 401, HTTP_STATUS_PAYMENT_REQUIRED: 402, HTTP_STATUS_FORBIDDEN: 403, HTTP_STATUS_NOT_FOUND: 404, HTTP_STATUS_METHOD_NOT_ALLOWED: 405, HTTP_STATUS_NOT_ACCEPTABLE: 406, HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED: 407, HTTP_STATUS_REQUEST_TIMEOUT: 408, HTTP_STATUS_CONFLICT: 409, HTTP_STATUS_GONE: 410, HTTP_STATUS_LENGTH_REQUIRED: 411, HTTP_STATUS_PRECONDITION_FAILED: 412, HTTP_STATUS_PAYLOAD_TOO_LARGE: 413, HTTP_STATUS_URI_TOO_LONG: 414, HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE: 415, HTTP_STATUS_RANGE_NOT_SATISFIABLE: 416, HTTP_STATUS_EXPECTATION_FAILED: 417, HTTP_STATUS_TEAPOT: 418, HTTP_STATUS_MISDIRECTED_REQUEST: 421, HTTP_STATUS_UNPROCESSABLE_ENTITY: 422, HTTP_STATUS_LOCKED: 423, HTTP_STATUS_FAILED_DEPENDENCY: 424, HTTP_STATUS_UNORDERED_COLLECTION: 425, HTTP_STATUS_UPGRADE_REQUIRED: 426, HTTP_STATUS_PRECONDITION_REQUIRED: 428, HTTP_STATUS_TOO_MANY_REQUESTS: 429, HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE: 431, HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS: 451, HTTP_STATUS_INTERNAL_SERVER_ERROR: 500, HTTP_STATUS_NOT_IMPLEMENTED: 501, HTTP_STATUS_BAD_GATEWAY: 502, HTTP_STATUS_SERVICE_UNAVAILABLE: 503, HTTP_STATUS_GATEWAY_TIMEOUT: 504, HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED: 505, HTTP_STATUS_VARIANT_ALSO_NEGOTIATES: 506, HTTP_STATUS_INSUFFICIENT_STORAGE: 507, HTTP_STATUS_LOOP_DETECTED: 508, HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED: 509, HTTP_STATUS_NOT_EXTENDED: 510, HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED: 511 }; const expectedHeaderNames = { HTTP2_HEADER_STATUS: ':status', HTTP2_HEADER_METHOD: ':method', HTTP2_HEADER_AUTHORITY: ':authority', HTTP2_HEADER_SCHEME: ':scheme', HTTP2_HEADER_PATH: ':path', HTTP2_HEADER_DATE: 'date', HTTP2_HEADER_ACCEPT_CHARSET: 'accept-charset', HTTP2_HEADER_ACCEPT_ENCODING: 'accept-encoding', HTTP2_HEADER_ACCEPT_LANGUAGE: 'accept-language', HTTP2_HEADER_ACCEPT_RANGES: 'accept-ranges', HTTP2_HEADER_ACCEPT: 'accept', HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN: 'access-control-allow-origin', HTTP2_HEADER_AGE: 'age', HTTP2_HEADER_ALLOW: 'allow', HTTP2_HEADER_AUTHORIZATION: 'authorization', HTTP2_HEADER_CACHE_CONTROL: 'cache-control', HTTP2_HEADER_CONTENT_DISPOSITION: 'content-disposition', HTTP2_HEADER_CONTENT_ENCODING: 'content-encoding', HTTP2_HEADER_CONTENT_LANGUAGE: 'content-language', HTTP2_HEADER_CONTENT_LENGTH: 'content-length', HTTP2_HEADER_CONTENT_LOCATION: 'content-location', HTTP2_HEADER_CONTENT_RANGE: 'content-range', HTTP2_HEADER_CONTENT_TYPE: 'content-type', HTTP2_HEADER_COOKIE: 'cookie', HTTP2_HEADER_CONNECTION: 'connection', HTTP2_HEADER_ETAG: 'etag', HTTP2_HEADER_EXPECT: 'expect', HTTP2_HEADER_EXPIRES: 'expires', HTTP2_HEADER_FROM: 'from', HTTP2_HEADER_HOST: 'host', HTTP2_HEADER_IF_MATCH: 'if-match', HTTP2_HEADER_IF_MODIFIED_SINCE: 'if-modified-since', HTTP2_HEADER_IF_NONE_MATCH: 'if-none-match', HTTP2_HEADER_IF_RANGE: 'if-range', HTTP2_HEADER_IF_UNMODIFIED_SINCE: 'if-unmodified-since', HTTP2_HEADER_LAST_MODIFIED: 'last-modified', HTTP2_HEADER_LINK: 'link', HTTP2_HEADER_LOCATION: 'location', HTTP2_HEADER_MAX_FORWARDS: 'max-forwards', HTTP2_HEADER_PREFER: 'prefer', HTTP2_HEADER_PROXY_AUTHENTICATE: 'proxy-authenticate', HTTP2_HEADER_PROXY_AUTHORIZATION: 'proxy-authorization', HTTP2_HEADER_PROXY_CONNECTION: 'proxy-connection', HTTP2_HEADER_RANGE: 'range', HTTP2_HEADER_REFERER: 'referer', HTTP2_HEADER_REFRESH: 'refresh', HTTP2_HEADER_RETRY_AFTER: 'retry-after', HTTP2_HEADER_SERVER: 'server', HTTP2_HEADER_SET_COOKIE: 'set-cookie', HTTP2_HEADER_STRICT_TRANSPORT_SECURITY: 'strict-transport-security', HTTP2_HEADER_TRANSFER_ENCODING: 'transfer-encoding', HTTP2_HEADER_USER_AGENT: 'user-agent', HTTP2_HEADER_VARY: 'vary', HTTP2_HEADER_VIA: 'via', HTTP2_HEADER_WWW_AUTHENTICATE: 'www-authenticate', HTTP2_HEADER_KEEP_ALIVE: 'keep-alive', HTTP2_HEADER_CONTENT_MD5: 'content-md5', HTTP2_HEADER_TE: 'te', HTTP2_HEADER_UPGRADE: 'upgrade', HTTP2_HEADER_HTTP2_SETTINGS: 'http2-settings' }; const expectedNGConstants = { NGHTTP2_SESSION_SERVER: 0, NGHTTP2_SESSION_CLIENT: 1, NGHTTP2_STREAM_STATE_IDLE: 1, NGHTTP2_STREAM_STATE_OPEN: 2, NGHTTP2_STREAM_STATE_RESERVED_LOCAL: 3, NGHTTP2_STREAM_STATE_RESERVED_REMOTE: 4, NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL: 5, NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE: 6, NGHTTP2_STREAM_STATE_CLOSED: 7, NGHTTP2_HCAT_REQUEST: 0, NGHTTP2_HCAT_RESPONSE: 1, NGHTTP2_HCAT_PUSH_RESPONSE: 2, NGHTTP2_HCAT_HEADERS: 3, NGHTTP2_NO_ERROR: 0, NGHTTP2_PROTOCOL_ERROR: 1, NGHTTP2_INTERNAL_ERROR: 2, NGHTTP2_FLOW_CONTROL_ERROR: 3, NGHTTP2_SETTINGS_TIMEOUT: 4, NGHTTP2_STREAM_CLOSED: 5, NGHTTP2_FRAME_SIZE_ERROR: 6, NGHTTP2_REFUSED_STREAM: 7, NGHTTP2_CANCEL: 8, NGHTTP2_COMPRESSION_ERROR: 9, NGHTTP2_CONNECT_ERROR: 10, NGHTTP2_ENHANCE_YOUR_CALM: 11, NGHTTP2_INADEQUATE_SECURITY: 12, NGHTTP2_HTTP_1_1_REQUIRED: 13, NGHTTP2_NV_FLAG_NONE: 0, NGHTTP2_NV_FLAG_NO_INDEX: 1, NGHTTP2_ERR_DEFERRED: -508, NGHTTP2_ERR_NOMEM: -901, NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE: -509, NGHTTP2_ERR_INVALID_ARGUMENT: -501, NGHTTP2_ERR_STREAM_CLOSED: -510, NGHTTP2_ERR_FRAME_SIZE_ERROR: -522, NGHTTP2_FLAG_NONE: 0, NGHTTP2_FLAG_END_STREAM: 1, NGHTTP2_FLAG_END_HEADERS: 4, NGHTTP2_FLAG_ACK: 1, NGHTTP2_FLAG_PADDED: 8, NGHTTP2_FLAG_PRIORITY: 32, NGHTTP2_DEFAULT_WEIGHT: 16, NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: 1, NGHTTP2_SETTINGS_ENABLE_PUSH: 2, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: 3, NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: 4, NGHTTP2_SETTINGS_MAX_FRAME_SIZE: 5, NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: 6 }; const defaultSettings = { DEFAULT_SETTINGS_HEADER_TABLE_SIZE: 4096, DEFAULT_SETTINGS_ENABLE_PUSH: 1, DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE: 65535, DEFAULT_SETTINGS_MAX_FRAME_SIZE: 16384 }; for (const name of Object.keys(constants)) { if (name.startsWith('HTTP_STATUS_')) { assert.strictEqual(expectedStatusCodes[name], constants[name], `Expected status code match for ${name}`); } else if (name.startsWith('HTTP2_HEADER_')) { assert.strictEqual(expectedHeaderNames[name], constants[name], `Expected header name match for ${name}`); } else if (name.startsWith('NGHTTP2_')) { assert.strictEqual(expectedNGConstants[name], constants[name], `Expected ng constant match for ${name}`); } else if (name.startsWith('DEFAULT_SETTINGS_')) { assert.strictEqual(defaultSettings[name], constants[name], `Expected default setting match for ${name}`); } }