Skip to content

Commit fa0848d

Browse files
committed
feat(server): Add hooks for HttpListener and HttpsListener to be started from existing listeners.
This allows Servers to be started on existing TcpListeners.
1 parent 292b4e6 commit fa0848d

File tree

3 files changed

+27
-21
lines changed

3 files changed

+27
-21
lines changed

src/net.rs

+24-13
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,15 @@ impl<'a, N: NetworkListener + 'a> Iterator for NetworkConnections<'a, N> {
5151
pub trait NetworkStream: Read + Write + Any + Send + Typeable {
5252
/// Get the remote address of the underlying connection.
5353
fn peer_addr(&mut self) -> io::Result<SocketAddr>;
54+
5455
/// Set the maximum time to wait for a read to complete.
5556
#[cfg(feature = "timeouts")]
5657
fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()>;
58+
5759
/// Set the maximum time to wait for a write to complete.
5860
#[cfg(feature = "timeouts")]
5961
fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()>;
62+
6063
/// This will be called when Stream should no longer be kept alive.
6164
#[inline]
6265
fn close(&mut self, _how: Shutdown) -> io::Result<()> {
@@ -66,9 +69,8 @@ pub trait NetworkStream: Read + Write + Any + Send + Typeable {
6669
// Unsure about name and implementation...
6770

6871
#[doc(hidden)]
69-
fn set_previous_response_expected_no_content(&mut self, _expected: bool) {
70-
71-
}
72+
fn set_previous_response_expected_no_content(&mut self, _expected: bool) { }
73+
7274
#[doc(hidden)]
7375
fn previous_response_expected_no_content(&self) -> bool {
7476
false
@@ -79,6 +81,7 @@ pub trait NetworkStream: Read + Write + Any + Send + Typeable {
7981
pub trait NetworkConnector {
8082
/// Type of Stream to create
8183
type Stream: Into<Box<NetworkStream + Send>>;
84+
8285
/// Connect to a remote address.
8386
fn connect(&self, host: &str, port: u16, scheme: &str) -> ::Result<Self::Stream>;
8487
}
@@ -215,13 +218,17 @@ impl Clone for HttpListener {
215218
}
216219
}
217220

218-
impl HttpListener {
221+
impl From<TcpListener> for HttpListener {
222+
fn from(listener: TcpListener) -> HttpListener {
223+
HttpListener(listener)
224+
}
225+
}
219226

227+
impl HttpListener {
220228
/// Start listening to an address over HTTP.
221229
pub fn new<To: ToSocketAddrs>(addr: To) -> ::Result<HttpListener> {
222230
Ok(HttpListener(try!(TcpListener::bind(addr))))
223231
}
224-
225232
}
226233

227234
impl NetworkListener for HttpListener {
@@ -382,17 +389,17 @@ impl NetworkConnector for HttpConnector {
382389
/// A closure as a connector used to generate TcpStreams per request
383390
///
384391
/// # Example
385-
///
392+
///
386393
/// Basic example:
387-
///
394+
///
388395
/// ```norun
389396
/// Client::with_connector(|addr: &str, port: u16, scheme: &str| {
390397
/// TcpStream::connect(&(addr, port))
391398
/// });
392399
/// ```
393-
///
400+
///
394401
/// Example using TcpBuilder from the net2 crate if you want to configure your source socket:
395-
///
402+
///
396403
/// ```norun
397404
/// Client::with_connector(|addr: &str, port: u16, scheme: &str| {
398405
/// let b = try!(TcpBuilder::new_v4());
@@ -499,7 +506,6 @@ pub struct HttpsListener<S: Ssl> {
499506
}
500507

501508
impl<S: Ssl> HttpsListener<S> {
502-
503509
/// Start listening to an address over HTTPS.
504510
pub fn new<To: ToSocketAddrs>(addr: To, ssl: S) -> ::Result<HttpsListener<S>> {
505511
HttpListener::new(addr).map(|l| HttpsListener {
@@ -508,6 +514,13 @@ impl<S: Ssl> HttpsListener<S> {
508514
})
509515
}
510516

517+
/// Construct an HttpsListener from a bound `TcpListener`.
518+
pub fn with_listener(listener: HttpListener, ssl: S) -> HttpsListener<S> {
519+
HttpsListener {
520+
listener: listener,
521+
ssl: ssl
522+
}
523+
}
511524
}
512525

513526
impl<S: Ssl + Clone> NetworkListener for HttpsListener<S> {
@@ -576,7 +589,6 @@ mod openssl {
576589
use openssl::x509::X509FileType;
577590
use super::{NetworkStream, HttpStream};
578591

579-
580592
/// An implementation of `Ssl` for OpenSSL.
581593
///
582594
/// # Example
@@ -678,7 +690,6 @@ mod tests {
678690

679691
let mock = stream.downcast::<MockStream>().ok().unwrap();
680692
assert_eq!(mock, Box::new(MockStream::new()));
681-
682693
}
683694

684695
#[test]
@@ -688,6 +699,6 @@ mod tests {
688699

689700
let mock = unsafe { stream.downcast_unchecked::<MockStream>() };
690701
assert_eq!(mock, Box::new(MockStream::new()));
691-
692702
}
693703
}
704+

src/server/listener.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ impl<A: NetworkListener + Send + 'static> ListenerPool<A> {
4242
fn spawn_with<A, F>(supervisor: mpsc::Sender<()>, work: Arc<F>, mut acceptor: A)
4343
where A: NetworkListener + Send + 'static,
4444
F: Fn(<A as NetworkListener>::Stream) + Send + Sync + 'static {
45-
4645
thread::spawn(move || {
4746
let _sentinel = Sentinel::new(supervisor, ());
4847

@@ -77,3 +76,4 @@ impl<T: Send + 'static> Drop for Sentinel<T> {
7776
let _ = self.supervisor.send(self.value.take().unwrap());
7877
}
7978
}
79+

src/server/mod.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,6 @@ impl<L: NetworkListener> Server<L> {
194194
pub fn set_write_timeout(&mut self, dur: Option<Duration>) {
195195
self.timeouts.write = dur;
196196
}
197-
198-
199197
}
200198

201199
impl Server<HttpListener> {
@@ -219,6 +217,7 @@ impl<L: NetworkListener + Send + 'static> Server<L> {
219217
pub fn handle<H: Handler + 'static>(self, handler: H) -> ::Result<Listening> {
220218
self.handle_threads(handler, num_cpus::get() * 5 / 4)
221219
}
220+
222221
/// Binds to a socket and starts handling connections with the provided
223222
/// number of threads.
224223
pub fn handle_threads<H: Handler + 'static>(self, handler: H,
@@ -228,8 +227,7 @@ impl<L: NetworkListener + Send + 'static> Server<L> {
228227
}
229228

230229
fn handle<H, L>(mut server: Server<L>, handler: H, threads: usize) -> ::Result<Listening>
231-
where H: Handler + 'static,
232-
L: NetworkListener + Send + 'static {
230+
where H: Handler + 'static, L: NetworkListener + Send + 'static {
233231
let socket = try!(server.listener.local_addr());
234232

235233
debug!("threads = {:?}", threads);
@@ -251,7 +249,6 @@ struct Worker<H: Handler + 'static> {
251249
}
252250

253251
impl<H: Handler + 'static> Worker<H> {
254-
255252
fn new(handler: H, timeouts: Timeouts) -> Worker<H> {
256253
Worker {
257254
handler: handler,
@@ -299,7 +296,6 @@ impl<H: Handler + 'static> Worker<H> {
299296
self.set_write_timeout(s, self.timeouts.write)
300297
}
301298

302-
303299
#[cfg(not(feature = "timeouts"))]
304300
fn set_write_timeout(&self, _s: &NetworkStream, _timeout: Option<Duration>) -> io::Result<()> {
305301
Ok(())
@@ -339,7 +335,6 @@ impl<H: Handler + 'static> Worker<H> {
339335
}
340336
};
341337

342-
343338
if !self.handle_expect(&req, wrt) {
344339
return false;
345340
}

0 commit comments

Comments
 (0)