1- import { defineEventHandler , H3Event , proxyRequest } from "h3" ;
2-
1+ import {
2+ defineEventHandler ,
3+ H3Event ,
4+ RequestHeaders ,
5+ getMethod ,
6+ getRequestHeaders ,
7+ sendProxy as _sendProxy ,
8+ } from "h3" ;
39/**
410 * Beware
511 * Using the SSR, cookies are transmitted to the proxy BUT
@@ -25,6 +31,83 @@ import { defineEventHandler, H3Event, proxyRequest } from "h3";
2531
2632import logger from "~/utils/logger" ;
2733
34+ process . env . NODE_TLS_REJECT_UNAUTHORIZED = "0" ;
35+
36+ /**
37+ * This code override proxyRequest from h3
38+ */
39+
40+ /**
41+ * start - this code is not exported from h3
42+ */
43+ export interface ProxyOptions {
44+ headers ?: RequestHeaders | HeadersInit ;
45+ fetchOptions ?: RequestInit ;
46+ fetch ?: typeof fetch ;
47+ sendStream ?: boolean ;
48+ cookieDomainRewrite ?: string | Record < string , string > ;
49+ cookiePathRewrite ?: string | Record < string , string > ;
50+ onResponse ?: ( event : H3Event , response : Response ) => void ;
51+ }
52+
53+ const ignoredHeaders = new Set ( [
54+ 'transfer-encoding' ,
55+ 'connection' ,
56+ 'keep-alive' ,
57+ 'upgrade' ,
58+ 'expect' ,
59+ 'host' ,
60+ ] ) ;
61+
62+ export function getProxyRequestHeaders ( event : H3Event ) {
63+ const headers = Object . create ( null ) ;
64+ const reqHeaders = getRequestHeaders ( event ) ;
65+ // eslint-disable-next-line no-restricted-syntax
66+ for ( const name in reqHeaders ) {
67+ if ( ! ignoredHeaders . has ( name ) ) {
68+ headers [ name ] = reqHeaders [ name ] ;
69+ }
70+ }
71+ return headers ;
72+ }
73+
74+ /**
75+ * end - this code is not exported from h3
76+ */
77+
78+ /**
79+ * This code override h3 default behavior:
80+ * Instead of reading the body we send the body as the stream, allowing better memory usage + prevent utf8 decoding
81+ * */
82+ async function proxyRequest (
83+ event : H3Event ,
84+ target : string ,
85+ opts : ProxyOptions = { } ,
86+ ) {
87+ const method = getMethod ( event ) ;
88+
89+ // Headers
90+ const headers = getProxyRequestHeaders ( event ) ;
91+ if ( opts . fetchOptions ?. headers ) {
92+ Object . assign ( headers , opts . fetchOptions . headers ) ;
93+ }
94+ if ( opts . headers ) {
95+ Object . assign ( headers , opts . headers ) ;
96+ }
97+ return _sendProxy ( event , target , {
98+ ...opts ,
99+ fetchOptions : {
100+ headers,
101+ method,
102+ body : method !== "GET" && method !== "HEAD" ? event . node . req : undefined ,
103+ ...opts . fetchOptions ,
104+ } as RequestInit ,
105+ } ) ;
106+ }
107+
108+ /**
109+ * Here we use the proxy as a default request
110+ */
28111export default defineEventHandler ( async ( event : H3Event ) => {
29112 const { API_URL } = useRuntimeConfig ( ) ;
30113 const target = new URL ( event . req . url as string , API_URL ) ;
@@ -33,6 +116,7 @@ export default defineEventHandler(async (event: H3Event) => {
33116 headers : {
34117 host : target . host ,
35118 } ,
119+ sendStream : true ,
36120 fetchOptions : {
37121 redirect : "manual" ,
38122 } ,
0 commit comments