mirror of
https://github.com/denoland/deno
synced 2024-09-29 21:05:38 +00:00
feat(ext/node): support http2session.socket
This commit is contained in:
parent
96cfe82664
commit
87c596ade3
|
@ -4,7 +4,7 @@
|
|||
// TODO(petamoriken): enable prefer-primordials for node polyfills
|
||||
// deno-lint-ignore-file prefer-primordials
|
||||
|
||||
import { core } from "ext:core/mod.js";
|
||||
import { core, primordials } from "ext:core/mod.js";
|
||||
import {
|
||||
op_http2_client_get_response,
|
||||
op_http2_client_get_response_body_chunk,
|
||||
|
@ -16,6 +16,7 @@ import {
|
|||
op_http2_connect,
|
||||
op_http2_poll_client_connection,
|
||||
} from "ext:core/ops";
|
||||
const { FunctionPrototypeBind, ReflectGetPrototypeOf } = primordials;
|
||||
|
||||
import { notImplemented, warnNotImplemented } from "ext:deno_node/_utils.ts";
|
||||
import { EventEmitter } from "node:events";
|
||||
|
@ -44,7 +45,9 @@ import {
|
|||
ERR_HTTP2_INVALID_PSEUDOHEADER,
|
||||
ERR_HTTP2_INVALID_SESSION,
|
||||
ERR_HTTP2_INVALID_STREAM,
|
||||
ERR_HTTP2_NO_SOCKET_MANIPULATION,
|
||||
ERR_HTTP2_SESSION_ERROR,
|
||||
ERR_HTTP2_SOCKET_UNBOUND,
|
||||
ERR_HTTP2_STREAM_CANCEL,
|
||||
ERR_HTTP2_STREAM_ERROR,
|
||||
ERR_HTTP2_TRAILERS_ALREADY_SENT,
|
||||
|
@ -70,6 +73,8 @@ const kSentTrailers = Symbol("sent-trailers");
|
|||
const kState = Symbol("state");
|
||||
const kType = Symbol("type");
|
||||
const kTimeout = Symbol("timeout");
|
||||
const kSocket = Symbol("socket");
|
||||
const kProxySocket = Symbol("proxySocket");
|
||||
|
||||
const kDenoResponse = Symbol("kDenoResponse");
|
||||
const kDenoRid = Symbol("kDenoRid");
|
||||
|
@ -100,11 +105,76 @@ function debugHttp2(...args) {
|
|||
}
|
||||
}
|
||||
|
||||
export class Http2Session extends EventEmitter {
|
||||
constructor(type, _options /* socket */) {
|
||||
super();
|
||||
const proxySocketHandler = {
|
||||
get(session, prop) {
|
||||
switch (prop) {
|
||||
case "setTimeout":
|
||||
case "ref":
|
||||
case "unref":
|
||||
return FunctionPrototypeBind(session[prop], session);
|
||||
case "destroy":
|
||||
case "emit":
|
||||
case "end":
|
||||
case "pause":
|
||||
case "read":
|
||||
case "resume":
|
||||
case "write":
|
||||
case "setEncoding":
|
||||
case "setKeepAlive":
|
||||
case "setNoDelay":
|
||||
throw new ERR_HTTP2_NO_SOCKET_MANIPULATION();
|
||||
default: {
|
||||
const socket = session[kSocket];
|
||||
if (socket === undefined) {
|
||||
throw new ERR_HTTP2_SOCKET_UNBOUND();
|
||||
}
|
||||
const value = socket[prop];
|
||||
return typeof value === "function"
|
||||
? FunctionPrototypeBind(value, socket)
|
||||
: value;
|
||||
}
|
||||
}
|
||||
},
|
||||
getPrototypeOf(session) {
|
||||
const socket = session[kSocket];
|
||||
if (socket === undefined) {
|
||||
throw new ERR_HTTP2_SOCKET_UNBOUND();
|
||||
}
|
||||
return ReflectGetPrototypeOf(socket);
|
||||
},
|
||||
set(session, prop, value) {
|
||||
switch (prop) {
|
||||
case "setTimeout":
|
||||
case "ref":
|
||||
case "unref":
|
||||
session[prop] = value;
|
||||
return true;
|
||||
case "destroy":
|
||||
case "emit":
|
||||
case "end":
|
||||
case "pause":
|
||||
case "read":
|
||||
case "resume":
|
||||
case "write":
|
||||
case "setEncoding":
|
||||
case "setKeepAlive":
|
||||
case "setNoDelay":
|
||||
throw new ERR_HTTP2_NO_SOCKET_MANIPULATION();
|
||||
default: {
|
||||
const socket = session[kSocket];
|
||||
if (socket === undefined) {
|
||||
throw new ERR_HTTP2_SOCKET_UNBOUND();
|
||||
}
|
||||
socket[prop] = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// TODO(bartlomieju): Handle sockets here
|
||||
export class Http2Session extends EventEmitter {
|
||||
constructor(type, _options, socket) {
|
||||
super();
|
||||
|
||||
this[kState] = {
|
||||
destroyCode: constants.NGHTTP2_NO_ERROR,
|
||||
|
@ -121,12 +191,11 @@ export class Http2Session extends EventEmitter {
|
|||
this[kEncrypted] = undefined;
|
||||
this[kAlpnProtocol] = undefined;
|
||||
this[kType] = type;
|
||||
this[kProxySocket] = null;
|
||||
this[kSocket] = socket;
|
||||
this[kTimeout] = null;
|
||||
// this[kProxySocket] = null;
|
||||
// this[kSocket] = socket;
|
||||
// this[kHandle] = undefined;
|
||||
|
||||
// TODO(bartlomieju): connecting via socket
|
||||
debugHttp2(type, "created");
|
||||
}
|
||||
|
||||
get encrypted(): boolean {
|
||||
|
@ -178,9 +247,12 @@ export class Http2Session extends EventEmitter {
|
|||
return false;
|
||||
}
|
||||
|
||||
get socket(): Socket /*| TlsSocket*/ {
|
||||
warnNotImplemented("Http2Session.socket");
|
||||
return {};
|
||||
get socket(): Socket {
|
||||
const proxySocket = this[kProxySocket];
|
||||
if (proxySocket === null) {
|
||||
return this[kProxySocket] = new Proxy(this, proxySocketHandler);
|
||||
}
|
||||
return proxySocket;
|
||||
}
|
||||
|
||||
get type(): number {
|
||||
|
@ -246,7 +318,7 @@ export class Http2Session extends EventEmitter {
|
|||
if (this.closed || this.destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
debugHttp2(this, "marking session closed");
|
||||
this[kState].flags |= SESSION_FLAGS_CLOSED;
|
||||
if (typeof callback === "function") {
|
||||
this.once("close", callback);
|
||||
|
@ -330,7 +402,8 @@ function closeSession(session: Http2Session, code?: number, error?: Error) {
|
|||
|
||||
export class ServerHttp2Session extends Http2Session {
|
||||
constructor() {
|
||||
super(constants.NGHTTP2_SESSION_SERVER, {});
|
||||
// TODO(satyarohith): pass socket instead of undefined
|
||||
super(constants.NGHTTP2_SESSION_SERVER, {}, undefined);
|
||||
}
|
||||
|
||||
altsvc(
|
||||
|
@ -368,7 +441,7 @@ export class ClientHttp2Session extends Http2Session {
|
|||
url: string,
|
||||
options: Record<string, unknown>,
|
||||
) {
|
||||
super(constants.NGHTTP2_SESSION_CLIENT, options);
|
||||
super(constants.NGHTTP2_SESSION_CLIENT, options, socket);
|
||||
this[kPendingRequestCalls] = null;
|
||||
this[kDenoClientRid] = undefined;
|
||||
this[kDenoConnRid] = undefined;
|
||||
|
|
Loading…
Reference in a new issue