housleyjk / ws-rs

Lightweight, event-driven WebSockets for Rust.
MIT License
1.46k stars 219 forks source link

ssl-server very unreliable with random behaviour #297

Open meruiden opened 4 years ago

meruiden commented 4 years ago

Hi,

I am trying to make a wss server. I use the examle ssl-server code:

extern crate ws;
extern crate openssl;
extern crate env_logger;

use std::rc::Rc;
use std::io::Read;
use std::fs::File;

use openssl::ssl::{SslAcceptor, SslAcceptorBuilder, SslMethod, SslStream};
use openssl::pkey::PKey;
use openssl::x509::{X509, X509Ref};

use ws::util::TcpStream;

struct Server {
    out: ws::Sender,
    ssl: Rc<SslAcceptor>,
}

impl ws::Handler for Server {

    fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
        self.out.send(msg)
    }

    fn upgrade_ssl_server(&mut self, sock: TcpStream) -> ws::Result<SslStream<TcpStream>> {
        println!("new connection!");

        self.ssl.accept(sock).map_err(From::from)
    }
}

fn main () {
    // Setup logging
    env_logger::init();

    let cert = {
        let data = read_file("certificate.crt").unwrap();
        X509::from_pem(data.as_ref()).unwrap()
    };

    let pkey = {
        let data = read_file("private.key").unwrap();
        PKey::private_key_from_pem(data.as_ref()).unwrap()
    };

     let acceptor = Rc::new({
        let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
        builder.set_private_key(&pkey).unwrap();
        builder.set_certificate(&cert).unwrap();

        builder.build()
    });

    let ws_settings = ws::Settings {
        max_connections: 100,
        queue_size: 50,
        panic_on_new_connection: false,
        panic_on_shutdown: false,
        fragments_capacity: 10,
        fragments_grow: true,
        fragment_size: u16::max_value() as usize,
        max_fragment_size: usize::max_value(),
        in_buffer_capacity: 2048,
        in_buffer_grow: true,
        out_buffer_capacity: 2048,
        out_buffer_grow: true,
        panic_on_internal: true,
        panic_on_capacity: false,
        panic_on_protocol: false,
        panic_on_encoding: false,
        panic_on_queue: false,
        panic_on_io: false,
        panic_on_timeout: false,
        shutdown_on_interrupt: true,
        masking_strict: false,
        key_strict: true,
        method_strict: false,
        encrypt_server: true,
        tcp_nodelay: true,
    };
    println!("max: {}", usize::max_value());

    assert!(ws_settings.queue_size * ws_settings.max_connections <= usize::max_value(), "overflow!");

    ws::Builder::new().with_settings(ws_settings).build(|out: ws::Sender| {
        Server {
            out: out,
            ssl: acceptor.clone(),
        }
    }).unwrap().listen("spaceio.csteenhuis.com:3012").unwrap();
}

fn read_file(name: &str) -> std::io::Result<Vec<u8>> {
    let mut file = r#try!(File::open(name));
    let mut buf = Vec::new();
    r#try!(file.read_to_end(&mut buf));
    Ok(buf)
}

But when I try to connect to it using


  var wsUri = "wss://spaceio.csteenhuis.com:3012";
  var output;

  function init()
  {
    output = document.getElementById("output");
    testWebSocket();
  }

  function testWebSocket()
  {
    websocket = new WebSocket(wsUri);
    websocket.onopen = function(evt) { onOpen(evt) };
    websocket.onclose = function(evt) { onClose(evt) };
    websocket.onmessage = function(evt) { onMessage(evt) };
    websocket.onerror = function(evt) { onError(evt) };
  }

  function onOpen(evt)
  {
    writeToScreen("CONNECTED");
    doSend("WebSocket rocks");
  }

  function onClose(evt)
  {
    writeToScreen("DISCONNECTED");
  }

  function onMessage(evt)
  {
    writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
    websocket.close();
  }

  function onError(evt)
  {
    writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
  }

  function doSend(message)
  {
    writeToScreen("SENT: " + message);
    websocket.send(message);
  }

  function writeToScreen(message)
  {
    var pre = document.createElement("p");
    pre.style.wordWrap = "break-word";
    pre.innerHTML = message;
    output.appendChild(pre);
  }

  window.addEventListener("load", init, false);

but most of the time I get Connection closed before receiving a handshake response from the chrome console.

and sometimes it connects without a problem.

it's super random and I have no clue why this happens.

The application is build using the OpenSSL build I got using vcpkg on Windows and runs on windows server 2016.

lucdoebereiner commented 4 years ago

Hi, I get the same strange behavior with my small server, running debian 10.