Merge branch 'devel'

Version 0.1.1 released.

Signed-off-by: Alexey Galakhov <agalakhov@snapview.de>
pull/7/head v0.1.1
Alexey Galakhov 8 years ago
commit ca2d2ce313
  1. 8
      Cargo.toml
  2. 17
      src/client.rs
  3. 2
      src/handshake/mod.rs
  4. 2
      src/protocol/frame/coding.rs
  5. 2
      src/protocol/frame/mod.rs
  6. 55
      src/protocol/message.rs
  7. 7
      src/protocol/mod.rs
  8. 9
      src/server.rs
  9. 6
      src/stream.rs
  10. 2
      src/util.rs

@ -1,13 +1,15 @@
[package] [package]
name = "tungstenite" name = "tungstenite"
description = "Lightweight stream-based WebSocket implementation" description = "Lightweight stream-based WebSocket implementation"
categories = ["Web programming", "Network programming"] categories = ["web-programming:websocket", "network-programming"]
keywords = ["websocket", "io", "web"] keywords = ["websocket", "io", "web"]
authors = ["Alexey Galakhov"] authors = ["Alexey Galakhov"]
license = "MIT" license = "MIT"
readme = "README.md" readme = "README.md"
homepage = "https://github.com/snapview/tungstenite-rs"
documentation = "https://docs.rs/tungstenite/0.1.1"
repository = "https://github.com/snapview/tungstenite-rs" repository = "https://github.com/snapview/tungstenite-rs"
version = "0.1.0" version = "0.1.1"
[features] [features]
default = ["tls"] default = ["tls"]
@ -23,7 +25,7 @@ log = "0.3.7"
rand = "0.3.15" rand = "0.3.15"
sha1 = "0.2.0" sha1 = "0.2.0"
url = "1.4.0" url = "1.4.0"
utf-8 = "0.6" utf-8 = "0.7.0"
[dependencies.native-tls] [dependencies.native-tls]
optional = true optional = true

@ -1,3 +1,5 @@
//! Methods to connect to an WebSocket as a client.
use std::net::{TcpStream, SocketAddr, ToSocketAddrs}; use std::net::{TcpStream, SocketAddr, ToSocketAddrs};
use std::result::Result as StdResult; use std::result::Result as StdResult;
use std::io::{Read, Write}; use std::io::{Read, Write};
@ -25,6 +27,14 @@ pub type AutoStream = TcpStream;
/// ///
/// The URL may be either ws:// or wss://. /// The URL may be either ws:// or wss://.
/// To support wss:// URLs, feature "tls" must be turned on. /// To support wss:// URLs, feature "tls" must be turned on.
///
/// This function "just works" for those who wants a simple blocking solution
/// similar to `std::net::TcpStream`. If you want a non-blocking or other
/// custom stream, call `client` instead.
///
/// 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>> { pub fn connect(url: Url) -> Result<WebSocket<AutoStream>> {
let mode = url_mode(&url)?; let mode = url_mode(&url)?;
let addrs = url.to_socket_addrs()?; let addrs = url.to_socket_addrs()?;
@ -77,7 +87,8 @@ fn connect_to_some<A>(addrs: A, url: &Url, mode: Mode) -> Result<AutoStream>
/// Get the mode of the given URL. /// Get the mode of the given URL.
/// ///
/// This function may be used in non-blocking implementations. /// This function may be used to ease the creation of custom TLS streams
/// in non-blocking algorithmss or for use with TLS libraries other than `native_tls`.
pub fn url_mode(url: &Url) -> Result<Mode> { pub fn url_mode(url: &Url) -> Result<Mode> {
match url.scheme() { match url.scheme() {
"ws" => Ok(Mode::Plain), "ws" => Ok(Mode::Plain),
@ -88,7 +99,9 @@ pub fn url_mode(url: &Url) -> Result<Mode> {
/// Do the client handshake over the given stream. /// Do the client handshake over the given stream.
/// ///
/// Use this function if you need a nonblocking handshake support. /// 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<Stream: Read + Write>(url: Url, stream: Stream)
-> StdResult<WebSocket<Stream>, HandshakeError<Stream, ClientHandshake>> -> StdResult<WebSocket<Stream>, HandshakeError<Stream, ClientHandshake>>
{ {

@ -1,3 +1,5 @@
//! WebSocket handshake control.
pub mod headers; pub mod headers;
pub mod client; pub mod client;
pub mod server; pub mod server;

@ -1,3 +1,5 @@
//! Various codes defined in RFC 6455.
use std::fmt; use std::fmt;
use std::convert::{Into, From}; use std::convert::{Into, From};

@ -1,3 +1,5 @@
//! Utilities to work with raw WebSocket frames.
pub mod coding; pub mod coding;
mod frame; mod frame;

@ -8,34 +8,67 @@ use error::Result;
mod string_collect { mod string_collect {
use utf8; use utf8;
use utf8::DecodeError;
use error::{Error, Result}; use error::{Error, Result};
pub struct StringCollector { pub struct StringCollector {
data: String, data: String,
decoder: utf8::Decoder, incomplete: Option<utf8::Incomplete>,
} }
impl StringCollector { impl StringCollector {
pub fn new() -> Self { pub fn new() -> Self {
StringCollector { StringCollector {
data: String::new(), data: String::new(),
decoder: utf8::Decoder::new(), incomplete: None,
} }
} }
pub fn extend<T: AsRef<[u8]>>(&mut self, tail: T) -> Result<()> { pub fn extend<T: AsRef<[u8]>>(&mut self, tail: T) -> Result<()> {
let (sym, text, result) = self.decoder.decode(tail.as_ref()); let mut input: &[u8] = tail.as_ref();
self.data.push_str(&sym);
self.data.push_str(text); if let Some(mut incomplete) = self.incomplete.take() {
match result { let fin = if let Some((result, rest)) = incomplete.try_complete(input) {
utf8::Result::Ok | utf8::Result::Incomplete => input = rest;
Ok(()), if let Ok(text) = result {
utf8::Result::Error { remaining_input_after_error: _ } => self.data.push_str(text);
Err(Error::Utf8), } else {
return Err(Error::Utf8)
}
true
} else {
input = &[];
false
};
if !fin {
self.incomplete = Some(incomplete)
}
}
if !input.is_empty() {
match utf8::decode(input) {
Ok(text) => {
self.data.push_str(text);
Ok(())
}
Err(DecodeError::Incomplete { valid_prefix, incomplete_suffix }) => {
self.data.push_str(valid_prefix);
self.incomplete = Some(incomplete_suffix);
Ok(())
}
Err(DecodeError::Invalid { valid_prefix, .. }) => {
self.data.push_str(valid_prefix);
Err(Error::Utf8)
}
}
} else {
Ok(())
} }
} }
pub fn into_string(self) -> Result<String> { pub fn into_string(self) -> Result<String> {
if self.decoder.has_incomplete_sequence() { if self.incomplete.is_some() {
Err(Error::Utf8) Err(Error::Utf8)
} else { } else {
Ok(self.data) Ok(self.data)

@ -1,4 +1,4 @@
//! Generic WebSocket protocol implementation //! Generic WebSocket message stream.
pub mod frame; pub mod frame;
@ -25,7 +25,10 @@ pub enum Role {
Client, Client,
} }
/// WebSocket input-output stream /// WebSocket input-output stream.
///
/// This is THE structure you want to create to me able to talk the WebSocket protocol.
/// It may be created by calling `connect`, `accept` or `client` functions.
pub struct WebSocket<Stream> { pub struct WebSocket<Stream> {
/// Server or client? /// Server or client?
role: Role, role: Role,

@ -1,3 +1,5 @@
//! Methods to accept an incoming WebSocket connection on a server.
pub use handshake::server::ServerHandshake; pub use handshake::server::ServerHandshake;
use handshake::HandshakeError; use handshake::HandshakeError;
@ -5,7 +7,12 @@ use protocol::WebSocket;
use std::io::{Read, Write}; use std::io::{Read, Write};
/// Accept the given TcpStream as a WebSocket. /// Accept the given Stream as a WebSocket.
///
/// This function starts a server WebSocket handshake over the given stream.
/// If you want TLS support, use `native_tls::TlsStream` or `openssl::ssl::SslStream`
/// for the stream here. Any `Read + Write` streams are supported, including
/// those from `Mio` and others.
pub fn accept<Stream: Read + Write>(stream: Stream) pub fn accept<Stream: Read + Write>(stream: Stream)
-> Result<WebSocket<Stream>, HandshakeError<Stream, ServerHandshake>> -> Result<WebSocket<Stream>, HandshakeError<Stream, ServerHandshake>>
{ {

@ -1,3 +1,9 @@
//! Convenience wrapper for streams to switch between plain TCP and TLS at runtime.
//!
//! There is no dependency on actual TLS implementations. Everything like
//! `native_tls` or `openssl` will work as long as there is a TLS stream supporting standard
//! `Read + Write` traits.
use std::io::{Read, Write, Result as IoResult}; use std::io::{Read, Write, Result as IoResult};
/// Stream mode, either plain TCP or TLS. /// Stream mode, either plain TCP or TLS.

@ -1,3 +1,5 @@
//! Helper traits to ease non-blocking handling.
use std::io::{Error as IoError, ErrorKind as IoErrorKind}; use std::io::{Error as IoError, ErrorKind as IoErrorKind};
use std::result::Result as StdResult; use std::result::Result as StdResult;

Loading…
Cancel
Save