Firefox中的Websockets无法使用多个HTTPS页面

时间:2014-08-18 17:46:12

标签: javascript node.js security ssl websocket

我有一个websocket客户端 - 服务器应用程序。这是客户端的简化代码:

const HOST = "wss://localhost:8000";

const SUB_PROTOCOL= "sub-protocol"; 

var websocket = new WebSocket(HOST, SUB_PROTOCOL);

websocket.onopen  = function(evt)   { ... };
websocket.onclose = function(evt)   { ... };
websocket.onerror = function(evt)   { ... };
websocket.onmessage = function(evt) { ... };

这是服务器:

const PORT = 8000;
const SUBPROTOCOL = 'sub-protocol';

var WebSocketServer = require('websocket').server;

var https = require('https');
var fs = require('fs');

// Private key and certification (self-signed for now) 
var options = {
  key: fs.readFileSync('cert/server.key'),
  cert: fs.readFileSync('cert/server.crt')
};

var server = https.createServer(options, function(request, response) {
    console.log((new Date()) + ' Received HTTP(S) request for ' + request.url);
    response.writeHead(404);
    response.end();
}); 

// bind server object to listen to PORT number
server.listen(PORT, function() {
    console.log((new Date()) + ' Server is listening on port ' + PORT);
});

wsServer = new WebSocketServer({
    httpServer: server,
    // You should not use autoAcceptConnections for production
    // applications, as it defeats all standard cross-origin protection
    // facilities built into the protocol and the browser.  You should
    // *always* verify the connection's origin and decide whether or not
    // to accept it.
    autoAcceptConnections: false
});


function originIsAllowed(origin) {
  // put logic here to detect whether the specified origin is allowed.
  return true;
}

// If autoAcceptConnections is set to false, a request event will be emitted
// by the server whenever a new WebSocket request is made
wsServer.on('request', function(request) {

    if (!originIsAllowed(request.origin)) {
      // Make sure we only accept requests from an allowed origin
      request.reject();
      console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
      return;
    }

    // accepts connection and return socket for this connection
    var connection = request.accept(SUB_PROTOCOL, request.origin);

    console.log((new Date()) + ' Connection accepted.');

    // when message is received
    connection.on('message', function(message) {

        // echo
        connection.send(connection, message.utf8Data);

    });


    connection.on('close', function(reasonCode, description) {
        console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
    });

});

即使使用一些HTTPS页面(在Twitter,mail.ru上测试),客户端和服务器也能按预期工作。但出于某些原因,例如没有Facebook或GitHub。

在JavaScript控制台中我得到了这个:

Exception { message: "", result: 2153644038, name: "", filename: "", lineNumber: 0, columnNumber: 0, inner: null, data: null }

然后是大堆栈跟踪:粘贴它here

最后:

Content Security Policy: The page's settings blocked the loading of a resource at wss://localhost:8000/ ("connect-src https://github.com:443 https://ghconduit.com:25035 https://live.github.com:443 https://uploads.github.com:443 https://s3.amazonaws.com:443").

我不知道这些网页与网页有何不同之处。我还要指出,这些网页可以在Chrome中使用。

(在Firefox 31中测试)

1 个答案:

答案 0 :(得分:1)

WebSocket连接失败的页面具有Content-Security-Policy标头,connect-src指令设置为仅允许连接到一组列入白名单的域。这意味着从该页面到任何非白名单域的所有连接都将失败。

目前还不清楚你是如何运行这段代码的。 Chrome可能允许扩展程序绕过该标头限制,而Firefox则不然,或者出现这种情况。