Merge branch 'devel'

pull/13/head
Alexey Galakhov 8 years ago
commit 50ff2aaf56
  1. 4
      Cargo.toml
  2. 23
      src/client.rs
  3. 2
      src/error.rs
  4. 13
      src/handshake/client.rs
  5. 5
      src/handshake/headers.rs
  6. 5
      src/handshake/server.rs
  7. 1
      src/lib.rs
  8. 2
      src/protocol/frame/coding.rs
  9. 37
      src/stream.rs
  10. 5
      src/util.rs

@ -7,9 +7,9 @@ authors = ["Alexey Galakhov"]
license = "MIT/Apache-2.0"
readme = "README.md"
homepage = "https://github.com/snapview/tungstenite-rs"
documentation = "https://docs.rs/tungstenite/0.2.3"
documentation = "https://docs.rs/tungstenite/0.2.4"
repository = "https://github.com/snapview/tungstenite-rs"
version = "0.2.3"
version = "0.2.4"
[features]
default = ["tls"]

@ -13,6 +13,7 @@ mod encryption {
pub use native_tls::TlsStream;
pub use stream::Stream as StreamSwitcher;
/// TCP stream switcher (plain/TLS).
pub type AutoStream = StreamSwitcher<TcpStream, TlsStream<TcpStream>>;
use stream::Mode;
@ -41,6 +42,7 @@ mod encryption {
use stream::Mode;
use error::{Error, Result};
/// TLS support is nod compiled in, this is just standard `TcpStream`.
pub type AutoStream = TcpStream;
pub fn wrap_stream(stream: TcpStream, _domain: &str, mode: Mode) -> Result<AutoStream> {
@ -57,7 +59,7 @@ use self::encryption::wrap_stream;
use protocol::WebSocket;
use handshake::HandshakeError;
use handshake::client::{ClientHandshake, Request};
use stream::Mode;
use stream::{NoDelay, Mode};
use error::{Error, Result};
@ -73,11 +75,13 @@ use error::{Error, Result};
/// This function uses `native_tls` to do TLS. If you want to use other TLS libraries,
/// use `client` instead. There is no need to enable the "tls" feature if you don't call
/// `connect` since it's the only function that uses native_tls.
pub fn connect(url: Url) -> Result<WebSocket<AutoStream>> {
let mode = url_mode(&url)?;
let addrs = url.to_socket_addrs()?;
let stream = connect_to_some(addrs, &url, mode)?;
client(url.clone(), stream)
pub fn connect<'t, Req: Into<Request<'t>>>(request: Req) -> Result<WebSocket<AutoStream>> {
let request: Request = request.into();
let mode = url_mode(&request.url)?;
let addrs = request.url.to_socket_addrs()?;
let mut stream = connect_to_some(addrs, &request.url, mode)?;
NoDelay::set_nodelay(&mut stream, true)?;
client(request, stream)
.map_err(|e| match e {
HandshakeError::Failure(f) => f,
HandshakeError::Interrupted(_) => panic!("Bug: blocking handshake not blocked"),
@ -116,9 +120,10 @@ pub fn url_mode(url: &Url) -> Result<Mode> {
/// Use this function if you need a nonblocking handshake support or if you
/// want to use a custom stream like `mio::tcp::TcpStream` or `openssl::ssl::SslStream`.
/// Any stream supporting `Read + Write` will do.
pub fn client<Stream: Read + Write>(url: Url, stream: Stream)
pub fn client<'t, Stream, Req>(request: Req, stream: Stream)
-> StdResult<WebSocket<Stream>, HandshakeError<Stream, ClientHandshake>>
where Stream: Read + Write,
Req: Into<Request<'t>>,
{
let request = Request { url: url, extra_headers: None };
ClientHandshake::start(stream, request).handshake()
ClientHandshake::start(stream, request.into()).handshake()
}

@ -15,9 +15,11 @@ use protocol::frame::CloseFrame;
#[cfg(feature="tls")]
pub mod tls {
//! TLS error wrapper module, feature-gated.
pub use native_tls::Error;
}
/// Result type of all Tungstenite library calls.
pub type Result<T> = result::Result<T, Error>;
/// Possible WebSocket errors

@ -1,3 +1,5 @@
//! Client handshake machine.
use base64;
use rand;
use httparse;
@ -14,7 +16,9 @@ use super::machine::{HandshakeMachine, StageResult, TryParse};
/// Client request.
pub struct Request<'t> {
/// `ws://` or `wss://` URL to connect to.
pub url: Url,
/// Extra HTTP headers to append to the request.
pub extra_headers: Option<&'t [(&'t str, &'t str)]>,
}
@ -38,6 +42,15 @@ impl<'t> Request<'t> {
}
}
impl From<Url> for Request<'static> {
fn from(value: Url) -> Self {
Request {
url: value,
extra_headers: None,
}
}
}
/// Client handshake role.
pub struct ClientHandshake {
verify_data: VerifyData,

@ -1,3 +1,5 @@
//! HTTP Request and response header handling.
use std::ascii::AsciiExt;
use std::str::from_utf8;
use std::slice;
@ -8,7 +10,7 @@ use httparse::Status;
use error::Result;
use super::machine::TryParse;
// Limit the number of header lines.
/// Limit for the number of header lines.
pub const MAX_HEADERS: usize = 124;
/// HTTP request or response headers.
@ -70,6 +72,7 @@ impl<'name, 'headers> Iterator for HeadersIter<'name, 'headers> {
/// Trait to convert raw objects into HTTP parseables.
pub trait FromHttparse<T>: Sized {
/// Convert raw object into parsed HTTP headers.
fn from_httparse(raw: T) -> Result<Self>;
}

@ -1,7 +1,8 @@
//! Server handshake machine.
use httparse;
use httparse::Status;
//use input_buffer::{InputBuffer, MIN_READ};
use error::{Error, Result};
use protocol::{WebSocket, Role};
use super::headers::{Headers, FromHttparse, MAX_HEADERS};
@ -10,7 +11,9 @@ use super::{MidHandshake, HandshakeRole, ProcessingResult, convert_key};
/// Request from the client.
pub struct Request {
/// Path part of the URL.
pub path: String,
/// HTTP headers.
pub headers: Headers,
}

@ -1,5 +1,6 @@
//! Lightweight, flexible WebSockets for Rust.
#![deny(
missing_docs,
missing_copy_implementations,
trivial_casts, trivial_numeric_casts,
unstable_features,

@ -6,7 +6,9 @@ use std::convert::{Into, From};
/// WebSocket message opcode as in RFC 6455.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum OpCode {
/// Data (text or binary).
Data(Data),
/// Control message (close, ping, pong).
Control(Control),
}

@ -6,16 +6,44 @@
use std::io::{Read, Write, Result as IoResult};
use std::net::TcpStream;
#[cfg(feature="tls")]
use native_tls::TlsStream;
/// Stream mode, either plain TCP or TLS.
#[derive(Clone, Copy)]
pub enum Mode {
/// Plain mode (`ws://` URL).
Plain,
/// TLS mode (`wss://` URL).
Tls,
}
/// Trait to switch TCP_NODELAY.
pub trait NoDelay {
/// Set the TCP_NODELAY option to the given value.
fn set_nodelay(&mut self, nodelay: bool) -> IoResult<()>;
}
impl NoDelay for TcpStream {
fn set_nodelay(&mut self, nodelay: bool) -> IoResult<()> {
TcpStream::set_nodelay(self, nodelay)
}
}
#[cfg(feature="tls")]
impl<S: Read + Write + NoDelay> NoDelay for TlsStream<S> {
fn set_nodelay(&mut self, nodelay: bool) -> IoResult<()> {
self.get_mut().set_nodelay(nodelay)
}
}
/// Stream, either plain TCP or TLS.
pub enum Stream<S, T> {
/// Unencrypted socket stream.
Plain(S),
/// Encrypted socket stream.
Tls(T),
}
@ -42,3 +70,12 @@ impl<S: Write, T: Write> Write for Stream<S, T> {
}
}
}
impl<S: NoDelay, T: NoDelay> NoDelay for Stream<S, T> {
fn set_nodelay(&mut self, nodelay: bool) -> IoResult<()> {
match *self {
Stream::Plain(ref mut s) => s.set_nodelay(nodelay),
Stream::Tls(ref mut s) => s.set_nodelay(nodelay),
}
}
}

@ -7,6 +7,7 @@ use error::Error;
/// Non-blocking IO handling.
pub trait NonBlockingError: Sized {
/// Convert WouldBlock to None and don't touch other errors.
fn into_non_blocking(self) -> Option<Self>;
}
@ -29,8 +30,12 @@ impl NonBlockingError for Error {
}
/// Non-blocking IO wrapper.
///
/// This trait is implemented for `Result<T, E: NonBlockingError>`.
pub trait NonBlockingResult {
/// Type of the converted result: `Result<Option<T>, E>`
type Result;
/// Perform the non-block conversion.
fn no_block(self) -> Self::Result;
}

Loading…
Cancel
Save