@@ -17,6 +17,7 @@ use std::sync::Arc;
17
17
use bytes:: Bytes ;
18
18
use futures:: { Async , Future , Poll , Stream } ;
19
19
use futures:: future:: { Either , Executor } ;
20
+ use h2;
20
21
use tokio_io:: { AsyncRead , AsyncWrite } ;
21
22
#[ cfg( feature = "runtime" ) ] use tokio_reactor:: Handle ;
22
23
@@ -46,6 +47,7 @@ pub struct Http<E = Exec> {
46
47
exec : E ,
47
48
h1_half_close : bool ,
48
49
h1_writev : bool ,
50
+ h2_builder : h2:: server:: Builder ,
49
51
mode : ConnectionMode ,
50
52
keep_alive : bool ,
51
53
max_buf_size : Option < usize > ,
@@ -120,14 +122,14 @@ where
120
122
121
123
#[ derive( Clone , Debug ) ]
122
124
enum Fallback < E > {
123
- ToHttp2 ( E ) ,
125
+ ToHttp2 ( h2 :: server :: Builder , E ) ,
124
126
Http1Only ,
125
127
}
126
128
127
129
impl < E > Fallback < E > {
128
130
fn to_h2 ( & self ) -> bool {
129
131
match * self {
130
- Fallback :: ToHttp2 ( _ ) => true ,
132
+ Fallback :: ToHttp2 ( .. ) => true ,
131
133
Fallback :: Http1Only => false ,
132
134
}
133
135
}
@@ -165,6 +167,7 @@ impl Http {
165
167
exec : Exec :: Default ,
166
168
h1_half_close : true ,
167
169
h1_writev : true ,
170
+ h2_builder : h2:: server:: Builder :: default ( ) ,
168
171
mode : ConnectionMode :: Fallback ,
169
172
keep_alive : true ,
170
173
max_buf_size : None ,
@@ -236,6 +239,19 @@ impl<E> Http<E> {
236
239
self
237
240
}
238
241
242
+ /// Sets the [`SETTINGS_MAX_CONCURRENT_STREAMS`][spec] option for HTTP2
243
+ /// connections.
244
+ ///
245
+ /// Default is no limit (`None`).
246
+ ///
247
+ /// [spec]: https://http2.github.io/http2-spec/#SETTINGS_MAX_CONCURRENT_STREAMS
248
+ pub fn http2_max_concurrent_streams ( & mut self , max : impl Into < Option < u32 > > ) -> & mut Self {
249
+ if let Some ( max) = max. into ( ) {
250
+ self . h2_builder . max_concurrent_streams ( max) ;
251
+ }
252
+ self
253
+ }
254
+
239
255
/// Enables or disables HTTP keep-alive.
240
256
///
241
257
/// Default is true.
@@ -278,6 +294,7 @@ impl<E> Http<E> {
278
294
exec,
279
295
h1_half_close : self . h1_half_close ,
280
296
h1_writev : self . h1_writev ,
297
+ h2_builder : self . h2_builder ,
281
298
mode : self . mode ,
282
299
keep_alive : self . keep_alive ,
283
300
max_buf_size : self . max_buf_size ,
@@ -350,15 +367,15 @@ impl<E> Http<E> {
350
367
}
351
368
ConnectionMode :: H2Only => {
352
369
let rewind_io = Rewind :: new ( io) ;
353
- let h2 = proto:: h2:: Server :: new ( rewind_io, service, self . exec . clone ( ) ) ;
370
+ let h2 = proto:: h2:: Server :: new ( rewind_io, service, & self . h2_builder , self . exec . clone ( ) ) ;
354
371
Either :: B ( h2)
355
372
}
356
373
} ;
357
374
358
375
Connection {
359
376
conn : Some ( either) ,
360
377
fallback : if self . mode == ConnectionMode :: Fallback {
361
- Fallback :: ToHttp2 ( self . exec . clone ( ) )
378
+ Fallback :: ToHttp2 ( self . h2_builder . clone ( ) , self . exec . clone ( ) )
362
379
} else {
363
380
Fallback :: Http1Only
364
381
} ,
@@ -538,11 +555,16 @@ where
538
555
} ;
539
556
let mut rewind_io = Rewind :: new ( io) ;
540
557
rewind_io. rewind ( read_buf) ;
541
- let exec = match self . fallback {
542
- Fallback :: ToHttp2 ( ref exec) => exec . clone ( ) ,
558
+ let ( builder , exec) = match self . fallback {
559
+ Fallback :: ToHttp2 ( ref builder , ref exec) => ( builder , exec ) ,
543
560
Fallback :: Http1Only => unreachable ! ( "upgrade_h2 with Fallback::Http1Only" ) ,
544
561
} ;
545
- let h2 = proto:: h2:: Server :: new ( rewind_io, dispatch. into_service ( ) , exec) ;
562
+ let h2 = proto:: h2:: Server :: new (
563
+ rewind_io,
564
+ dispatch. into_service ( ) ,
565
+ builder,
566
+ exec. clone ( ) ,
567
+ ) ;
546
568
547
569
debug_assert ! ( self . conn. is_none( ) ) ;
548
570
self . conn = Some ( Either :: B ( h2) ) ;
0 commit comments