@@ -31,12 +31,16 @@ use std::io::ErrorKind;
31
31
use futures:: { Poll , Future , Async , AsyncSink , Stream , Sink , StartSend } ;
32
32
use tokio:: io:: { AsyncRead , AsyncWrite } ;
33
33
34
- use tungstenite:: handshake:: client:: { ClientHandshake , Response , Request } ;
35
- use tungstenite:: handshake:: server:: { ServerHandshake , Callback , NoCallback } ;
36
- use tungstenite:: handshake:: { HandshakeRole , HandshakeError } ;
37
- use tungstenite:: protocol:: { WebSocket , Message , Role } ;
38
- use tungstenite:: error:: Error as WsError ;
39
- use tungstenite:: server;
34
+ use tungstenite:: {
35
+ error:: Error as WsError ,
36
+ handshake:: {
37
+ HandshakeRole , HandshakeError ,
38
+ client:: { ClientHandshake , Response , Request } ,
39
+ server:: { ServerHandshake , Callback , NoCallback } ,
40
+ } ,
41
+ protocol:: { WebSocket , Message , Role , WebSocketConfig } ,
42
+ server,
43
+ } ;
40
44
41
45
#[ cfg( feature="connect" ) ]
42
46
pub use connect:: { connect_async, client_async_tls} ;
@@ -53,14 +57,31 @@ pub use connect::{connect_async, client_async_tls};
53
57
///
54
58
/// This is typically used for clients who have already established, for
55
59
/// example, a TCP connection to the remote server.
56
- pub fn client_async < ' a , R , S > ( request : R , stream : S ) -> ConnectAsync < S >
60
+ pub fn client_async < ' a , R , S > (
61
+ request : R ,
62
+ stream : S ,
63
+ ) -> ConnectAsync < S >
64
+ where
65
+ R : Into < Request < ' a > > ,
66
+ S : AsyncRead + AsyncWrite
67
+ {
68
+ client_async_with_config ( request, stream, None )
69
+ }
70
+
71
+ /// The same as `client_async()` but the one can specify a websocket configuration.
72
+ /// Please refer to `client_async()` for more details.
73
+ pub fn client_async_with_config < ' a , R , S > (
74
+ request : R ,
75
+ stream : S ,
76
+ config : Option < WebSocketConfig > ,
77
+ ) -> ConnectAsync < S >
57
78
where
58
79
R : Into < Request < ' a > > ,
59
80
S : AsyncRead + AsyncWrite
60
81
{
61
82
ConnectAsync {
62
83
inner : MidHandshake {
63
- inner : Some ( ClientHandshake :: start ( stream, request. into ( ) ) . handshake ( ) )
84
+ inner : Some ( ClientHandshake :: start ( stream, request. into ( ) , config ) . handshake ( ) )
64
85
}
65
86
}
66
87
}
@@ -83,19 +104,45 @@ where
83
104
accept_hdr_async ( stream, NoCallback )
84
105
}
85
106
107
+ /// The same as `accept_async()` but the one can specify a websocket configuration.
108
+ /// Please refer to `accept_async()` for more details.
109
+ pub fn accept_async_with_config < S > (
110
+ stream : S ,
111
+ config : Option < WebSocketConfig > ,
112
+ ) -> AcceptAsync < S , NoCallback >
113
+ where
114
+ S : AsyncRead + AsyncWrite ,
115
+ {
116
+ accept_hdr_async_with_config ( stream, NoCallback , config)
117
+ }
118
+
86
119
/// Accepts a new WebSocket connection with the provided stream.
87
120
///
88
121
/// This function does the same as `accept_async()` but accepts an extra callback
89
122
/// for header processing. The callback receives headers of the incoming
90
123
/// requests and is able to add extra headers to the reply.
91
124
pub fn accept_hdr_async < S , C > ( stream : S , callback : C ) -> AcceptAsync < S , C >
125
+ where
126
+ S : AsyncRead + AsyncWrite ,
127
+ C : Callback ,
128
+ {
129
+ accept_hdr_async_with_config ( stream, callback, None )
130
+ }
131
+
132
+ /// The same as `accept_hdr_async()` but the one can specify a websocket configuration.
133
+ /// Please refer to `accept_hdr_async()` for more details.
134
+ pub fn accept_hdr_async_with_config < S , C > (
135
+ stream : S ,
136
+ callback : C ,
137
+ config : Option < WebSocketConfig > ,
138
+ ) -> AcceptAsync < S , C >
92
139
where
93
140
S : AsyncRead + AsyncWrite ,
94
141
C : Callback ,
95
142
{
96
143
AcceptAsync {
97
144
inner : MidHandshake {
98
- inner : Some ( server:: accept_hdr ( stream, callback) )
145
+ inner : Some ( server:: accept_hdr_with_config ( stream, callback, config ) )
99
146
}
100
147
}
101
148
}
@@ -116,15 +163,24 @@ pub struct WebSocketStream<S> {
116
163
impl < S > WebSocketStream < S > {
117
164
/// Convert a raw socket into a WebSocketStream without performing a
118
165
/// handshake.
119
- pub fn from_raw_socket ( stream : S , role : Role ) -> Self {
120
- let ws = WebSocket :: from_raw_socket ( stream, role) ;
166
+ pub fn from_raw_socket (
167
+ stream : S ,
168
+ role : Role ,
169
+ config : Option < WebSocketConfig > ,
170
+ ) -> Self {
171
+ let ws = WebSocket :: from_raw_socket ( stream, role, config) ;
121
172
WebSocketStream { inner : ws }
122
173
}
123
174
124
175
/// Convert a raw socket into a WebSocketStream without performing a
125
176
/// handshake.
126
- pub fn from_partially_read ( stream : S , part : Vec < u8 > , role : Role ) -> Self {
127
- let ws = WebSocket :: from_partially_read ( stream, part, role) ;
177
+ pub fn from_partially_read (
178
+ stream : S ,
179
+ part : Vec < u8 > ,
180
+ role : Role ,
181
+ config : Option < WebSocketConfig > ,
182
+ ) -> Self {
183
+ let ws = WebSocket :: from_partially_read ( stream, part, role, config) ;
128
184
WebSocketStream { inner : ws }
129
185
}
130
186
}
@@ -143,8 +199,7 @@ impl<T> Sink for WebSocketStream<T> where T: AsyncRead + AsyncWrite {
143
199
type SinkError = WsError ;
144
200
145
201
fn start_send ( & mut self , item : Message ) -> StartSend < Message , WsError > {
146
- try!( self . inner . write_message ( item) . to_async ( ) ) ;
147
- Ok ( AsyncSink :: Ready )
202
+ self . inner . write_message ( item) . to_start_send ( )
148
203
}
149
204
150
205
fn poll_complete ( & mut self ) -> Poll < ( ) , WsError > {
@@ -238,3 +293,24 @@ impl<T> ToAsync for Result<T, WsError> {
238
293
}
239
294
}
240
295
296
+ trait ToStartSend {
297
+ type T ;
298
+ type E ;
299
+ fn to_start_send ( self ) -> StartSend < Self :: T , Self :: E > ;
300
+ }
301
+
302
+ impl ToStartSend for Result < ( ) , WsError > {
303
+ type T = Message ;
304
+ type E = WsError ;
305
+ fn to_start_send ( self ) -> StartSend < Self :: T , Self :: E > {
306
+ match self {
307
+ Ok ( _) => Ok ( AsyncSink :: Ready ) ,
308
+ Err ( error) => match error {
309
+ WsError :: Io ( ref err) if err. kind ( ) == ErrorKind :: WouldBlock => Ok ( AsyncSink :: Ready ) ,
310
+ WsError :: SendQueueFull ( msg) => Ok ( AsyncSink :: NotReady ( msg) ) ,
311
+ err => Err ( err) ,
312
+ }
313
+ }
314
+ }
315
+ }
316
+
0 commit comments