1
1
#![ deny( warnings) ]
2
2
extern crate http;
3
3
extern crate hyper;
4
+ extern crate h2;
4
5
#[ macro_use]
5
6
extern crate futures;
6
7
extern crate futures_timer;
@@ -1562,6 +1563,73 @@ fn http1_only() {
1562
1563
} ) ) . unwrap_err ( ) ;
1563
1564
}
1564
1565
1566
+ #[ test]
1567
+ fn http2_service_error_sends_reset_reason ( ) {
1568
+ use std:: error:: Error ;
1569
+ let server = serve ( ) ;
1570
+ let addr_str = format ! ( "http://{}" , server. addr( ) ) ;
1571
+
1572
+ server
1573
+ . reply ( )
1574
+ . error ( h2:: Error :: from ( h2:: Reason :: INADEQUATE_SECURITY ) ) ;
1575
+
1576
+ let mut rt = Runtime :: new ( ) . expect ( "runtime new" ) ;
1577
+
1578
+ let err = rt. block_on ( hyper:: rt:: lazy ( move || {
1579
+ let client = Client :: builder ( )
1580
+ . http2_only ( true )
1581
+ . build_http :: < hyper:: Body > ( ) ;
1582
+ let uri = addr_str. parse ( ) . expect ( "server addr should parse" ) ;
1583
+
1584
+ client. get ( uri)
1585
+ } ) ) . unwrap_err ( ) ;
1586
+
1587
+ let h2_err = err
1588
+ . source ( )
1589
+ . unwrap ( )
1590
+ . downcast_ref :: < h2:: Error > ( )
1591
+ . unwrap ( ) ;
1592
+
1593
+ assert_eq ! ( h2_err. reason( ) , Some ( h2:: Reason :: INADEQUATE_SECURITY ) ) ;
1594
+ }
1595
+
1596
+ #[ test]
1597
+ fn http2_body_user_error_sends_reset_reason ( ) {
1598
+ use std:: error:: Error ;
1599
+ let server = serve ( ) ;
1600
+ let addr_str = format ! ( "http://{}" , server. addr( ) ) ;
1601
+
1602
+ let b = :: futures:: stream:: once :: < String , h2:: Error > ( Err (
1603
+ h2:: Error :: from ( h2:: Reason :: INADEQUATE_SECURITY )
1604
+ ) ) ;
1605
+ let b = hyper:: Body :: wrap_stream ( b) ;
1606
+
1607
+ server
1608
+ . reply ( )
1609
+ . body_stream ( b) ;
1610
+
1611
+ let mut rt = Runtime :: new ( ) . expect ( "runtime new" ) ;
1612
+
1613
+ let err = rt. block_on ( hyper:: rt:: lazy ( move || {
1614
+ let client = Client :: builder ( )
1615
+ . http2_only ( true )
1616
+ . build_http :: < hyper:: Body > ( ) ;
1617
+ let uri = addr_str. parse ( ) . expect ( "server addr should parse" ) ;
1618
+
1619
+ client
1620
+ . get ( uri)
1621
+ . and_then ( |res| res. into_body ( ) . concat2 ( ) )
1622
+ } ) ) . unwrap_err ( ) ;
1623
+
1624
+ let h2_err = err
1625
+ . source ( )
1626
+ . unwrap ( )
1627
+ . downcast_ref :: < h2:: Error > ( )
1628
+ . unwrap ( ) ;
1629
+
1630
+ assert_eq ! ( h2_err. reason( ) , Some ( h2:: Reason :: INADEQUATE_SECURITY ) ) ;
1631
+ }
1632
+
1565
1633
// -------------------------------------------------
1566
1634
// the Server that is used to run all the tests with
1567
1635
// -------------------------------------------------
@@ -1609,6 +1677,8 @@ impl Serve {
1609
1677
}
1610
1678
}
1611
1679
1680
+ type BoxError = Box < :: std:: error:: Error + Send + Sync > ;
1681
+
1612
1682
struct ReplyBuilder < ' a > {
1613
1683
tx : & ' a spmc:: Sender < Reply > ,
1614
1684
}
@@ -1635,10 +1705,13 @@ impl<'a> ReplyBuilder<'a> {
1635
1705
self . tx . send ( Reply :: Body ( body. as_ref ( ) . to_vec ( ) . into ( ) ) ) . unwrap ( ) ;
1636
1706
}
1637
1707
1638
- fn body_stream ( self , body : Body )
1639
- {
1708
+ fn body_stream ( self , body : Body ) {
1640
1709
self . tx . send ( Reply :: Body ( body) ) . unwrap ( ) ;
1641
1710
}
1711
+
1712
+ fn error < E : Into < BoxError > > ( self , err : E ) {
1713
+ self . tx . send ( Reply :: Error ( err. into ( ) ) ) . unwrap ( ) ;
1714
+ }
1642
1715
}
1643
1716
1644
1717
impl < ' a > Drop for ReplyBuilder < ' a > {
@@ -1666,6 +1739,7 @@ enum Reply {
1666
1739
Version ( hyper:: Version ) ,
1667
1740
Header ( HeaderName , HeaderValue ) ,
1668
1741
Body ( hyper:: Body ) ,
1742
+ Error ( BoxError ) ,
1669
1743
End ,
1670
1744
}
1671
1745
@@ -1677,7 +1751,7 @@ enum Msg {
1677
1751
}
1678
1752
1679
1753
impl TestService {
1680
- fn call ( & self , req : Request < Body > ) -> Box < Future < Item =Response < Body > , Error =hyper :: Error > + Send > {
1754
+ fn call ( & self , req : Request < Body > ) -> Box < Future < Item =Response < Body > , Error =BoxError > + Send > {
1681
1755
let tx1 = self . tx . clone ( ) ;
1682
1756
let tx2 = self . tx . clone ( ) ;
1683
1757
let replies = self . reply . clone ( ) ;
@@ -1691,12 +1765,12 @@ impl TestService {
1691
1765
} ;
1692
1766
tx2. send ( msg) . unwrap ( ) ;
1693
1767
Ok ( ( ) )
1694
- } ) . map ( move |_| {
1768
+ } ) . and_then ( move |_| {
1695
1769
TestService :: build_reply ( replies)
1696
1770
} ) )
1697
1771
}
1698
1772
1699
- fn build_reply ( replies : spmc:: Receiver < Reply > ) -> Response < Body > {
1773
+ fn build_reply ( replies : spmc:: Receiver < Reply > ) -> Result < Response < Body > , BoxError > {
1700
1774
let mut res = Response :: new ( Body :: empty ( ) ) ;
1701
1775
while let Ok ( reply) = replies. try_recv ( ) {
1702
1776
match reply {
@@ -1712,10 +1786,11 @@ impl TestService {
1712
1786
Reply :: Body ( body) => {
1713
1787
* res. body_mut ( ) = body;
1714
1788
} ,
1789
+ Reply :: Error ( err) => return Err ( err) ,
1715
1790
Reply :: End => break ,
1716
1791
}
1717
1792
}
1718
- res
1793
+ Ok ( res)
1719
1794
}
1720
1795
}
1721
1796
0 commit comments