@gjsify/http2 0.24.2 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import{__esmMin as e,__exportAll as t}from"./_virtual/_rolldown/runtime.js";import n from"gi://GLib?version=2.0";import r from"gi://Gio?version=2.0";import{hasNativeHttp2 as i,loadNativeHttp2 as a}from"@gjsify/http2-native";var o=t({Http2NativeClientDispatcher:()=>Http2NativeClientDispatcher});function makeBodyIterator(e){return{[Symbol.asyncIterator](){return{next(){return e.bodyBuffer.length>0?Promise.resolve({value:e.bodyBuffer.shift(),done:!1}):e.bodyClosed?Promise.resolve({value:void 0,done:!0}):new Promise(t=>{e.bodyResolvers.push(t)})}}}}}function headersRecordToArrays(e){let t=[],n=[];for(let[r,i]of Object.entries(e))if(Array.isArray(i))for(let e of i)t.push(r),n.push(String(e));else t.push(r),n.push(String(i));return{names:t,values:n}}var s,Http2NativeClientDispatcher,c=e(()=>{s=16*1024,Http2NativeClientDispatcher=class{_bridge=null;_connection=null;_inSource=null;_streams=new Map;_closed=!1;_callbacks;_connectError=null;constructor(e={}){this._callbacks=e}static available(){return i()}connect(e,t){if(!i())throw Error(`@gjsify/http2-native prebuild not loadable — native client unavailable`);let o=a();if(!o)throw Error(`@gjsify/http2-native load failed`);let c=o.SessionBridge.new_client();if(!c)throw Error(`SessionBridge.new_client() returned null`);let l=new r.SocketClient,u;try{u=l.connect_to_host(e,t,null)}catch(e){throw this._connectError=e instanceof Error?e:Error(String(e)),c.close(),this._connectError}u.get_socket().set_blocking(!1),this._bridge=c,this._connection=u,c.connect(`headers-received`,(e,t,n,r)=>{this._onHeaders(t,n,r)}),c.connect(`data-received`,(e,t,n,r)=>{this._onData(t,n,r)}),c.connect(`stream-closed`,(e,t,n)=>{this._onStreamClosed(t)}),c.connect(`frame-send-ready`,()=>{this._flushOutput()}),c.connect(`goaway-received`,(e,t,n)=>{this._callbacks.onGoaway&&this._callbacks.onGoaway(t,n),this._close()}),c.connect(`push-promise-received`,(e,t,n,r)=>{this._onPushPromise(t,n,r)}),this._flushOutput();let d=u.get_input_stream().create_source(null),cb=()=>{if(this._closed)return!1;try{let e=u.get_input_stream().read_bytes(s,null);if(e.get_size()===0)return this._close(),!1;c.feed_input(e),c.dispatch_pending(),this._flushOutput()}catch(e){return e instanceof n.Error&&e.matches(r.io_error_quark(),r.IOErrorEnum.WOULD_BLOCK)?!0:(this._close(),!1)}return!0};d.set_callback(cb),d.attach(n.MainContext.default()),this._inSource=d}submitRequest(e,t){if(!this._bridge)throw Error(`Native client session is not connected`);let{names:n,values:r}=headersRecordToArrays(e),i=this._bridge.submit_request(n,r,t);return i?(this._streams.set(i,{endStreamFromPeer:!1,responseHeaders:null,bodyBuffer:[],bodyResolvers:[],bodyClosed:!1}),this._flushOutput(),i):0}writeData(e,t,r){if(!this._bridge)return;let i=n.Bytes.new(new Uint8Array(t.buffer,t.byteOffset,t.byteLength));this._bridge.submit_data(e,i,r),this._flushOutput()}body(e){let t=this._streams.get(e);return t?makeBodyIterator(t):(async function*(){})()}responseHeaders(e){let t=this._streams.get(e);return t?t.responseHeaders:null}close(){this._close()}_close(){if(!this._closed){this._closed=!0;try{this._bridge?.submit_goaway(0,0),this._flushOutput()}catch{}if(this._inSource){try{this._inSource.destroy()}catch{}this._inSource=null}try{this._connection?.close(null)}catch{}this._connection=null;try{this._bridge?.close()}catch{}this._bridge=null;for(let e of this._streams.values())for(e.bodyClosed=!0;e.bodyResolvers.length>0;)e.bodyResolvers.shift()({value:void 0,done:!0});this._callbacks.onClose&&this._callbacks.onClose()}}_flushOutput(){if(this._closed||!this._bridge||!this._connection)return;let e=this._bridge.drain_output();if(e.get_size()===0)return;let t=e.get_data();try{this._connection.get_output_stream().write(t,null)}catch{this._close()}}_onHeaders(e,t,n){let r=t.deep_unpack(),i={};for(let[e,t]of r)if(e in i){let n=i[e];Array.isArray(n)?n.push(t):i[e]=[n,t]}else i[e]=t;let a=this._streams.get(e);if(a&&(a.responseHeaders=i,n&&(a.bodyClosed=!0)),this._callbacks.onResponse){let t=a??this._registerStreamForPush(e);this._callbacks.onResponse({streamId:e,headers:i,endStream:n,body:makeBodyIterator(t)})}}_onData(e,t,n){let r=this._streams.get(e);if(r){if(t.get_size()>0){let e=Buffer.from(t.get_data());r.bodyResolvers.length>0?r.bodyResolvers.shift()({value:e,done:!1}):r.bodyBuffer.push(e)}if(n)for(r.bodyClosed=!0;r.bodyResolvers.length>0;)r.bodyResolvers.shift()({value:void 0,done:!0})}}_onStreamClosed(e){let t=this._streams.get(e);if(t)for(t.bodyClosed=!0;t.bodyResolvers.length>0;)t.bodyResolvers.shift()({value:void 0,done:!0})}_onPushPromise(e,t,n){let r=n.deep_unpack(),i={};for(let[e,t]of r)i[e]=t;this._registerStreamForPush(t),this._callbacks.onPushPromise&&this._callbacks.onPushPromise({parentStreamId:e,promisedStreamId:t,headers:i})}_registerStreamForPush(e){let t=this._streams.get(e);return t||(t={endStreamFromPeer:!1,responseHeaders:null,bodyBuffer:[],bodyResolvers:[],bodyClosed:!1},this._streams.set(e,t)),t}}});c();export{Http2NativeClientDispatcher,c as init_native_client_dispatcher,o as native_client_dispatcher_exports};
1
+ import{__esmMin as e,__exportAll as t}from"./_virtual/_rolldown/runtime.js";import n from"gi://GLib?version=2.0";import r from"gi://Gio?version=2.0";import{hasNativeHttp2 as i,loadNativeHttp2 as a}from"@gjsify/http2-native";var o=t({Http2NativeClientDispatcher:()=>Http2NativeClientDispatcher});function makeBodyIterator(e){return{[Symbol.asyncIterator](){return{next(){return e.bodyBuffer.length>0?Promise.resolve({value:e.bodyBuffer.shift(),done:!1}):e.bodyClosed?Promise.resolve({value:void 0,done:!0}):new Promise(t=>{e.bodyResolvers.push(t)})}}}}}function headersRecordToArrays(e){let t=[],n=[];for(let[r,i]of Object.entries(e))if(Array.isArray(i))for(let e of i)t.push(r),n.push(String(e));else t.push(r),n.push(String(i));return{names:t,values:n}}var s,Http2NativeClientDispatcher,c=e(()=>{s=16*1024,Http2NativeClientDispatcher=class{_bridge=null;_connection=null;_inSource=null;_streams=new Map;_closed=!1;_callbacks;_connectError=null;constructor(e={}){this._callbacks=e}static available(){return i()}connect(e,t){if(!i())throw Error(`@gjsify/http2-native prebuild not loadable — native client unavailable`);let o=a();if(!o)throw Error(`@gjsify/http2-native load failed`);let c=o.SessionBridge.new_client();if(!c)throw Error(`SessionBridge.new_client() returned null`);let l=new r.SocketClient,u;try{u=l.connect_to_host(e,t,null)}catch(e){throw this._connectError=e instanceof Error?e:Error(String(e)),c.close(),this._connectError}u.get_socket().set_blocking(!1),this._bridge=c,this._connection=u,c.connect(`headers-received`,(e,t,n,r)=>{this._onHeaders(t,n,r)}),c.connect(`data-received`,(e,t,n,r)=>{this._onData(t,n,r)}),c.connect(`stream-closed`,(e,t,n)=>{this._onStreamClosed(t)}),c.connect(`frame-send-ready`,()=>{this._flushOutput()}),c.connect(`goaway-received`,(e,t,n)=>{this._callbacks.onGoaway&&this._callbacks.onGoaway(t,n),this._close()}),c.connect(`push-promise-received`,(e,t,n,r)=>{this._onPushPromise(t,n,r)}),this._flushOutput();let d=u.get_input_stream().create_source(null),cb=()=>{if(this._closed)return!1;try{let e=u.get_input_stream().read_bytes(s,null);if(e.get_size()===0)return this._close(),!1;c.feed_input(e),c.dispatch_pending(),this._flushOutput()}catch(e){return e instanceof n.Error&&e.matches(r.io_error_quark(),r.IOErrorEnum.WOULD_BLOCK)?!0:(this._close(),!1)}return!0};d.set_callback(cb),d.attach(n.MainContext.default()),this._inSource=d}submitRequest(e,t){if(!this._bridge)throw Error(`Native client session is not connected`);let{names:n,values:r}=headersRecordToArrays(e),i=this._bridge.submit_request(n,r,t);return i?(this._streams.set(i,{endStreamFromPeer:!1,responseHeaders:null,bodyBuffer:[],bodyResolvers:[],bodyClosed:!1}),this._flushOutput(),i):0}writeData(e,t,r){if(!this._bridge)return;let i=n.Bytes.new(new Uint8Array(t.buffer,t.byteOffset,t.byteLength));this._bridge.submit_data(e,i,r),this._flushOutput()}body(e){let t=this._streams.get(e);return t?makeBodyIterator(t):(async function*(){})()}responseHeaders(e){let t=this._streams.get(e);return t?t.responseHeaders:null}close(){this._close()}_close(){if(!this._closed){if(this._closed=!0,this._bridge?.submit_goaway(0,0),this._bridge&&this._connection)try{let e=this._bridge.drain_output();e.get_size()>0&&this._connection.get_output_stream().write(e.get_data(),null)}catch{}this._inSource&&=(this._inSource.destroy(),null);try{this._connection?.close(null)}catch{}this._connection=null,this._bridge?.close(),this._bridge=null;for(let e of this._streams.values())for(e.bodyClosed=!0;e.bodyResolvers.length>0;)e.bodyResolvers.shift()({value:void 0,done:!0});this._callbacks.onClose&&this._callbacks.onClose()}}_flushOutput(){if(this._closed||!this._bridge||!this._connection)return;let e=this._bridge.drain_output();if(e.get_size()===0)return;let t=e.get_data();try{this._connection.get_output_stream().write(t,null)}catch{this._close()}}_onHeaders(e,t,n){let r=t.deep_unpack(),i={};for(let[e,t]of r)if(e in i){let n=i[e];Array.isArray(n)?n.push(t):i[e]=[n,t]}else i[e]=t;let a=this._streams.get(e);if(a&&(a.responseHeaders=i,n&&(a.bodyClosed=!0)),this._callbacks.onResponse){let t=a??this._registerStreamForPush(e);this._callbacks.onResponse({streamId:e,headers:i,endStream:n,body:makeBodyIterator(t)})}}_onData(e,t,n){let r=this._streams.get(e);if(r){if(t.get_size()>0){let e=Buffer.from(t.get_data());r.bodyResolvers.length>0?r.bodyResolvers.shift()({value:e,done:!1}):r.bodyBuffer.push(e)}if(n)for(r.bodyClosed=!0;r.bodyResolvers.length>0;)r.bodyResolvers.shift()({value:void 0,done:!0})}}_onStreamClosed(e){let t=this._streams.get(e);if(t)for(t.bodyClosed=!0;t.bodyResolvers.length>0;)t.bodyResolvers.shift()({value:void 0,done:!0})}_onPushPromise(e,t,n){let r=n.deep_unpack(),i={};for(let[e,t]of r)i[e]=t;this._registerStreamForPush(t),this._callbacks.onPushPromise&&this._callbacks.onPushPromise({parentStreamId:e,promisedStreamId:t,headers:i})}_registerStreamForPush(e){let t=this._streams.get(e);return t||(t={endStreamFromPeer:!1,responseHeaders:null,bodyBuffer:[],bodyResolvers:[],bodyClosed:!1},this._streams.set(e,t)),t}}});c();export{Http2NativeClientDispatcher,c as init_native_client_dispatcher,o as native_client_dispatcher_exports};
@@ -1 +1 @@
1
- import{__esmMin as e,__exportAll as t}from"./_virtual/_rolldown/runtime.js";import n from"gi://GLib?version=2.0";import r from"gi://Gio?version=2.0";import{hasNativeHttp2 as i,loadNativeHttp2 as a}from"@gjsify/http2-native";var o=t({Http2NativeDispatcher:()=>Http2NativeDispatcher});function bytesAreH2Preface(e){if(e.length<s)return!1;for(let t=0;t<s;t++)if(e[t]!==l[t])return!1;return!0}function headersRecordToArrays(e){let t=[],n=[];for(let[r,i]of Object.entries(e))if(Array.isArray(i))for(let e of i)t.push(r),n.push(String(e));else t.push(r),n.push(String(i));return{names:t,values:n}}var s,c,Http2NativeDispatcher,l,u=e(()=>{s=24,c=16*1024,Http2NativeDispatcher=class{_service=null;_connections=new Set;_listenPort=0;_handler;_prefaceGate;_onNonH2c;constructor(e){this._handler=e.handler,this._prefaceGate=e.prefaceGate??!1,this._onNonH2c=e.onNonH2c??null}static available(){return i()}listen(e){if(!i())throw Error(`@gjsify/http2-native prebuild not loadable — dispatcher unavailable`);this._service=new r.SocketService;let t=e;if(e>0){if(!this._service.add_inet_port(e,null))throw Error(`Failed to bind native HTTP/2 dispatcher on port ${e}`)}else{let e=r.InetAddress.new_from_string(`0.0.0.0`)??r.InetAddress.new_any(r.SocketFamily.IPV4),n=r.InetSocketAddress.new(e,0),[i,a]=this._service.add_address(n,r.SocketType.STREAM,r.SocketProtocol.TCP,null);if(!i)throw Error(`Failed to bind native HTTP/2 dispatcher on ephemeral port`);let o=a;o&&typeof o.get_port==`function`&&(t=o.get_port())}return this._listenPort=t,this._service.connect(`incoming`,(e,t)=>(this._acceptConnection(t),!0)),this._service.start(),t}close(){if(this._service){this._service.stop();try{this._service.close()}catch{}this._service=null}for(let e of this._connections)this._closeConnection(e);this._connections.clear()}_acceptConnection(e){let t=e.get_socket();t.set_blocking(!1);let r=e.get_remote_address(),i=r?r.get_address().to_string():`127.0.0.1`,a=r&&typeof r.get_port==`function`?r.get_port():0;if(this._prefaceGate)try{if(t.condition_check(n.IOCondition.IN)&n.IOCondition.IN){let[n,r]=t.receive(c,null);if(n>=s&&bytesAreH2Preface(r)){this._setupNativeConnection(e,t,r.slice(0,n),i,a);return}this._onNonH2c&&this._onNonH2c(e,r.slice(0,n));return}}catch{}this._setupNativeConnection(e,t,null,i,a)}_setupNativeConnection(e,t,i,o,s){let l=a();if(!l){try{e.close(null)}catch{}return}let u=l.SessionBridge.new_server();if(!u){try{e.close(null)}catch{}return}let d={bridge:u,socket:t,inStream:e.get_input_stream(),outStream:e.get_output_stream(),inSource:null,streams:new Map,pendingWrite:null,closed:!1,remoteAddress:o,remotePort:s};this._connections.add(d),u.connect(`headers-received`,(e,t,n,r)=>{this._onHeaders(d,t,n,r)}),u.connect(`data-received`,(e,t,n,r)=>{this._onData(d,t,n,r)}),u.connect(`stream-closed`,(e,t,n)=>{this._onStreamClosed(d,t,n)}),u.connect(`frame-send-ready`,()=>{this._flushOutput(d)}),u.connect(`goaway-received`,()=>{this._closeConnection(d)}),i&&i.byteLength>0&&(u.feed_input(n.Bytes.new(i)),u.dispatch_pending(),this._flushOutput(d)),this._flushOutput(d);let f=d.inStream.create_source(null),cb=()=>{if(d.closed)return!1;try{let e=d.inStream.read_bytes(c,null);if(e.get_size()===0)return this._closeConnection(d),!1;u.feed_input(e),u.dispatch_pending(),this._flushOutput(d)}catch(e){return e instanceof n.Error&&e.matches(r.io_error_quark(),r.IOErrorEnum.WOULD_BLOCK)?!0:(this._closeConnection(d),!1)}return!0};f.set_callback(cb),f.attach(n.MainContext.default()),d.inSource=f}_flushOutput(e){if(e.closed)return;let t=e.bridge.drain_output();if(t.get_size()===0)return;let n=t.get_data();try{e.outStream.write(n,null)}catch{this._closeConnection(e)}}_onHeaders(e,t,n,r){let i=n.deep_unpack(),a={};for(let[e,t]of i){let n=e.toLowerCase();if(n in a){let e=a[n];Array.isArray(e)?e.push(t):a[n]=[e,t]}else a[n]=t}let o={endStreamFromPeer:r,bodyBuffer:[],bodyResolvers:[],bodyClosed:r,responseSubmitted:!1};e.streams.set(t,o);let s={streamId:t,headers:a,endStream:r,remoteAddress:e.remoteAddress,remotePort:e.remotePort,localPort:this._listenPort,body:this._makeBodyIterator(o),backend:this._makeBackend(e,t)};Promise.resolve().then(()=>{try{this._handler(s)}catch(e){let t=e;console.error(`Http2NativeDispatcher: handler threw:`,t.message??String(e),t.stack??``)}})}_onData(e,t,n,r){let i=e.streams.get(t);if(i){if(n.get_size()>0){let e=Buffer.from(n.get_data());i.bodyResolvers.length>0?i.bodyResolvers.shift()({value:e,done:!1}):i.bodyBuffer.push(e)}if(r)for(i.bodyClosed=!0;i.bodyResolvers.length>0;)i.bodyResolvers.shift()({value:void 0,done:!0})}}_onStreamClosed(e,t,n){let r=e.streams.get(t);if(r)for(r.bodyClosed=!0;r.bodyResolvers.length>0;)r.bodyResolvers.shift()({value:void 0,done:!0});e.streams.delete(t)}_makeBackend(e,t){return{streamId:t,respond:(n,r)=>{this._submitResponse(e,t,n,r)},writeData:(n,r)=>{this._submitData(e,t,n,r)},reset:(n=0)=>{try{e.bridge.submit_rst_stream(t,n)}catch{}this._flushOutput(e)},pushPromise:n=>{let{names:r,values:i}=headersRecordToArrays(n),a=e.bridge.submit_push_promise(t,r,i);return this._flushOutput(e),a?(e.streams.set(a,{endStreamFromPeer:!0,bodyBuffer:[],bodyResolvers:[],bodyClosed:!0,responseSubmitted:!1}),this._makeBackend(e,a)):null}}}_submitResponse(e,t,n,r){let i=e.streams.get(t);if(!i||i.responseSubmitted)return;i.responseSubmitted=!0;let{names:a,values:o}=headersRecordToArrays(n);e.bridge.submit_response(t,a,o,r),this._flushOutput(e)}_submitData(e,t,r,i){if(r.length===0&&!i)return;let a=n.Bytes.new(new Uint8Array(r.buffer,r.byteOffset,r.byteLength));e.bridge.submit_data(t,a,i),this._flushOutput(e)}_makeBodyIterator(e){return{[Symbol.asyncIterator](){return{next(){return e.bodyBuffer.length>0?Promise.resolve({value:e.bodyBuffer.shift(),done:!1}):e.bodyClosed?Promise.resolve({value:void 0,done:!0}):new Promise(t=>{e.bodyResolvers.push(t)})}}}}}_closeConnection(e){if(e.closed)return;e.closed=!0;try{e.bridge.submit_goaway(0,0)}catch{}try{this._flushOutput(e)}catch{}if(e.inSource){try{e.inSource.destroy()}catch{}e.inSource=null}try{e.socket.shutdown(!1,!0)}catch{}for(let t of e.streams.values())for(t.bodyClosed=!0;t.bodyResolvers.length>0;)t.bodyResolvers.shift()({value:void 0,done:!0});let finalClose=()=>{try{e.outStream.close(null)}catch{}try{e.inStream.close(null)}catch{}try{e.socket.close()}catch{}try{e.bridge.close()}catch{}};n.idle_add(n.PRIORITY_DEFAULT,()=>(finalClose(),!1)),this._connections.delete(e)}},l=new Uint8Array([80,82,73,32,42,32,72,84,84,80,47,50,46,48,13,10,13,10,83,77,13,10,13,10])});u();export{Http2NativeDispatcher,u as init_native_dispatcher,o as native_dispatcher_exports};
1
+ import{__esmMin as e,__exportAll as t}from"./_virtual/_rolldown/runtime.js";import n from"gi://GLib?version=2.0";import r from"gi://Gio?version=2.0";import{hasNativeHttp2 as i,loadNativeHttp2 as a}from"@gjsify/http2-native";var o=t({Http2NativeDispatcher:()=>Http2NativeDispatcher});function bytesAreH2Preface(e){if(e.length<s)return!1;for(let t=0;t<s;t++)if(e[t]!==l[t])return!1;return!0}function headersRecordToArrays(e){let t=[],n=[];for(let[r,i]of Object.entries(e))if(Array.isArray(i))for(let e of i)t.push(r),n.push(String(e));else t.push(r),n.push(String(i));return{names:t,values:n}}var s,c,Http2NativeDispatcher,l,u=e(()=>{s=24,c=16*1024,Http2NativeDispatcher=class{_service=null;_connections=new Set;_listenPort=0;_handler;_prefaceGate;_onNonH2c;constructor(e){this._handler=e.handler,this._prefaceGate=e.prefaceGate??!1,this._onNonH2c=e.onNonH2c??null}static available(){return i()}listen(e){if(!i())throw Error(`@gjsify/http2-native prebuild not loadable — dispatcher unavailable`);this._service=new r.SocketService;let t=e;if(e>0){if(!this._service.add_inet_port(e,null))throw Error(`Failed to bind native HTTP/2 dispatcher on port ${e}`)}else{let e=r.InetAddress.new_from_string(`0.0.0.0`)??r.InetAddress.new_any(r.SocketFamily.IPV4),n=r.InetSocketAddress.new(e,0),[i,a]=this._service.add_address(n,r.SocketType.STREAM,r.SocketProtocol.TCP,null);if(!i)throw Error(`Failed to bind native HTTP/2 dispatcher on ephemeral port`);let o=a;o&&typeof o.get_port==`function`&&(t=o.get_port())}return this._listenPort=t,this._service.connect(`incoming`,(e,t)=>(this._acceptConnection(t),!0)),this._service.start(),t}close(){this._service&&=(this._service.stop(),this._service.close(),null);for(let e of this._connections)this._closeConnection(e);this._connections.clear()}_acceptConnection(e){let t=e.get_socket();t.set_blocking(!1);let r=e.get_remote_address(),i=r?r.get_address().to_string():`127.0.0.1`,a=r&&typeof r.get_port==`function`?r.get_port():0;if(this._prefaceGate)try{if(t.condition_check(n.IOCondition.IN)&n.IOCondition.IN){let[n,r]=t.receive(c,null);if(n>=s&&bytesAreH2Preface(r)){this._setupNativeConnection(e,t,r.slice(0,n),i,a);return}this._onNonH2c&&this._onNonH2c(e,r.slice(0,n));return}}catch{}this._setupNativeConnection(e,t,null,i,a)}_setupNativeConnection(e,t,i,o,s){let l=a();if(!l){console.error(`Http2NativeDispatcher: @gjsify/http2-native loaded at listen() but failed here — dropping connection`);try{e.close(null)}catch{}return}let u=l.SessionBridge.new_server();if(!u){console.error(`Http2NativeDispatcher: SessionBridge.new_server() returned null — dropping connection`);try{e.close(null)}catch{}return}let d={bridge:u,socket:t,inStream:e.get_input_stream(),outStream:e.get_output_stream(),inSource:null,streams:new Map,pendingWrite:null,closed:!1,remoteAddress:o,remotePort:s};this._connections.add(d),u.connect(`headers-received`,(e,t,n,r)=>{this._onHeaders(d,t,n,r)}),u.connect(`data-received`,(e,t,n,r)=>{this._onData(d,t,n,r)}),u.connect(`stream-closed`,(e,t,n)=>{this._onStreamClosed(d,t,n)}),u.connect(`frame-send-ready`,()=>{this._flushOutput(d)}),u.connect(`goaway-received`,()=>{this._closeConnection(d)}),i&&i.byteLength>0&&(u.feed_input(n.Bytes.new(i)),u.dispatch_pending(),this._flushOutput(d)),this._flushOutput(d);let f=d.inStream.create_source(null),cb=()=>{if(d.closed)return!1;try{let e=d.inStream.read_bytes(c,null);if(e.get_size()===0)return this._closeConnection(d),!1;u.feed_input(e),u.dispatch_pending(),this._flushOutput(d)}catch(e){return e instanceof n.Error&&e.matches(r.io_error_quark(),r.IOErrorEnum.WOULD_BLOCK)?!0:(this._closeConnection(d),!1)}return!0};f.set_callback(cb),f.attach(n.MainContext.default()),d.inSource=f}_flushOutput(e){if(e.closed)return;let t=e.bridge.drain_output();if(t.get_size()===0)return;let n=t.get_data();try{e.outStream.write(n,null)}catch{this._closeConnection(e)}}_onHeaders(e,t,n,r){let i=n.deep_unpack(),a={};for(let[e,t]of i){let n=e.toLowerCase();if(n in a){let e=a[n];Array.isArray(e)?e.push(t):a[n]=[e,t]}else a[n]=t}let o={endStreamFromPeer:r,bodyBuffer:[],bodyResolvers:[],bodyClosed:r,responseSubmitted:!1};e.streams.set(t,o);let s={streamId:t,headers:a,endStream:r,remoteAddress:e.remoteAddress,remotePort:e.remotePort,localPort:this._listenPort,body:this._makeBodyIterator(o),backend:this._makeBackend(e,t)};Promise.resolve().then(()=>{try{this._handler(s)}catch(e){let t=e;console.error(`Http2NativeDispatcher: handler threw:`,t.message??String(e),t.stack??``)}})}_onData(e,t,n,r){let i=e.streams.get(t);if(i){if(n.get_size()>0){let e=Buffer.from(n.get_data());i.bodyResolvers.length>0?i.bodyResolvers.shift()({value:e,done:!1}):i.bodyBuffer.push(e)}if(r)for(i.bodyClosed=!0;i.bodyResolvers.length>0;)i.bodyResolvers.shift()({value:void 0,done:!0})}}_onStreamClosed(e,t,n){let r=e.streams.get(t);if(r)for(r.bodyClosed=!0;r.bodyResolvers.length>0;)r.bodyResolvers.shift()({value:void 0,done:!0});e.streams.delete(t)}_makeBackend(e,t){return{streamId:t,respond:(n,r)=>{this._submitResponse(e,t,n,r)},writeData:(n,r)=>{this._submitData(e,t,n,r)},reset:(n=0)=>{e.bridge.submit_rst_stream(t,n),this._flushOutput(e)},pushPromise:n=>{let{names:r,values:i}=headersRecordToArrays(n),a=e.bridge.submit_push_promise(t,r,i);return this._flushOutput(e),a?(e.streams.set(a,{endStreamFromPeer:!0,bodyBuffer:[],bodyResolvers:[],bodyClosed:!0,responseSubmitted:!1}),this._makeBackend(e,a)):null}}}_submitResponse(e,t,n,r){let i=e.streams.get(t);if(!i||i.responseSubmitted)return;i.responseSubmitted=!0;let{names:a,values:o}=headersRecordToArrays(n);e.bridge.submit_response(t,a,o,r),this._flushOutput(e)}_submitData(e,t,r,i){if(r.length===0&&!i)return;let a=n.Bytes.new(new Uint8Array(r.buffer,r.byteOffset,r.byteLength));e.bridge.submit_data(t,a,i),this._flushOutput(e)}_makeBodyIterator(e){return{[Symbol.asyncIterator](){return{next(){return e.bodyBuffer.length>0?Promise.resolve({value:e.bodyBuffer.shift(),done:!1}):e.bodyClosed?Promise.resolve({value:void 0,done:!0}):new Promise(t=>{e.bodyResolvers.push(t)})}}}}}_closeConnection(e){if(e.closed)return;e.closed=!0,e.bridge.submit_goaway(0,0);try{let t=e.bridge.drain_output();t.get_size()>0&&e.outStream.write(t.get_data(),null)}catch{}e.inSource&&=(e.inSource.destroy(),null);try{e.socket.shutdown(!1,!0)}catch{}for(let t of e.streams.values())for(t.bodyClosed=!0;t.bodyResolvers.length>0;)t.bodyResolvers.shift()({value:void 0,done:!0});let finalClose=()=>{try{e.outStream.close(null)}catch{}try{e.inStream.close(null)}catch{}try{e.socket.close()}catch{}e.bridge.close()};n.idle_add(n.PRIORITY_DEFAULT,()=>(finalClose(),!1)),this._connections.delete(e)}},l=new Uint8Array([80,82,73,32,42,32,72,84,84,80,47,50,46,48,13,10,13,10,83,77,13,10,13,10])});u();export{Http2NativeDispatcher,u as init_native_dispatcher,o as native_dispatcher_exports};
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";import{constants as e}from"../protocol.js";import{installHeaderMethods as t}from"./response/headers.js";import{installStreamIoMethods as n}from"./response/stream-io.js";import{installRespondWithFileMethods as r}from"./response/respond-with-file.js";import{installPushMethods as i}from"./response/push.js";import{EventEmitter as a}from"node:events";import{Writable as o}from"node:stream";import{Buffer as s}from"node:buffer";var Http2ServerResponse=class extends o{statusCode=200;statusMessage=``;headersSent=!1;finished=!1;sendDate=!0;_soupMsg;_nativeBackend;_headers=new Map;_streaming=!1;_timeoutTimer=null;_stream=null;_detachedBody=null;get stream(){return this._stream}get socket(){return null}get isDetached(){return this._soupMsg===null&&this._nativeBackend===null}get detachedBody(){return this._detachedBody?s.concat(this._detachedBody):null}get isNative(){return this._nativeBackend!==null}get nativeBackend(){return this._nativeBackend}_setStream(e){this._stream=e}_setNativeBackend(e){this._nativeBackend=e}constructor(e,t=null){super(),this._soupMsg=e,this._nativeBackend=t,e===null&&t===null&&(this._detachedBody=[])}},ServerHttp2Stream=class extends a{id;pushAllowed;sentHeaders={};_res;_session;_isPushedStream;_pushedChildren=[];_pushPromiseFrame=null;_pushRequestHeaders=null;get session(){return this._session}get headersSent(){return this._res.headersSent}get closed(){return this._res.writableEnded}get destroyed(){return this._res.destroyed}get pending(){return!1}get state(){return this.closed?e.NGHTTP2_STREAM_STATE_CLOSED:e.NGHTTP2_STREAM_STATE_OPEN}get pushPromiseFrame(){return this._pushPromiseFrame}get pushRequestHeaders(){return this._pushRequestHeaders}get pushedChildren(){return this._pushedChildren}constructor(e,t=null,n={}){super(),this._res=e,this._session=t,this._isPushedStream=n.isPushedStream===!0,this.id=n.streamId??1,this.pushAllowed=!this._isPushedStream&&t?.canPush!==!1,e.on(`finish`,()=>this.emit(`close`)),e.on(`error`,e=>this.emit(`error`,e))}respond(e,t){this._res.respond(e,t)}write(e,t,n){return this._res.write(e,t,n)}end(e,t,n){return this._res.end(e,t,n),this}destroy(e){return this._res.destroy(e),this}close(t,n){n&&this.once(`close`,n);let r=this._res.nativeBackend;if(r)try{r.reset(t??e.NGHTTP2_NO_ERROR)}catch{}this._res.end()}priority(e){}setTimeout(e,t){return this._res.setTimeout(e,t),this}sendTrailers(e){}additionalHeaders(e){}respondWithFD(e,t,n){this._res.respondWithFD(e,t,n)}respondWithFile(e,t,n){this._res.respondWithFile(e,t,n)}};t(Http2ServerResponse.prototype),n(Http2ServerResponse.prototype),r(Http2ServerResponse.prototype),i(Http2ServerResponse.prototype,ServerHttp2Stream.prototype);export{Http2ServerResponse,ServerHttp2Stream};
1
+ import"../_virtual/_rolldown/runtime.js";import{constants as e}from"../protocol.js";import{installHeaderMethods as t}from"./response/headers.js";import{installStreamIoMethods as n}from"./response/stream-io.js";import{installRespondWithFileMethods as r}from"./response/respond-with-file.js";import{installPushMethods as i}from"./response/push.js";import{EventEmitter as a}from"node:events";import{Writable as o}from"node:stream";import{Buffer as s}from"node:buffer";var Http2ServerResponse=class extends o{statusCode=200;statusMessage=``;headersSent=!1;finished=!1;sendDate=!0;_soupMsg;_nativeBackend;_headers=new Map;_streaming=!1;_timeoutTimer=null;_stream=null;_detachedBody=null;get stream(){return this._stream}get socket(){return null}get isDetached(){return this._soupMsg===null&&this._nativeBackend===null}get detachedBody(){return this._detachedBody?s.concat(this._detachedBody):null}get isNative(){return this._nativeBackend!==null}get nativeBackend(){return this._nativeBackend}_setStream(e){this._stream=e}_setNativeBackend(e){this._nativeBackend=e}constructor(e,t=null){super(),this._soupMsg=e,this._nativeBackend=t,e===null&&t===null&&(this._detachedBody=[])}},ServerHttp2Stream=class extends a{id;pushAllowed;sentHeaders={};_res;_session;_isPushedStream;_pushedChildren=[];_pushPromiseFrame=null;_pushRequestHeaders=null;get session(){return this._session}get headersSent(){return this._res.headersSent}get closed(){return this._res.writableEnded}get destroyed(){return this._res.destroyed}get pending(){return!1}get state(){return this.closed?e.NGHTTP2_STREAM_STATE_CLOSED:e.NGHTTP2_STREAM_STATE_OPEN}get pushPromiseFrame(){return this._pushPromiseFrame}get pushRequestHeaders(){return this._pushRequestHeaders}get pushedChildren(){return this._pushedChildren}constructor(e,t=null,n={}){super(),this._res=e,this._session=t,this._isPushedStream=n.isPushedStream===!0,this.id=n.streamId??1,this.pushAllowed=!this._isPushedStream&&t?.canPush!==!1,e.on(`finish`,()=>this.emit(`close`)),e.on(`error`,e=>this.emit(`error`,e))}respond(e,t){this._res.respond(e,t)}write(e,t,n){return this._res.write(e,t,n)}end(e,t,n){return this._res.end(e,t,n),this}destroy(e){return this._res.destroy(e),this}close(t,n){n&&this.once(`close`,n);let r=this._res.nativeBackend;r&&r.reset(t??e.NGHTTP2_NO_ERROR),this._res.end()}priority(e){}setTimeout(e,t){return this._res.setTimeout(e,t),this}sendTrailers(e){}additionalHeaders(e){}respondWithFD(e,t,n){this._res.respondWithFD(e,t,n)}respondWithFile(e,t,n){this._res.respondWithFile(e,t,n)}};t(Http2ServerResponse.prototype),n(Http2ServerResponse.prototype),r(Http2ServerResponse.prototype),i(Http2ServerResponse.prototype,ServerHttp2Stream.prototype);export{Http2ServerResponse,ServerHttp2Stream};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/http2",
3
- "version": "0.24.2",
3
+ "version": "0.26.0",
4
4
  "description": "Node.js http2 module for Gjs",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -33,8 +33,8 @@
33
33
  "http2"
34
34
  ],
35
35
  "devDependencies": {
36
- "@gjsify/cli": "^0.24.2",
37
- "@gjsify/unit": "^0.24.2",
36
+ "@gjsify/cli": "^0.26.0",
37
+ "@gjsify/unit": "^0.26.0",
38
38
  "@types/node": "^25.9.2",
39
39
  "typescript": "^6.0.3"
40
40
  },
@@ -43,9 +43,9 @@
43
43
  "@girs/glib-2.0": "^4.1.0",
44
44
  "@girs/gobject-2.0": "^4.1.0",
45
45
  "@girs/soup-3.0": "^4.1.0",
46
- "@gjsify/events": "^0.24.2",
47
- "@gjsify/http2-native": "^0.24.2",
48
- "@gjsify/utils": "^0.24.2"
46
+ "@gjsify/events": "^0.26.0",
47
+ "@gjsify/http2-native": "^0.26.0",
48
+ "@gjsify/utils": "^0.26.0"
49
49
  },
50
50
  "gjsify": {
51
51
  "runtimes": {