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