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" ;
3
9
/**
4
10
* Beware
5
11
* Using the SSR, cookies are transmitted to the proxy BUT
@@ -25,6 +31,81 @@ import { defineEventHandler, H3Event, proxyRequest } from "h3";
25
31
26
32
import logger from "~/utils/logger" ;
27
33
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
+ */
28
109
export default defineEventHandler ( async ( event : H3Event ) => {
29
110
const { API_URL } = useRuntimeConfig ( ) ;
30
111
const target = new URL ( event . req . url as string , API_URL ) ;
@@ -33,6 +114,7 @@ export default defineEventHandler(async (event: H3Event) => {
33
114
headers : {
34
115
host : target . host ,
35
116
} ,
117
+ sendStream : true ,
36
118
fetchOptions : {
37
119
redirect : "manual" ,
38
120
} ,
0 commit comments