Coder Social home page Coder Social logo

rust-websocket's People

Contributors

ashfordneil avatar bentheelder avatar bgdncz avatar cyderize avatar enet4 avatar fuchsnj avatar illegalprime avatar janhohenheim avatar jaysonsantos avatar kpp avatar manishearth avatar mati865 avatar mbrubeck avatar mikeswoods avatar mr-leshiy avatar najamelan avatar nashenas88 avatar nox avatar overdrivenpotato avatar paul-andre avatar peterw-lwl avatar simonsapin avatar spinda avatar sterlingjensen avatar surdus avatar therustmonk avatar timvisee avatar tomaka avatar vi avatar x1957 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-websocket's Issues

API Discussion: becoming lightweight and feature-full (through hyper, mio, net2 and more)

This seemed like a good place for this. I wanted to flesh out a few things I was thinking about.
There are many websocket libraries out there today but this one is the coolest, and it can be cooler!
There are many missing features and pain points of the library that I wanted to discuss and I thought I would list them here. We should also include some features from other libraries and become the best ws library out there!

Features:

  • HTTP Server integration
    • Take hyper requests and turn them into websockets
    • integration with hyper and others can be kept under a feature.
    • easier routing
  • custom headers
    • Cookies is probably useful, etc.
  • non-blocking
    • simple, use the net2 crate
  • mio support
    • easy, but API should be decided first
  • protocols
    • easy, needs API change
  • bare bones
    • easier user control of the dataframe sent over the wire
    • a lot of this is just more documentation
  • thread pool
    • probably behind a feature toggle, not a priority, seems useful
  • autobahn tests
    • add permessage-deflate

Pain Points:

  • maybe using hyper is overkill. still not 100% sure.
    • http-muncher or httparse + some header library might be OK
    • we really don't need anything more than stdlib, see websocket-stream
    • we might be able to get away with maybe 1 dependency
  • not so precise error handling scheme, although this is a low priority
  • more documentation
  • more fluent API
    • this is mostly true but I think there are some places that could be more readable
  • less unecessary copying (there is still some going on!)

Future:

  • I'm a worried about supporting future revisions to the standard, the code now isn't so flexible.

This mostly spawned out of me trying to fix #53, and I thought we should discuss some API before I sink more time into it. If we're all clear on what we want it to look like we can easily split up work and people can more easily contribute.

So @cyderize to start off do you think this list is complete? I have some API ideas I'll post soon.

first websocket messages can be consumed during handshake process

I have been tracking down a series of intermittent failures inside servos test suite to do with Websockets. The original issue is available here servo/servo#9803 but it's full of crazy thoughts and lots of distractions and is probably best to ignore.

I believe I have tracked down the issue to a problem in the way rust-websocket reads the handshake response and then transfers over to reading the BufReader itself. What happens is occasionally when hyper reads the handshake response into the buffer it also pulls with it the next message(s) aswell. So when parse_response returns the BufReader is setup that it's position points to the next message that is in it's internal buffer and the stream has been completely consumed.

https://github.com/cyderize/rust-websocket/blob/master/src/client/response.rs#L45

    let response = try!(parse_response(reader));

This becomes a problem when begin() in response.rs is called to create a sender and receiver, this function throws away the previous BufReader by sending the inner stream to Receiver that creates a new BufReader so everything inside the old buffer that was ready to be parsed is lost.

https://github.com/cyderize/rust-websocket/blob/master/src/client/response.rs#L133

This issue is made more frequent by servos test suite because a lot of the tests send the first websocket message instantly after the handshake response, so the issue pops up there a lot more often.

I'll create a pull request with what I think is an easy solution to the problem but I'm not sure if it's the best thing to do. It just moves the BufReader over to reciever instead of the internal stream.

Example of usage with a HTTP server?

Hello, I'd love to use rust-websocket for a project I'm working on. I'd like to make a server (using iron or hyper) that supports both HTTP connections and WebSocket connections. I imagine this is a common use case. Is this possible with the current API? If so, perhaps a simple example in the docs would be very helpful.

Use associated types

The bulk of this library will be rewritten using much nicer associated types.

This will be happening in the dev branch, and will be merged into master when complete, removing the annoying old_impl_check warnings.

SSL bound server errors on read_request

So I can't seem to get a secure socket server running correctly, each successful connection returns a "Bad file descriptor" error upon read_request. Strangely, the sample runs perfectly fine if I use Server::bind instead of Server::bind_secure. I've tested this on Ubuntu 15.04 64bit and OSX 10.10.5, the same issue persists.

I was also able to get an Iron server working with the same SSL certificates, so I'm fairly sure that hyper is not the issue here.

Example code: (You need a valid certificate saved as certs/cert.pem and key as certs/privkey.pem)

extern crate websocket;
extern crate openssl;

use std::thread;
use std::path::Path;

use websocket::{Client, Message, Server};
use websocket::client::request::Url;

use openssl::ssl::{SslContext, SslMethod};
use openssl::x509::X509FileType;

fn main() {
    // Set up SSL
    let mut context = SslContext::new(SslMethod::Tlsv1).unwrap();
    let _ = context.set_certificate_file(Path::new("certs/cert.pem"), X509FileType::PEM);
    let _ = context.set_private_key_file(Path::new("certs/privkey.pem"), X509FileType::PEM);

    // Launch server
    let server = Server::bind_secure("0.0.0.0:1234", &context).unwrap();

    // New thread for client
    thread::spawn(|| {
        let url = Url::parse("wss://127.0.0.1:1234").unwrap(); // Socket URL
        let mut client = Client::connect(url).unwrap() // Fetch request
                                .send().unwrap()       // Fetch response
                                .begin();              // Get client

        // Send a hello world message
        let _ = client.send_message(&Message::text("Hello, World!"));
    });

    // Handle server connections
    for connection in server {
        let connection = connection.unwrap();

        // This will panic with "Bad file descriptor"
        let _request = connection.read_request().unwrap();

        // ...
    }
}

Migrate to new Io module

All dependencies now compile.

We need to rewrite everything to use the new IO module std::io, std::net, etc.

Add method to "upgrade" hyper request to a WebSocket.

Currently the HTTP request is parsed inside of the library. It would be nice if there was a way to check if an existing hyper Request is a websocket request, and if so provide a way to "upgrade" it into a websocket connection. This allows using hyper as a HTTP server and accepting websockets on the same port.

This is similar to how the ruby library faye-websocket works. You can check the env (essentially a standard request format) if it is a websocket, and if so "upgrade" it into a websocket connection.

add .shutdown() method to server

As far as I can tell, it does not seem possible to stop the server and close all of the connections cleanly.

Right now you would need some way to signal to each connection to shut them down,then to break out of the for connection in server you would have to wait for another connection to connect and then break (or make one yourself). But this is very messy. It would be great if there was a shutdown() method on the server.

URL parse errors not exposed for matching?

extern crate websocket;

use websocket:client::request::Url;

fn main() {
    let input = "127.0.0.1:1880";
    let url: Url = match input.parse() {
        Ok(url) => url,
        Err(err) => {
            println!("{:?}", err);
        }
    }
}

Output:

RelativeUrlWithoutBase

However, I don't seem to be able to match on this enum.
If I try, it gives:

src/main.rs:146:17: 146:39 warning: pattern binding `RelativeUrlWithoutBase` is named the same as one of the variants of the type `url::parser::ParseError` [E0170]
src/main.rs:146             Err(RelativeUrlWithoutBase) => {
                                ^~~~~~~~~~~~~~~~~~~~~~
src/main.rs:146:17: 146:39 help: run `rustc --explain E0170` to see a detailed explanation
src/main.rs:146:17: 146:39 help: if you meant to match on a variant, consider making the path in the pattern qualified: `url::parser::ParseError::RelativeUrlWithoutBase`

Trying to use the enum from the url crate directly gives me:

src/main.rs:14:5: 14:52 error: variant `RelativeUrlWithoutBase` is private
src/main.rs:14 use url::parser::ParseError::RelativeUrlWithoutBase;

Unless I'm missing something, the websocket library doesn't actually expose this error, the client.rs file only has

pub use url::Url;

Please let me know if there's a correct way to be able to match on the URL parse errors, thanks! Sorry, I'm relatively new at rust and maybe missed something obvious.

bug? latest version under chromium

WebSocket connection to 'ws://127.0.0.1:8080/' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received index.html:8

but ok under firefox and midori.

and version 0.9.2 are all ok.

openssl dependency conflics breaks build

My local build fails with:

native library openssl is being linked to by more than one package, and can only be linked to by one package
openssl-sys v0.7.0
openssl-sys v0.6.7

Hacking the library to depend on 0.6.7 fixes the build, for now at least.

example doesn't work

Hi,

I'm new to rust. I compiled the repo but the main thread is panicking:

     Running `target/debug/examples/server`
thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 48, message: "Address already in use" } }', ../src/libcore/result.rs:785
note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: Process didn't exit successfully: `target/debug/examples/server` (exit code: 101)

Create a todo for contributions

I think a TODO list would be great for contributors. It would be much easier than searching in every file for bugs, typos and lack of documentation.

one client, one thread?

In rust and rust-websocket, how to keep the connection for each client persion?
if one client, one thread, can reach 10k connections in single server machine?

doesn't build on 1.1 release

TL;DR: Quick (and IMO correct) fix for now is to pin the hyper dependency to the last version before the refactor, 0.5.2. Iron did the same thing while it gets familiar with the changes.

So 1.1 is out. Hyper made some refactorings that changed some stuff around, but mainly with respect to this package it concerns the fact that parse_response is now in hyper::http::h1 instead of just hyper::http, and so on. I was working on a fix but the problem I ran into was this at the end of src/server/mod.rs:

/// Represents a connection to the server that has not been processed yet.
pub struct Connection<R: Read, W: Write>(R, W);

impl<R: Read, W: Write> Connection<R, W> {
    /// Process this connection and read the request.
    pub fn read_request(self) -> io::Result<Request<R, W>> {
        match Request::read(self.0, self.1) {
            Ok(result) => { Ok(result) },
            Err(err) => {
                Err(io::Error::new(io::ErrorKind::InvalidInput, err))
            }
        }
    }
}

This io::Error::new method requires that the error payload err 'implements' Into<Box<Error + Send + Sync>>. The error is that the err is not Sync or Send. These kinds of bugs are annoying to track down because it's difficult to tell which field is implicitly breaking the Sync/Send bounds. If I had to guess, it's also coming from the hyper refactors, so one of the hyper-related error variants is most likely the culprit.

broken?

broken by library sha1?
how to fix?

an error every time

I run example/server.rs ,
in server console, report:
thread '' panicked at 'called Result::unwrap() on an Err value: IoError(end of file)', /home/rustbuild/src/rust-buildbot/slave/nightly-linux/build/src/libcore/result.rs:746

and in firefox console:
载入页面时到 ws://127.0.0.1:8080/ 的连接被中断。(connection was aborted when loading page: ws://127.0.0.1:8080/)

every time when I refresh web page in browser and wait some seconds, it occurs.

Unmasked data error

I have errors with version 0.14:

thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value:
DataFrameError("Expected unmasked data frame")', ../src/libcore\result.rs:741

When I try hyper example Chrome also logs:

WebSocket connection to 'ws://127.0.0.1:2794/' failed:
A server must not mask any frames that it sends to the client.

Any example doesn't work. How to fix?

Env:
64 bit + rustc 1.6.0-nightly (1805bba39 2015-11-26) + Win 10

error: binary operation `+` cannot be applied to type `collections::vec::Vec<u8>`

Hello, I'm seeing the following compiler errors:

$ cargo build
   Compiling websocket v0.11.9
/Users/llehmijo/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.9/src/message.rs:59:11: 59:15 error: binary operation `+` cannot be applied to type `collections::vec::Vec<u8>` [E0369]
/Users/llehmijo/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.9/src/message.rs:59          data = data + &dataframe.data[..];
                                                                                                                   ^~~~
/Users/llehmijo/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.9/src/message.rs:106:6: 106:9 error: binary operation `+` cannot be applied to type `collections::vec::Vec<u8>` [E0369]
/Users/llehmijo/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.9/src/message.rs:106         Ok(buf + self.reason.as_bytes())
$ rustc --version
rustc 1.1.0-nightly (dc630d01e 2015-05-09) (built 2015-05-09)

Any way forward from here?

Thanks!

Could not compile `bswap`.

Hi @cyderize,

Thank you first for your work about _rust-websocket_'s project.

I report for you this incident on a _OS X Yosemite_ with the _10.10.2_'s Version:
The fail is bswap: Could not compile bswap.

> cargo build                                                                                    ()
    Updating git repository `https://github.com/cyderize/rust-websocket.git`
    Updating registry `https://github.com/rust-lang/crates.io-index`
 Downloading openssl-sys v0.5.1
 Downloading unicase v0.0.5
 Downloading rustc-serialize v0.3.3
 Downloading openssl v0.5.1
 Downloading hyper v0.3.0
 Downloading time v0.1.20
 Downloading byteorder v0.2.14
 Downloading cookie v0.1.14
 Downloading url v0.2.23
 Downloading pkg-config v0.3.1
 Downloading mime v0.0.10
 Downloading bswap v0.1.8
 Downloading rand v0.2.0
   Compiling bitflags v0.1.1
   Compiling bswap v0.1.8
   Compiling libc v0.1.3
   Compiling matches v0.1.2
/nfs/zfs-student-5/users/2013/adjivas/.cargo/registry/src/github.com-1ecc6299db9ec823/bswap-0.1.8/src/lib.rs:56:15: 56:42 error: mismatched types:
 expected `usize`,
    found `u32`
(expected usize,
    found u32) [E0308]
/nfs/zfs-student-5/users/2013/adjivas/.cargo/registry/src/github.com-1ecc6299db9ec823/bswap-0.1.8/src/lib.rs:56         2.pow(off.trailing_zeros() as u32)
                                                                                                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
   Compiling rustc-serialize v0.3.3
   Compiling gcc v0.3.1
   Compiling log v0.2.5
   Compiling pkg-config v0.3.1
   Compiling unicase v0.0.5
Build failed, waiting for other jobs to finish...
Could not compile `bswap`.

To learn more, run the command again with --verbose.

My tree after:

.
├── Cargo.lock
├── Cargo.toml
├── src
│   └── main.rs
└── target
    └── debug
        ├── build
        │   ├── openssl-sys-f4dc33ec05a937b0
        │   └── time-8511b46a947a4506
        ├── deps
        │   ├── bswap-3db22c6264f0f04b.d
        │   ├── libbitflags-518ea12e21428edd.rlib
        │   ├── libgcc-a2129010e6303bbd.rlib
        │   ├── liblibc-2a692f33a70517c8.rlib
        │   ├── liblog-045aab9d45b4c031.rlib
        │   ├── libmatches-68db25b520030534.rlib
        │   ├── libpkg-config-4849fc4851dfef8e.rlib
        │   ├── librustc-serialize-fb785ec689194073.rlib
        │   └── libunicase-9f1a923080f372c3.rlib
        ├── examples
        └── native

Can't run on 1.1.0-nightly: panicked at 'called `Result::unwrap()`

I can run both server and client, but when the client starts there is a runtime error:

$ cargo run --example server
     Running `target/debug/examples/server`
Connection from 127.0.0.1:58077
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: NoDataAvailable', /Users/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-mac/build/src/libcore/result.rs:729
$ cargo run --example client
     Running `target/debug/examples/client`
Connecting to ws://127.0.0.1:2794/
thread '<main>' panicked at 'arithmetic operation overflowed', /Users/endel/.cargo/registry/src/github.com-1ecc6299db9ec823/httparse-0.1.1/src/lib.rs:34
$ rustc --version
rustc 1.1.0-nightly (aecf3d8b6 2015-05-01) (built 2015-05-01)

get stable-compatible

I really would love it if this could build on stable. I would love to help wherever I can.

Some approaches I've seen to getting things to build on stable include:

  • introducing a cargo feature that enables specific functionality that requires nightly, that is, one feature for each distinct piece of functionality. Then use the cfg(feature = "blah") to conditionally compile pieces of code
  • alternatively, as above, introduce some 'nightly' feature that toggles all functionality that requires nightly, if it doesn't make sense to provide fine-grained toggling
  • rip out the implementations of unstable features that is relied upon from the nightly std and embed it into your own package, at least until the fate of such unstable features is determined

fails to compile with rust nightly (4/22)

   Compiling websocket v0.11.6
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\lib.rs:4:4: 4:12 error: stability a
ttributes may not be used outside of the standard library
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\lib.rs:4 #![unstable]
                                                                                                 ^~~~~~~~
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\dataframe.rs:1:4: 1:10 error: stabi
lity attributes may not be used outside of the standard library
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\dataframe.rs:1 #![stable]
                                                                                                       ^~~~~~
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\result.rs:1:4: 1:10 error: stabilit
y attributes may not be used outside of the standard library
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\result.rs:1 #![stable]
                                                                                                    ^~~~~~
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\stream.rs:1:4: 1:10 error: stabilit
y attributes may not be used outside of the standard library
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\stream.rs:1 #![stable]
                                                                                                    ^~~~~~
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\header/mod.rs:1:4: 1:10 error: stab
ility attributes may not be used outside of the standard library
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\header/mod.rs:1 #![stable]
                                                                                                        ^~~~~~
error: aborting due to 5 previous errors
Build failed, waiting for other jobs to finish...
Could not compile `websocket`.
rustc --version
rustc 1.0.0-nightly (2baf34825 2015-04-21) (built 2015-04-22)

Cloning Streams is Untenable

Currently I am trying to refactor the idea of a Stream in this library.
A stream should simply be something that can be written to and read from.

The hyper has had some issues with this idea as well, and recently refactored their NetworkStream which implemented (in my opinion too many) traits: Read + Write + Any + Send + Typeable, into a Transport trait which simply implements Read + Write (and Evented for mio support).

The Problem

We are supporting a (maybe strange, maybe normal) use case of being able to split the client into two owned copies (sender and receiver) so they may be used in different threads.

This creates a need for streams to support the ability to clone themselves into two owned copies.
This is OK with TcpStream, but in SslStream the try_clone(&self) function is deprecated in newer versions and will be removed.

Hyper integration is also blocked since Hyper's NetworkStream and now Transport do not implement try_clone(&self), presumably because of the above reason.

Solution: Remove Support, Switch to Arc<Mutex<Client<...>>>

The solution as I see it is to no longer support multi-threading as a first class use-case.
If someone needs to use a client on multiple threads they can wrap it in a lock.
I am under the impression that this is how it currently works when one clones a TcpStream and tries to read and write to it: the kernel has a lock on this file descriptor and blocks calls accordingly. Please correct me if I am wrong. This change would just make the locking more explicit.

This would also allow the Client to not own its stream (which is wanted in the use case of hyper integration).

Multi-threading for servers is still practical though, since each Client the server creates can be dispatched to worker threads safely.

For Those Still Holding Out

There will be a method on the Client called .stream(&self) -> &S which would return the concrete type of the stream the Client is using, so it can be cloned by people who want to.

Implications

  1. Client can no longer be split.
  2. Sender and Receiver will no longer be able to own/borrow their stream.

Request parsing should be done in a separate thread

I'm not sure I fully understand the situation, but let me explain. While running a server, it seems that some laggy clients can slow down the entire accept()ing process on the server.

According to the gdb stack trace, it is sometimes stuck as follows:

#0  0x00007ffff72b755d in read () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x000055555561e2fa in net::tcp::TcpStream.Read::read::hcc8bbd2f6c31c9d1o7m ()
#2  0x00005555555af2c4 in websocket::stream::WebSocketStream.Read::read (self=0x7fffffffc750, buf=...) at /home/barosl/.cargo/git/checkouts/rust-websocket-3ef83361cb9b03c6/master/src/stream.rs:19
#3  0x00005555555af052 in fnfn (b=...) at /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/io/buffered.rs:96
#4  0x00005555555aedc3 in websocket::io::with_end_to_cap<closure> (v=0x7fffffffc780, f={union Result<usize, std::io::error::Error> (struct (&mut [u8]))} 0x7fffffffb420)
    at /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/io/mod.rs:77
#5  0x00005555555ae94d in websocket::io::buffered::BufReader<R>.BufRead::fill_buf (self=0x7fffffffc750)
    at /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/io/buffered.rs:96
#6  0x00005555555adc8c in websocket::http::parse_request<std::io::buffered::BufReader<websocket::stream::WebSocketStream>> (buf=0x7fffffffc750)
    at /home/barosl/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.3.2/src/http.rs:313
#7  0x00005555555ad492 in websocket::server::request::Request<R, W>::read (reader=..., writer=...) at /home/barosl/.cargo/git/checkouts/rust-websocket-3ef83361cb9b03c6/master/src/server/request.rs:85
#8  0x00005555555ac426 in websocket::server::Server<'a>::accept (self=0x7fffffffd900) at /home/barosl/.cargo/git/checkouts/rust-websocket-3ef83361cb9b03c6/master/src/server/mod.rs:139
#9  0x00005555555b07a5 in websocket::server::Server<'a>.Iterator::next (self=0x7fffffffd900) at /home/barosl/.cargo/git/checkouts/rust-websocket-3ef83361cb9b03c6/master/src/server/mod.rs:156

As you can see, it is indefinitely waiting for the client to respond with the request header. That means, the following code in src/server/mod.rs is problematic:

match Request::read(try!(wsstream.try_clone()), try!(wsstream.try_clone())) {

I believe this is because, currently, the request parsing is done in the main thread. To cope with this, the parsing should be delegated to the client thread. But it is not possible, as there is no other way to parse the request manually other than relying on Server::accept().

So, I think, there should be two separate methods. One for the TcpStream acceptance, the other for the usual HTTP parsing. The iterator for Server should process only the former, and the latter may be processed in a separate thread.

Am I right? What do you think on this?

tokio support

It would be great if this library supported tokio-rs, it would really ease up the interop and composability of this library.

I'll study the source code and I will file a PR, if I'm confident I know enough about the source to make the changes, and if that feature is desirable enough.

Build fails on Windows: Cannot open include file: 'openssl/ssl.h': No such file or directory

`cargo run
Compiling traitobject v0.0.1
Compiling lazy_static v0.2.1
Compiling unicode-normalization v0.1.2
Compiling libc v0.2.10
Compiling log v0.3.6
Compiling language-tags v0.2.2
Compiling winapi v0.2.6
Compiling semver v0.1.20
Compiling typeable v0.1.2
Compiling pkg-config v0.3.8
Compiling winapi-build v0.1.1
Compiling mime v0.2.2
Compiling ws2_32-sys v0.2.1
Compiling rand v0.3.14
Compiling user32-sys v0.2.0
Compiling openssl-sys v0.7.14
Compiling num_cpus v0.2.13
Compiling rustc_version v0.1.7
Compiling cfg-if v0.1.0
Compiling matches v0.1.2
Compiling kernel32-sys v0.2.2
Compiling unicode-bidi v0.2.3
Compiling byteorder v0.5.1
Compiling bitflags v0.7.0
Compiling rustc-serialize v0.3.19
Compiling unicase v1.4.0
Compiling gcc v0.3.32
Compiling httparse v1.1.2
Compiling gdi32-sys v0.2.0
Compiling hpack v0.2.0
Compiling idna v0.1.0
Compiling solicit v0.4.4
Compiling openssl-sys-extras v0.7.14
Compiling openssl v0.7.14
Compiling url v1.2.0
Build failed, waiting for other jobs to finish...
error: failed to run custom build command for openssl v0.7.14
Process didn't exit successfully: C:\prod\ws\target\debug\build\openssl-5464f8f6e728c35a\build-script-build (
--- stdout
TARGET = Some("x86_64-pc-windows-msvc")
OPT_LEVEL = Some("0")
PROFILE = Some("debug")
TARGET = Some("x86_64-pc-windows-msvc")
debug=true opt-level=0
HOST = Some("x86_64-pc-windows-msvc")
TARGET = Some("x86_64-pc-windows-msvc")
TARGET = Some("x86_64-pc-windows-msvc")
HOST = Some("x86_64-pc-windows-msvc")
CC_x86_64-pc-windows-msvc = None
CC_x86_64_pc_windows_msvc = None
HOST_CC = None
CC = None
TARGET = Some("x86_64-pc-windows-msvc")
HOST = Some("x86_64-pc-windows-msvc")
CFLAGS_x86_64-pc-windows-msvc = None
CFLAGS_x86_64_pc_windows_msvc = None
HOST_CFLAGS = None
CFLAGS = None
running: "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\cl.exe" "/nologo" "/MD" "/Z7"
s\target\debug\build\openssl-5464f8f6e728c35a\out\src\c_helpers.o" "/c" "src/c_helpers.c"
c_helpers.c
src/c_helpers.c(1): fatal error C1083: Cannot open include file: 'openssl/ssl.h': No such file or directory
ExitStatus(ExitStatus(2))

command did not execute successfully, got: exit code: 2

--- stderr
thread '

' panicked at 'explicit panic', C:\Users.cargo\registry\src\github.com-1ecc6299db9e\src\lib.rs:848
note: Run with RUST_BACKTRACE=1 for a backtrace.

`

fails to compile with rust nightly (4/23)

   Compiling websocket v0.11.7
C:\Users\fuchs_000\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.7\src\ws\util\dataframe.rs:3:5: 3:28 e
rror: unresolved import `std::num::FromPrimitive`. There is no `FromPrimitive` in `std::num`
C:\Users\fuchs_000\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.7\src\ws\util\dataframe.rs:3 use std::
num::FromPrimitive;

error: aborting due to previous error
Build failed, waiting for other jobs to finish...
Could not compile `websocket`.
rustc --version
rustc 1.1.0-nightly (90cc83015 2015-04-22) (built 2015-04-23)

Sender shared across threads

Is it possible to have multiple threads use a Sender simultaneously?
I have a thread whose entire purpose is sending a ping-type message, and it worked with the old Client design, but I'm not sure how to transition it into the new Receiver/Sender design (Sender doesn't implement Clone).

perfect lib

this is the best websocket of rust now!
Do you consider to combine with hyper?
thx.

Server works for Firefox but not for Chrome

When I run the examples server and autobahn-server they fail in Chome but work in Firefox

The server fails with one of the message below

thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: NoDataAvailable', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/result.rs:729

thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: IoError(Error { repr: Os(32) })', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/result.rs:729

Chrome's error message is below

WebSocket connection to 'ws://127.0.0.1:2794/' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received

One difference I can see in the request headers is Chrome has client_max_window_bits in its Sec-WebSocket-Extensions header

Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

Firefox
GET / HTTP/1.1
Host: 127.0.0.1:2794
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: null
Sec-WebSocket-Protocol: rust-websocket
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: lDZ28g1qsvq2+z4hj7hUzQ==
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

HTTP/1.1 101 Switching Protocols
Sec-WebSocket-Accept: fhZDselY5dBr8uW+eFXcOtdkUXw=
Connection: Upgrade
Upgrade: websocket

..Hello

Chrome
GET / HTTP/1.1
Host: 127.0.0.1:2794
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: null
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-GB,en;q=0.8
Sec-WebSocket-Key: QUrpS70CwiViTEk5g68sBA==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: rust-websocket

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: OPF1GnZv5n7IftL0aFw7ijr3v6c=

..Hello

Panic on Request.accept()

I'm getting a panic when accepting a new connection using Request.accept() on server, especially when multiple clients are trying to connect at once.

thread '<main>' panicked at 'called `Option::unwrap()` on a `None` value', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/option.rs:362
stack backtrace:
   1:     0x7f9cfc9b10f4 - sys::backtrace::write::h9babc8795a85a17910C
   2:     0x7f9cfc9b4c7f - panicking::on_panic::h87037425aaedfce4thJ
   3:     0x7f9cfc9a276a - rt::unwind::begin_unwind_inner::h938edd242c70217e2XI
   4:     0x7f9cfc9a2e21 - rt::unwind::begin_unwind_fmt::h73e2fa758231ca8aDWI
   5:     0x7f9cfc9b4667 - rust_begin_unwind
   6:     0x7f9cfc9e0b64 - panicking::panic_fmt::h4acd4dec7d5ce278Tku
   7:     0x7f9cfc9e09e4 - panicking::panic::he2b07ace86a7d60eqju
   8:     0x7f9cfc91f898 - option::Option<T>::unwrap::h8919241931690594829
                        at /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/macros.rs:19
   9:     0x7f9cfc91aede - server::response::Response<R, W>::new::h4627714234374605650
                        at /home/barosl/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.2/src/server/response.rs:73
  10:     0x7f9cfc91acd8 - server::request::Request<R, W>::fail::h18318390619043582200
                        at /home/barosl/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.2/src/server/request.rs:152
  11:     0x7f9cfc909e78 - server::request::Request<R, W>::accept::h8170096839402963781
                        at /home/barosl/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.2/src/server/request.rs:145
  12:     0x7f9cfc8f955e - main::h618e390d4325d3e6maa
                        at src/main.rs:17
  13:     0x7f9cfc9b85d8 - rust_try_inner
  14:     0x7f9cfc9b85c5 - rust_try
  15:     0x7f9cfc9b67cb - rt::lang_start::h5750d73c7867c0b9ecJ
  16:     0x7f9cfc8f99e4 - main
  17:     0x7f9cfbad1ec4 - __libc_start_main
  18:     0x7f9cfc8f9148 - <unknown>
  19:                0x0 - <unknown>

The relevant code seems to be:

    /* src/server/response.rs:71-73 */
    pub fn new(request: Request<R, W>) -> Response<R, W> {
        let mut headers = Headers::new();
        headers.set(WebSocketAccept::new(request.key().unwrap()));

server.try_accept() ?

Is there a non-blocking way to check if there is an incoming connection and get that connection if there is?

Something like server.accept() but that would return an Option and return None instead of waiting would be nice.

Explicit versions for dependencies

As seen in #54 star-dependencies can cause problems for packages relying on websocket.
Also it's very unlikely that websocket will work with whatever versions its dependencies decide to release.

Would you consider adding explicit version requirements? I could send a PR for that.

Timeout on `recv_message`

Currently as I'm seeing it, an attacker could hold a thread responding to requests hostage as long as they want. I can of course terminate threads after a certain time but this probably has some dangerous side-effects that I don't ever want to happen.

Some autobahn tests fail

For some reason many tests from the autobahn test suite are now failing.

Not sure what exactly has changed that could cause this strange behaviour.

Failed to build OpenSSL on El Capitan

When running cargo build I was getting this error.

failed to run custom build command for `openssl v0.7.6`
Process didn't exit successfully: `/Users/.../Developer/hello_world/target/debug/build/openssl-09576f2f9776fa80/build-script-build` (exit code: 101)
--- stdout
TARGET = Some("x86_64-apple-darwin")
OPT_LEVEL = Some("0")
PROFILE = Some("debug")
TARGET = Some("x86_64-apple-darwin")
debug=true opt-level=0
HOST = Some("x86_64-apple-darwin")
TARGET = Some("x86_64-apple-darwin")
TARGET = Some("x86_64-apple-darwin")
HOST = Some("x86_64-apple-darwin")
CC_x86_64-apple-darwin = None
CC_x86_64_apple_darwin = None
HOST_CC = None
CC = None
HOST = Some("x86_64-apple-darwin")
TARGET = Some("x86_64-apple-darwin")
HOST = Some("x86_64-apple-darwin")
CFLAGS_x86_64-apple-darwin = None
CFLAGS_x86_64_apple_darwin = None
HOST_CFLAGS = None
CFLAGS = None
running: "cc" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-m64" "-fPIC" "-o" "/Users/.../Developer/hello_world/target/debug/build/openssl-09576f2f9776fa80/out/src/c_helpers.o" "-c" "src/c_helpers.c"
ExitStatus(ExitStatus(256))


command did not execute successfully, got: exit code: 1



--- stderr
src/c_helpers.c:1:10: fatal error: 'openssl/ssl.h' file not found
#include <openssl/ssl.h>
         ^
1 error generated.
thread '<main>' panicked at 'explicit panic', /Users/.../.cargo/registry/src/github.com-88ac128001ac3a9a/gcc-0.3.25/src/lib.rs:818

Fixed by the following:

$ brew uninstall --force openssl
$ brew install openssl
$ brew link --force openssl
$ cargo clean
$ cargo build

Fix from http://stackoverflow.com/questions/30818391/gem-eventmachine-fatal-error-openssl-ssl-h-file-not-found#comment55942148_33956405

Hope that this saves someone else some time.

Non-owning Message sending.

Is there a way, or could it be possible to add one, to send messages without having to allocate?

Basically having something like a MessageRef or using Cow so an allocation isn't required.

My use-case is I'm sending a pretty big Vec<u8> to multiple clients at 30 FPS, and right now I have to clone the vector for every client.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.