@@ -4,12 +4,17 @@ extern crate clap;
4
4
5
5
use bytes:: Bytes ;
6
6
use clap:: Parser ;
7
+ use http_body_util:: combinators:: BoxBody ;
7
8
use http_body_util:: Full ;
8
9
use hyper:: body:: Incoming ;
9
10
use hyper:: server:: conn:: http1;
10
11
use hyper_util:: rt:: { tokio:: TokioIo , tokio:: TokioTimer } ;
11
12
use josh_proxy:: cli;
12
- use josh_proxy:: { run_git_with_auth, FetchError , MetaConfig , RemoteAuth , RepoConfig , RepoUpdate } ;
13
+ use josh_proxy:: juniper_hyper:: graphql;
14
+ use josh_proxy:: {
15
+ body:: { empty, full} ,
16
+ run_git_with_auth, FetchError , MetaConfig , RemoteAuth , RepoConfig , RepoUpdate ,
17
+ } ;
13
18
use opentelemetry:: global;
14
19
use opentelemetry:: sdk:: propagation:: TraceContextPropagator ;
15
20
use tokio:: pin;
@@ -297,7 +302,7 @@ async fn fetch_upstream(
297
302
async fn static_paths (
298
303
service : & JoshProxyService ,
299
304
path : & str ,
300
- ) -> josh:: JoshResult < Option < Response < Full < Bytes > > > > {
305
+ ) -> josh:: JoshResult < Option < Response < BoxBody < Bytes , hyper :: Error > > > > {
301
306
tracing:: debug!( "static_path {:?}" , path) ;
302
307
if path == "/version" {
303
308
return Ok ( Some ( make_response (
@@ -356,7 +361,7 @@ async fn static_paths(
356
361
async fn repo_update_fn (
357
362
serv : Arc < JoshProxyService > ,
358
363
req : Request < Incoming > ,
359
- ) -> josh:: JoshResult < Response < Full < Bytes > > > {
364
+ ) -> josh:: JoshResult < Response < BoxBody < Bytes , hyper :: Error > > > {
360
365
let body = req. into_body ( ) . collect ( ) . await ?. to_bytes ( ) ;
361
366
362
367
let s = tracing:: span!( tracing:: Level :: TRACE , "repo update worker" ) ;
@@ -378,10 +383,10 @@ async fn repo_update_fn(
378
383
Ok ( match result {
379
384
Ok ( stderr) => Response :: builder ( )
380
385
. status ( hyper:: StatusCode :: OK )
381
- . body ( Full :: new ( Bytes :: from ( stderr) ) ) ,
386
+ . body ( full ( stderr) ) ,
382
387
Err ( josh:: JoshError ( stderr) ) => Response :: builder ( )
383
388
. status ( hyper:: StatusCode :: INTERNAL_SERVER_ERROR )
384
- . body ( Full :: new ( Bytes :: from ( stderr) ) ) ,
389
+ . body ( full ( stderr) ) ,
385
390
} ?)
386
391
}
387
392
@@ -509,19 +514,19 @@ async fn do_filter(
509
514
Ok ( ( ) )
510
515
}
511
516
512
- fn make_response ( body : & str , code : hyper:: StatusCode ) -> Response < Full < Bytes > > {
517
+ fn make_response ( body : & str , code : hyper:: StatusCode ) -> Response < BoxBody < Bytes , hyper :: Error > > {
513
518
let owned_body = body. to_owned ( ) ;
514
519
Response :: builder ( )
515
520
. status ( code)
516
521
. header ( hyper:: header:: CONTENT_TYPE , "text/plain" )
517
- . body ( Full :: new ( Bytes :: from ( owned_body) ) )
522
+ . body ( full ( owned_body) )
518
523
. expect ( "Can't build response" )
519
524
}
520
525
521
526
async fn handle_ui_request (
522
527
req : Request < Incoming > ,
523
528
resource_path : & str ,
524
- ) -> josh:: JoshResult < Response < Full < Bytes > > > {
529
+ ) -> josh:: JoshResult < Response < BoxBody < Bytes , hyper :: Error > > > {
525
530
/*
526
531
// Proxy: can be used for UI development or to serve a different UI
527
532
if let Some(proxy) = &ARGS.static_resource_proxy_target {
@@ -530,7 +535,7 @@ async fn handle_ui_request(
530
535
Ok(response) => Ok(response),
531
536
Err(error) => Ok(Response::builder()
532
537
.status(StatusCode::INTERNAL_SERVER_ERROR)
533
- .body(Full::new(Bytes::from( format!("Proxy error: {:?}", error) )))
538
+ .body(full( format!("Proxy error: {:?}", error)))
534
539
.unwrap()),
535
540
};
536
541
}*/
@@ -553,7 +558,7 @@ async fn handle_ui_request(
553
558
let resolver = hyper_staticfile:: Resolver :: new ( "josh/static" ) ;
554
559
let request = hyper:: http:: Request :: get ( resolve_path) . body ( ( ) ) . unwrap ( ) ;
555
560
let result = resolver. resolve_request ( & request) . await ?;
556
- let response = hyper:: Response :: new ( Full :: new (
561
+ let response = hyper:: Response :: new ( full (
557
562
hyper_staticfile:: ResponseBuilder :: new ( )
558
563
. request ( & req)
559
564
. build ( result) ?
@@ -932,7 +937,7 @@ fn head_ref_or_default(head_ref: &str) -> HeadRef {
932
937
async fn handle_serve_namespace_request (
933
938
serv : Arc < JoshProxyService > ,
934
939
req : Request < Incoming > ,
935
- ) -> josh:: JoshResult < Response < Full < Bytes > > > {
940
+ ) -> josh:: JoshResult < Response < BoxBody < Bytes , hyper :: Error > > > {
936
941
let error_response = |status : StatusCode | Ok ( make_response ( "" , status) ) ;
937
942
938
943
if req. method ( ) != hyper:: Method :: POST {
@@ -1126,7 +1131,7 @@ async fn handle_serve_namespace_request(
1126
1131
async fn call_service (
1127
1132
serv : Arc < JoshProxyService > ,
1128
1133
req_auth : ( josh_proxy:: auth:: Handle , Request < Incoming > ) ,
1129
- ) -> josh:: JoshResult < Response < Full < Bytes > > > {
1134
+ ) -> josh:: JoshResult < Response < BoxBody < Bytes , hyper :: Error > > > {
1130
1135
let ( auth, req) = req_auth;
1131
1136
1132
1137
let path = {
@@ -1194,7 +1199,7 @@ async fn call_service(
1194
1199
return Ok ( Response :: builder ( )
1195
1200
. status ( hyper:: StatusCode :: FOUND )
1196
1201
. header ( "Location" , redirect_path)
1197
- . body ( Full :: new ( Bytes :: new ( ) ) ) ?) ;
1202
+ . body ( empty ( ) ) ?) ;
1198
1203
}
1199
1204
} ;
1200
1205
@@ -1232,7 +1237,7 @@ async fn call_service(
1232
1237
return Ok ( Response :: builder ( )
1233
1238
. status ( hyper:: StatusCode :: TEMPORARY_REDIRECT )
1234
1239
. header ( "Location" , format ! ( "{}{}" , remote_url, parsed_url. pathinfo) )
1235
- . body ( Full :: new ( Bytes :: new ( ) ) ) ?) ;
1240
+ . body ( empty ( ) ) ?) ;
1236
1241
}
1237
1242
1238
1243
if is_repo_blocked ( & meta) {
@@ -1260,7 +1265,7 @@ async fn call_service(
1260
1265
"Basic realm=User Visible Realm" ,
1261
1266
)
1262
1267
. status ( hyper:: StatusCode :: UNAUTHORIZED ) ;
1263
- return Ok ( builder. body ( Full :: new ( Bytes :: new ( ) ) ) ?) ;
1268
+ return Ok ( builder. body ( empty ( ) ) ?) ;
1264
1269
}
1265
1270
1266
1271
if parsed_url. api == "/~/graphql" {
@@ -1269,11 +1274,13 @@ async fn call_service(
1269
1274
1270
1275
if parsed_url. api == "/~/graphiql" {
1271
1276
let addr = format ! ( "/~/graphql{}" , meta. config. repo) ;
1272
- return Ok ( tokio:: task:: spawn_blocking ( move || {
1273
- josh_proxy:: juniper_hyper:: graphiql ( & addr, None )
1274
- } )
1275
- . in_current_span ( )
1276
- . await ??) ;
1277
+ let resp =
1278
+ tokio:: task:: spawn (
1279
+ async move { josh_proxy:: juniper_hyper:: graphiql ( & addr, None ) . await } ,
1280
+ )
1281
+ . in_current_span ( )
1282
+ . await ?;
1283
+ return Ok ( into_body ( resp) ) ;
1277
1284
}
1278
1285
1279
1286
let headref = head_ref_or_default ( & parsed_url. headref ) ;
@@ -1297,11 +1304,11 @@ async fn call_service(
1297
1304
"Basic realm=User Visible Realm" ,
1298
1305
)
1299
1306
. status ( hyper:: StatusCode :: UNAUTHORIZED ) ;
1300
- return Ok ( builder. body ( Full :: new ( Bytes :: new ( ) ) ) ?) ;
1307
+ return Ok ( builder. body ( empty ( ) ) ?) ;
1301
1308
}
1302
1309
Err ( FetchError :: Other ( e) ) => {
1303
1310
let builder = Response :: builder ( ) . status ( hyper:: StatusCode :: INTERNAL_SERVER_ERROR ) ;
1304
- return Ok ( builder. body ( Full :: new ( Bytes :: from ( e. 0 ) ) ) ?) ;
1311
+ return Ok ( builder. body ( full ( e. 0 ) ) ?) ;
1305
1312
}
1306
1313
}
1307
1314
@@ -1382,7 +1389,9 @@ async fn call_service(
1382
1389
// it is executed in all cases.
1383
1390
std:: mem:: drop ( temp_ns) ;
1384
1391
1385
- Ok ( cgires. 0 )
1392
+ Ok ( cgires
1393
+ . 0
1394
+ . map ( |body| body. map_err ( |never| match never { } ) . boxed ( ) ) )
1386
1395
}
1387
1396
1388
1397
async fn serve_query (
@@ -1391,7 +1400,7 @@ async fn serve_query(
1391
1400
upstream_repo : String ,
1392
1401
filter : josh:: filter:: Filter ,
1393
1402
head_ref : & str ,
1394
- ) -> josh:: JoshResult < Response < Full < Bytes > > > {
1403
+ ) -> josh:: JoshResult < Response < BoxBody < Bytes , hyper :: Error > > > {
1395
1404
let tracing_span = tracing:: span!( tracing:: Level :: TRACE , "render worker" ) ;
1396
1405
let head_ref = head_ref. to_string ( ) ;
1397
1406
let res = tokio:: task:: spawn_blocking ( move || -> josh:: JoshResult < _ > {
@@ -1434,15 +1443,15 @@ async fn serve_query(
1434
1443
. get ( "content-type" )
1435
1444
. unwrap_or ( & "text/plain" . to_string ( ) ) ,
1436
1445
)
1437
- . body ( Full :: new ( Bytes :: from ( res) ) ) ?,
1446
+ . body ( full ( res) ) ?,
1438
1447
1439
1448
Ok ( None ) => Response :: builder ( )
1440
1449
. status ( hyper:: StatusCode :: NOT_FOUND )
1441
- . body ( Full :: new ( Bytes :: from ( "File not found" . to_string ( ) ) ) ) ?,
1450
+ . body ( full ( "File not found" . to_string ( ) ) ) ?,
1442
1451
1443
1452
Err ( res) => Response :: builder ( )
1444
1453
. status ( hyper:: StatusCode :: UNPROCESSABLE_ENTITY )
1445
- . body ( Full :: new ( Bytes :: from ( res. to_string ( ) ) ) ) ?,
1454
+ . body ( full ( res. to_string ( ) ) ) ?,
1446
1455
} )
1447
1456
}
1448
1457
@@ -1756,16 +1765,8 @@ async fn serve_graphql(
1756
1765
upstream_repo : String ,
1757
1766
upstream : String ,
1758
1767
auth : josh_proxy:: auth:: Handle ,
1759
- ) -> josh:: JoshResult < Response < Full < Bytes > > > {
1768
+ ) -> josh:: JoshResult < Response < BoxBody < Bytes , hyper :: Error > > > {
1760
1769
let remote_url = upstream. clone ( ) + upstream_repo. as_str ( ) ;
1761
- let parsed = match josh_proxy:: juniper_hyper:: parse_req ( req) . await {
1762
- Ok ( r) => r,
1763
- Err ( resp) => {
1764
- return Ok ( hyper:: Response :: new ( Full :: new ( Bytes :: from (
1765
- resp. collect ( ) . await ?. to_bytes ( ) ,
1766
- ) ) ) )
1767
- }
1768
- } ;
1769
1770
1770
1771
let transaction_mirror = josh:: cache:: Transaction :: open (
1771
1772
& serv. repo_path . join ( "mirror" ) ,
@@ -1796,12 +1797,16 @@ async fn serve_graphql(
1796
1797
// First attempt to serve GraphQL query. If we can serve it
1797
1798
// that means all requested revisions were specified by SHA and we could find
1798
1799
// all of them locally, so no need to fetch.
1799
- let res = parsed. execute ( & root_node, & context) . await ;
1800
+ let res = graphql ( root_node, context, req) . await ;
1801
+
1802
+ if !res. status ( ) . is_success ( ) {
1803
+ return Ok ( res. map ( |body| body. map_err ( |never| match never { } ) . boxed ( ) ) ) ;
1804
+ }
1800
1805
1801
1806
// The "allow_refs" flag will be set by the query handler if we need to do a fetch
1802
1807
// to complete the query.
1803
1808
if !* context. allow_refs . lock ( ) . unwrap ( ) {
1804
- res
1809
+ Ok ( res)
1805
1810
} else {
1806
1811
match fetch_upstream (
1807
1812
serv. clone ( ) ,
@@ -1823,16 +1828,16 @@ async fn serve_graphql(
1823
1828
"Basic realm=User Visible Realm" ,
1824
1829
)
1825
1830
. status ( hyper:: StatusCode :: UNAUTHORIZED ) ;
1826
- return Ok ( builder. body ( Full :: new ( Bytes :: new ( ) ) ) ?) ;
1831
+ return Ok ( builder. body ( empty ( ) ) ?) ;
1827
1832
}
1828
1833
Err ( FetchError :: Other ( e) ) => {
1829
1834
let builder =
1830
1835
Response :: builder ( ) . status ( hyper:: StatusCode :: INTERNAL_SERVER_ERROR ) ;
1831
- return Ok ( builder. body ( Full :: new ( Bytes :: from ( e. 0 ) ) ) ?) ;
1836
+ return Ok ( builder. body ( full ( e. 0 ) ) ?) ;
1832
1837
}
1833
1838
} ;
1834
1839
1835
- parsed . execute ( & root_node, & context) . await
1840
+ Ok ( graphql ( root_node, context, req ) . await )
1836
1841
}
1837
1842
} ;
1838
1843
@@ -1842,8 +1847,8 @@ async fn serve_graphql(
1842
1847
hyper:: StatusCode :: BAD_REQUEST
1843
1848
} ;
1844
1849
1845
- let body = Full :: new ( Bytes :: from ( serde_json:: to_string_pretty ( & res) . unwrap ( ) ) ) ;
1846
- let mut resp = Response :: new ( Full :: new ( Bytes :: new ( ) ) ) ;
1850
+ let body = full ( serde_json:: to_string_pretty ( & res) . unwrap ( ) ) ;
1851
+ let mut resp = Response :: new ( empty ( ) ) ;
1847
1852
* resp. status_mut ( ) = code;
1848
1853
resp. headers_mut ( ) . insert (
1849
1854
hyper:: header:: CONTENT_TYPE ,
0 commit comments