@@ -208,6 +208,7 @@ export default function ({ app, mesh }) {
208
208
209
209
function getRoute ( ep , path ) {
210
210
if ( ep === app . endpoint . id ) {
211
+ if ( ! path . endsWith ( '/' ) ) path += '/'
211
212
var route = localRoutes . find ( r => r . path === path )
212
213
if ( route ) {
213
214
return mesh . discover ( route . service . endpoint . id ) . then (
@@ -237,8 +238,7 @@ export default function ({ app, mesh }) {
237
238
if ( ep === app . endpoint . id ) {
238
239
checkPath ( path )
239
240
checkRoute ( info )
240
- var prefix = path
241
- if ( ! prefix . endsWith ( '/' ) ) prefix += '/'
241
+ if ( ! path . endsWith ( '/' ) ) path += '/'
242
242
var service = {
243
243
name : info . service . name ,
244
244
kind : info . service . kind ,
@@ -248,9 +248,9 @@ export default function ({ app, mesh }) {
248
248
if ( localRoutes [ i ] ?. path === path ) {
249
249
localRoutes [ i ] . service = service
250
250
} else if ( i < 0 ) {
251
- localRoutes . push ( { path, prefix , service } )
251
+ localRoutes . push ( { path, service } )
252
252
} else {
253
- localRoutes . splice ( i , 0 , { path, prefix , service } )
253
+ localRoutes . splice ( i , 0 , { path, service } )
254
254
}
255
255
saveLocalConfig ( )
256
256
return Promise . resolve ( )
@@ -267,6 +267,7 @@ export default function ({ app, mesh }) {
267
267
268
268
function deleteRoute ( ep , path ) {
269
269
if ( ep === app . endpoint . id ) {
270
+ if ( ! path . endsWith ( '/' ) ) path += '/'
270
271
var i = localRoutes . findIndex ( r => r . path === path )
271
272
if ( i >= 0 ) {
272
273
localRoutes . splice ( i , 1 )
@@ -283,9 +284,72 @@ export default function ({ app, mesh }) {
283
284
}
284
285
}
285
286
286
- var forwardService = pipeline ( $ => $ )
287
+ var $route
287
288
288
- var connectService = pipeline ( $ => $ )
289
+ var forwardService = pipeline ( $ => $
290
+ . pipe ( evt => {
291
+ if ( evt instanceof MessageStart ) {
292
+ var url = new URL ( evt . head . path )
293
+ var path = url . pathname
294
+ if ( path . startsWith ( '/svc/' ) ) path = path . substring ( 4 )
295
+ if ( ! path . endsWith ( '/' ) ) path += '/'
296
+ if ( $route = localRoutes . findLast ( r => path . startsWith ( r . path ) ) ) {
297
+ var service = $route . service
298
+ var basepath = `/api/forward/${ service . kind } /${ URL . encodeComponent ( service . name ) } `
299
+ evt . head . path = os . path . join ( basepath , path . substring ( $route . path . length ) ) + url . search
300
+ return ( $route . service . endpoint . id === app . endpoint . id ? 'local' : 'remote' )
301
+ } else {
302
+ return '404'
303
+ }
304
+ }
305
+ } , {
306
+ 'remote' : ( $ => $
307
+ . muxHTTP ( ( ) => $route , { version : 2 } ) . to ( $ => $
308
+ . pipe ( ( ) => mesh . connect ( $route . service . endpoint . id ) )
309
+ )
310
+ ) ,
311
+ 'local' : $ => $ . pipe ( connectService ) ,
312
+ '404' : $ => $ . replaceMessage ( new Message ( { status : 404 } ) ) ,
313
+ } )
314
+ )
315
+
316
+ var matchApiForwardKindName = new http . Match ( '/api/forward/{kind}/{name}' )
317
+ var matchApiForwardKindNameStar = new http . Match ( '/api/forward/{kind}/{name}/*' )
318
+
319
+ var $service
320
+ var $serviceURL
321
+
322
+ var connectService = pipeline ( $ => $
323
+ . pipe ( evt => {
324
+ if ( evt instanceof MessageStart ) {
325
+ var url = new URL ( evt . head . path )
326
+ var params = matchApiForwardKindNameStar ( url . pathname ) || matchApiForwardKindName ( url . pathname )
327
+ if ( params ) {
328
+ var kind = params . kind
329
+ var name = URL . decodeComponent ( params . name )
330
+ evt . head . path = '/' + ( params [ '*' ] || '' ) + url . search
331
+ $service = localServices [ kind ] ?. [ name ]
332
+ }
333
+ if ( ! $service ) return '404'
334
+ return $service . target . address . startsWith ( '/' ) ? 'stdio' : 'http'
335
+ }
336
+ } , {
337
+ 'http' : ( $ => $
338
+ . handleMessageStart ( msg => {
339
+ $serviceURL = new URL ( $service . target . address )
340
+ msg . head . path = os . path . join ( $serviceURL . pathname , msg . head . path )
341
+ msg . head . headers . host = $serviceURL . hostname
342
+ } )
343
+ . muxHTTP ( ( ) => $service ) . to ( $ => $
344
+ . connect ( ( ) => `${ $serviceURL . hostname } :${ $serviceURL . port } ` )
345
+ )
346
+ ) ,
347
+ 'stdio' : ( $ => $
348
+ . replaceMessage ( new Message ( { status : 404 } ) )
349
+ ) ,
350
+ '404' : $ => $ . replaceMessage ( new Message ( { status : 404 } ) ) ,
351
+ } )
352
+ )
289
353
290
354
function getServiceFilePathname ( username , ep , kind , name ) {
291
355
if ( ! username ) {
0 commit comments