@@ -94,6 +94,28 @@ function getApp() {
9494 return c . json ( getContext ( ) ) ;
9595 } ) ;
9696
97+ app . post ( "/json" , async ( c ) => {
98+ try {
99+ const json = await c . req . json ( ) ;
100+ } catch ( e ) {
101+ if ( e instanceof SyntaxError ) {
102+ return c . text ( "Invalid JSON" , 400 ) ;
103+ }
104+ throw e ;
105+ }
106+ return c . json ( getContext ( ) ) ;
107+ } ) ;
108+
109+ app . post ( "/text" , async ( c ) => {
110+ const text = await c . req . text ( ) ;
111+ return c . json ( getContext ( ) ) ;
112+ } ) ;
113+
114+ app . post ( "/form" , async ( c ) => {
115+ const form = await c . req . parseBody ( ) ;
116+ return c . json ( getContext ( ) ) ;
117+ } ) ;
118+
97119 app . on ( [ "GET" ] , [ "/user" , "/user/blocked" ] , ( c ) => {
98120 return c . json ( getContext ( ) ) ;
99121 } ) ;
@@ -140,7 +162,7 @@ t.test("it adds context from request for GET", opts, async (t) => {
140162} ) ;
141163
142164t . test ( "it adds JSON body to context" , opts , async ( t ) => {
143- const response = await getApp ( ) . request ( "/" , {
165+ const response = await getApp ( ) . request ( "/json " , {
144166 method : "POST" ,
145167 headers : {
146168 "content-type" : "application/json" ,
@@ -153,12 +175,12 @@ t.test("it adds JSON body to context", opts, async (t) => {
153175 method : "POST" ,
154176 body : { title : "test" } ,
155177 source : "hono" ,
156- route : "/" ,
178+ route : "/json " ,
157179 } ) ;
158180} ) ;
159181
160182t . test ( "it adds form body to context" , opts , async ( t ) => {
161- const response = await getApp ( ) . request ( "/" , {
183+ const response = await getApp ( ) . request ( "/form " , {
162184 method : "POST" ,
163185 headers : {
164186 "content-type" : "application/x-www-form-urlencoded" ,
@@ -171,12 +193,12 @@ t.test("it adds form body to context", opts, async (t) => {
171193 method : "POST" ,
172194 body : { title : "test" } ,
173195 source : "hono" ,
174- route : "/" ,
196+ route : "/form " ,
175197 } ) ;
176198} ) ;
177199
178200t . test ( "it adds text body to context" , opts , async ( t ) => {
179- const response = await getApp ( ) . request ( "/" , {
201+ const response = await getApp ( ) . request ( "/text " , {
180202 method : "POST" ,
181203 headers : {
182204 "content-type" : "text/plain" ,
@@ -189,12 +211,12 @@ t.test("it adds text body to context", opts, async (t) => {
189211 method : "POST" ,
190212 body : "test" ,
191213 source : "hono" ,
192- route : "/" ,
214+ route : "/text " ,
193215 } ) ;
194216} ) ;
195217
196218t . test ( "it adds xml body to context" , opts , async ( t ) => {
197- const response = await getApp ( ) . request ( "/" , {
219+ const response = await getApp ( ) . request ( "/text " , {
198220 method : "POST" ,
199221 headers : {
200222 "content-type" : "application/xml" ,
@@ -207,7 +229,7 @@ t.test("it adds xml body to context", opts, async (t) => {
207229 method : "POST" ,
208230 body : "<test>test</test>" ,
209231 source : "hono" ,
210- route : "/" ,
232+ route : "/text " ,
211233 } ) ;
212234} ) ;
213235
@@ -379,3 +401,108 @@ t.test("The hono async context still works", opts, async (t) => {
379401 const body = await response . text ( ) ;
380402 t . equal ( body , "test-value" ) ;
381403} ) ;
404+
405+ t . test ( "Proxy request" , opts , async ( t ) => {
406+ const { Hono } = require ( "hono" ) as typeof import ( "hono" ) ;
407+ const { serve } =
408+ require ( "@hono/node-server" ) as typeof import ( "@hono/node-server" ) ;
409+
410+ const app = new Hono ( ) ;
411+
412+ app . on ( [ "GET" , "POST" ] , "/proxy" , async ( c ) => {
413+ const response = await globalThis . fetch (
414+ new Request ( "http://127.0.0.1:8768/body" , {
415+ method : c . req . method ,
416+ headers : c . req . raw . headers ,
417+ body : c . req . raw . body ,
418+ // @ts -expect-error wrong types
419+ duplex : "half" ,
420+ redirect : "manual" ,
421+ } )
422+ ) ;
423+ // clone the response to return a response with modifiable headers
424+ return new Response ( response . body , response ) ;
425+ } ) ;
426+
427+ app . post ( "/body" , async ( c ) => {
428+ return await c . req . json ( ) ;
429+ } ) ;
430+
431+ const server = serve ( {
432+ fetch : app . fetch ,
433+ port : 8767 ,
434+ hostname : "127.0.0.1" ,
435+ } ) ;
436+
437+ const app2 = new Hono ( ) ;
438+ app2 . all ( "/*" , async ( c ) => {
439+ return c . text ( await c . req . text ( ) ) ;
440+ } ) ;
441+
442+ const server2 = serve ( {
443+ fetch : app2 . fetch ,
444+ port : 8768 ,
445+ hostname : "127.0.0.1" ,
446+ } ) ;
447+
448+ const response = await fetch . fetch ( {
449+ url : new URL ( "http://127.0.0.1:8767/proxy" ) ,
450+ method : "POST" ,
451+ headers : {
452+ "Content-Type" : "application/json" ,
453+ } ,
454+ body : JSON . stringify ( { a : 1 } ) ,
455+ } ) ;
456+ t . equal ( response . statusCode , 200 ) ;
457+ t . equal ( response . body , JSON . stringify ( { a : 1 } ) ) ;
458+
459+ // Cleanup servers
460+ server . close ( ) ;
461+ server2 . close ( ) ;
462+ } ) ;
463+
464+ t . test ( "Body parsing in middleware" , opts , async ( t ) => {
465+ const { Hono } = require ( "hono" ) as typeof import ( "hono" ) ;
466+
467+ const app = new Hono < { Variables : { body : any } } > ( ) ;
468+
469+ app . use ( async ( c , next ) => {
470+ c . set ( "body" , await c . req . json ( ) ) ;
471+ return next ( ) ;
472+ } ) ;
473+
474+ app . post ( "/" , async ( c ) => {
475+ return c . json ( getContext ( ) ) ;
476+ } ) ;
477+
478+ const response = await app . request ( "/" , {
479+ method : "POST" ,
480+ headers : {
481+ "Content-Type" : "application/json" ,
482+ } ,
483+ body : JSON . stringify ( { x : 42 } ) ,
484+ } ) ;
485+
486+ const body = await response . json ( ) ;
487+ t . match ( body , {
488+ method : "POST" ,
489+ body : { x : 42 } ,
490+ source : "hono" ,
491+ route : "/" ,
492+ } ) ;
493+ } ) ;
494+
495+ t . test ( "invalid json body" , opts , async ( t ) => {
496+ const app = getApp ( ) ;
497+
498+ const response = await app . request ( "/json" , {
499+ method : "POST" ,
500+ headers : {
501+ "Content-Type" : "application/json" ,
502+ } ,
503+ body : "invalid" ,
504+ } ) ;
505+
506+ t . same ( response . status , 400 ) ;
507+ t . same ( await response . text ( ) , "Invalid JSON" ) ;
508+ } ) ;
0 commit comments