@@ -26,6 +26,7 @@ use std::sync::Arc;
26
26
use std:: rc:: Rc ;
27
27
use std:: marker;
28
28
use std:: mem;
29
+ use std:: net;
29
30
30
31
// tokio
31
32
use futures:: { Stream , Sink , Future , stream} ;
@@ -49,6 +50,11 @@ use http2::stream as streaming;
49
50
use http2:: settings;
50
51
use shared:: server_settings;
51
52
53
+ #[ derive( Debug ) ]
54
+ pub enum ServerError {
55
+ InvalidSettingsConfiguration
56
+ }
57
+
52
58
// TODO this doesn't really belong in the net package.
53
59
pub struct Server < T , R , S >
54
60
where T : server_trait:: OsmiumServer < Request =R , Response =S > ,
@@ -57,38 +63,61 @@ pub struct Server<T, R, S>
57
63
{
58
64
hpack : hpack:: HPack ,
59
65
app : T ,
60
- server_settings : server_settings:: ServerSettings
66
+ security_settings : Option < server_settings:: SecuritySettings > ,
67
+ bind_address : net:: SocketAddr ,
68
+ local_settings : settings:: Settings ,
69
+ local_settings_frame : framing:: settings:: SettingsFrameCompressModel
61
70
}
62
71
63
72
impl < T , R , S > Server < T , R , S >
64
73
where T : ' static + server_trait:: OsmiumServer < Request =R , Response =S > + marker:: Sync + marker:: Send ,
65
74
R : ' static + convert:: From < streaming:: StreamRequest > ,
66
75
S : ' static + convert:: Into < streaming:: StreamResponse >
67
76
{
68
- pub fn new ( app : T , server_settings : server_settings:: ServerSettings ) -> Self {
69
- Server {
77
+ pub fn new ( app : T , server_settings : server_settings:: ServerSettings ) -> Result < Self , ServerError > {
78
+ // Read the settings configuration.
79
+ let mut local_settings = settings:: Settings :: spec_default ( ) ;
80
+ if local_settings. apply_changes ( server_settings. get_http2_settings ( ) ) . is_err ( ) {
81
+ return Err ( ServerError :: InvalidSettingsConfiguration ) ;
82
+ } ;
83
+
84
+ let mut local_settings_frame = framing:: settings:: SettingsFrameCompressModel :: new ( ) ;
85
+ for setting in server_settings. get_http2_settings ( ) {
86
+ local_settings_frame. add_parameter ( setting. get_name ( ) , setting. get_value ( ) ) ;
87
+ }
88
+
89
+ // Build the server bind address.
90
+ let addr = format ! ( "{}:{}" , server_settings. get_host( ) , server_settings. get_port( ) ) . parse ( ) . unwrap ( ) ;
91
+
92
+ Ok ( Server {
70
93
hpack : hpack:: HPack :: new ( ) ,
71
94
app : app,
72
- server_settings : server_settings
73
- }
95
+ security_settings : server_settings. get_security ( ) ,
96
+ bind_address : addr,
97
+ local_settings : local_settings,
98
+ local_settings_frame : local_settings_frame
99
+ } )
74
100
}
75
101
76
102
// The start method consumes self so that it can ensure it can be used on the connection threads.
77
103
// The connection threads take a closure which must have static lifetime. If server startup
78
104
// succeeds, then the a shared pointer to self is returned.
79
- pub fn start_server ( self ) -> Arc < Box < Self > >
105
+ pub fn start_server ( mut self ) -> Arc < Box < Self > >
80
106
{
81
107
// tokio event loop
82
108
let mut event_loop = tokio_core:: reactor:: Core :: new ( ) . unwrap ( ) ;
83
109
let handle = event_loop. handle ( ) ;
84
110
85
111
// create a listener for incoming tcp connections
86
- let addr = format ! ( "{}:{}" , self . server_settings. get_host( ) , self . server_settings. get_port( ) ) . parse ( ) . unwrap ( ) ;
87
- let listener = tokio_core:: net:: TcpListener :: bind ( & addr, & handle) . unwrap ( ) ;
112
+ let listener = tokio_core:: net:: TcpListener :: bind ( & self . bind_address , & handle) . unwrap ( ) ;
88
113
89
114
let thread_pool = Rc :: new ( ThreadPool :: new ( 10 ) ) ;
90
115
91
- let acceptor_factory = acceptor_factory:: AcceptorFactory :: new ( & self . server_settings . get_security ( ) ) ;
116
+ // Create the acceptor factory.
117
+ let mut security = None ;
118
+ mem:: swap ( & mut security, & mut self . security_settings ) ;
119
+ // TODO might not exist.
120
+ let acceptor_factory = acceptor_factory:: AcceptorFactory :: new ( & security. unwrap ( ) ) ;
92
121
93
122
// TODO this should vary depending on the startup type chosen (http/https)
94
123
let handshake: Box < self :: h2handshake:: H2Handshake > = Box :: new ( https:: HttpsH2Handshake :: new ( acceptor_factory) ) ;
@@ -100,13 +129,8 @@ impl<T, R, S> Server<T, R, S>
100
129
debug ! ( "Starting connection on {}" , _remote_addr) ;
101
130
102
131
let inner_handle = handle. clone ( ) ;
103
-
104
- let mut settings_response = framing:: settings:: SettingsFrameCompressModel :: new ( ) ;
105
- settings_response. add_parameter ( settings:: SettingName :: SettingsHeaderTableSize , 65536 ) ;
106
- settings_response. add_parameter ( settings:: SettingName :: SettingsInitialWindowSize , 131072 ) ;
107
- settings_response. add_parameter ( settings:: SettingName :: SettingsMaxFrameSize , 16384 ) ;
108
-
109
- let handshake_future = handshake. attempt_handshake ( socket, Box :: new ( settings_response) )
132
+
133
+ let handshake_future = handshake. attempt_handshake ( socket, Box :: new ( server_instance. local_settings_frame . clone ( ) ) )
110
134
. map_err ( |e| {
111
135
error ! ( "I/O error while attempting connection handshake {}" , e) ;
112
136
} )
@@ -137,6 +161,7 @@ impl<T, R, S> Server<T, R, S>
137
161
let mut connection = connection:: Connection :: new (
138
162
server_instance. hpack . new_send_context ( ) ,
139
163
server_instance. hpack . new_recv_context ( ) ,
164
+ server_instance. local_settings . clone ( ) ,
140
165
temp_frame,
141
166
shutdown_signal:: ShutdownSignaller :: new ( shutdown_read_tx)
142
167
) ;
0 commit comments