We have to implement WebSocket connection with third-party WebSocket server. But they are using Authorization header for establishing a connection between WebSocket client and WebSocket server. But I could not find any solution to add Authorization header in WebSocket client during connection.
Please help me to resolve this issue.
This is my code I am using
var ws = new WebSocketClient();
var headers ={Authorization: 'token'}
ws.on('connectFailed', function(error) {
console.log('Connect Error: ' + error.toString());
});
ws.on('connect', function(connection) {
console.log('WebSocket Client Connected');
});
ws.connect('wss://url', '',headers);
Response is like this
Server responded with a non-101 status: 400 Bad Request
Response Headers Follow:
server: nginx/1.11.7
date: Thu, 11 Jul 2019 19:49:58 GMT
content-type: text/html
content-length: 31
connection: keep-alive
Related
I'm trying to get the response header of a website and get the cookies that i can find inside. There is no problem, it's working when i start the request through a terminal with "node file.js".
But i'm launching the POST request through a local HTML page, so i used browersify for be able to launch a request from a client-side (or at least this is what i understood).
Then i'm using a CORS proxy to get around “No Access-Control-Allow-Origin header” problems. When i start the request from my local HTML page it's working and i can read the body but i'm not able to find the reponse header of the website and get the cookie that i need.
Here how my request looks like:
function connectionInfoConcert(account, psw, next){
console.log("-------------CREATE HEADER-------------\n")
var options = {
method: 'POST',
url: 'https://tranquil-thicket-71867.herokuapp.com/https://www.infoconcert.com/mon-infoconcert/connexion.html',
headers: {
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Language':'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7',
'Cache-Control':'max-age=0',
'Connection':'keep-alive',
'Content-Length':'184',
'Content-Type':'application/x-www-form-urlencoded',
'origin': 'https://www.infoconcert.com',
'referer': 'https://www.infoconcert.com/mon-infoconcert/connexion.html'
},
form: {
origin:'',
username: account,
password: psw
}
};
console.log("-------------END HEADER-------------\n-----------START REQUEST-----------------------")
request(options, function (error, response, body) {
if (!error) {
console.log(response)
console.log(body)
console.log(response.headers['set-cookie'][0]); //obviously 'set-cookie' doesn't exist
}
else {
console.log(error)
console.log(response)
console.log("-------------ERROR------------")
return console.log("Something went wrong")
}
});}
https://www.infoconcert.com/mon-infoconcert/connexion.html is the website where i try to get the cookie
https://tranquil-thicket-71867.herokuapp.com is the CORS proxy that i'm using.
If some of you know how to be able to get the correct header it would be really nice !
Edit 1 :
The problem is when i do my request to "https://www.infoconcert.com/mon-infoconcert/connexion.html" i can find the cookie that i'm looking for in response.headers["set-cookie"].
But because i'm doing the request from a html page it's not working and i'm doing the request to "https://tranquil-thicket-71867.herokuapp.com/https://www.infoconcert.com/mon-infoconcert/connexion.html" but i can't find my cookie in the response.
Here the header of the response i got from "https://tranquil-thicket-71867.herokuapp.com/https://www.infoconcert.com/mon-infoconcert/connexion.html"
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: server,vary,cache-control,content-type,content-encoding,p3p,date,expires,pragma,connection,x-cache-info,x-final-url,access-control-allow-origin
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Thu, 03 May 2018 17:23:49 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
P3p: policyref="/w3c/p3p.xml", CP="NOI DSP COR NID CUR ADM DEV OUR BUS"
Pragma: no-cache
Server: Apache
Transfer-Encoding: chunked
Vary: Accept-Encoding,User-Agent
Via: 1.1 vegur
X-Cache-Info: not cacheable; response specified "Cache-Control: private"
X-Cors-Redirect-1: 302 https://www.infoconcert.com/mon-infoconcert/index.html
X-Cors-Redirect-2: 302 https://www.infoconcert.com/mon-infoconcert/connexion.html
X-Final-Url: https://www.infoconcert.com/mon-infoconcert/connexion.html
X-Request-Url: https://www.infoconcert.com/mon-infoconcert/connexion.html
So i think it's my proxy who doesn't forward the cookie that he gets.
If you need more details just ask.
Thanks you very much for your help
I'm trying to make a GET query using Fetch but I'm getting an error 404 when passing the Authorization.
I don't know why this error happens because the server responds well when I use a tool like Postman.
Authorization: Basic ...
method: GET
url: https://zammad.zonngo.com/api/v1/ticket_articles
When I use Javascript fetch API the error 404 appears.
OPTIONS https://zammad.zonngo.com/api/v1/ticket_articles 404 (Not Found)
There's my code:
const myHeaders = new Headers();
myHeaders.append('Authorization','Basic ...');
myHeaders.append('Content-Type','application/json');
fetch(URLTICKETS, {
method: 'GET',
headers: myHeaders
})
.then(response => {
console.log(response);
})
.then(error => {
console.log(error);
});
Would be nice if anyone can help me.
The GET method on the URL returns a 401 status code but the OPTIONS method actually returns a 404.
http OPTIONS https://zammad.zonngo.com/api/v1/ticket_articles
HTTP/1.1 404 Not Found
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Thu, 02 Nov 2017 01:37:59 GMT
Server: nginx/1.10.3 (Ubuntu)
Transfer-Encoding: chunked
X-Request-Id: 16f58319-2658-4b0e-824c-08ca68e8d401
X-Runtime: 0.003135
The OPTIONS is probably caused by a CORS preflight request which does not seem to be handled correctly by https://zammad.zonngo.com/.
https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
Okay, I've looked all over for this. Basically we're using $http request that ARE cross domain requests. Our server allows the domain and when a request returns 200, everything is OK. However, anytime our server returns an error, 500, 401, whatever, Angular thinks it's a CORS issue.
I debugged the response with Fiddler to verify my server IS returning a 500, yet Angular chokes on it.
Here's the request:
var params = {
url: "fakehost/example",
method: 'GET',
headers: {
"Authorization": "Basic encodedAuthExample"
}
};
$http(params).then(
function (response) { // success
},
function (error) { // error
// error.status is always 0, never includes data error msg
});
Then in the console, I will see this:
XMLHttpRequest cannot load fakehost/example. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'mylocalhost:5750' is therefore not allowed access.
Yet, in fiddler, the true response is:
HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 26 Aug 2014 12:18:17 GMT
Content-Length: 5683
{"errorId":null,"errorMessage":"Index was outside the bounds of the array.","errorDescription":"Stack trace here"}
I'm on AngularJS v1.2.16
I think I found an answer, looks like you will have to inject in your asp.net pipeline the correct CORS headers, as mentioned here.
I am trying to create a simple WebSocket connection in JavaScript against my Rails app. I get the following:
WebSocket connection to 'ws://localhost:4000/' failed: Error during WebSocket handshake: 'Sec-WebSocket-Accept' header is missing
What am I doing wrong? Here is my code:
JavaScript:
var socket = new WebSocket('ws://localhost:4000');
socket.onopen = function() {
var handshake =
"GET / HTTP/1.1\n" +
"Host: localhost\n" +
"Upgrade: websocket\n" +
"Connection: Upgrade\n" +
"Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\n" +
"Sec-WebSocket-Protocol: quote\n" +
"Sec-WebSocket-Version: 13\n" +
"Origin: http://localhost\n";
socket.send(handshake);
};
socket.onmessage = function(data) {
console.log(data);
};
Ruby:
require 'rubygems'
require 'em-websocket-server'
module QuoteService
class WebSocket < EventMachine::WebSocket::Server
def on_connect
handshake_response = "HTTP/1.1 101 Switching Protocols\n"
handshake_response << "Upgrade: websocket\n"
handshake_response << "Connection: Upgrade\n"
handshake_response << "Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\n"
handshake_response << "Sec-WebSocket-Protocol: quote\n"
send_message(handshake_response)
end
def on_receive(data)
puts 'RECEIVED: ' + data
end
end
end
EventMachine.run do
print 'Starting WebSocket server...'
EventMachine.start_server '0.0.0.0', 4000, QuoteService::WebSocket
puts 'running'
end
The handshake headers are per Wikipedia.
I think that once the connection is open the request and response have already occurred, so sending headers at that point is too late. In addition, headers have to end with a blank line, which you omitted.
According to the demos, you don't even have to set headers in the client or the server--the ruby module automatically takes care of the headers on the server side, and html5 automatically takes care of the headers on the client side. I think this should work:
require "em-websocket-server"
class EchoServer < EM::WebSocket::Server
def on_connect
EM::WebSocket::Log.debug "Connected"
puts "I felt a connection."
end
def on_receive msg
puts "RECEIVED: #{msg}"
send_message msg
end
end
EM.run do
myhost = "0.0.0.0"
myport = 8000
puts "Starting WebSocket server. Listening on port #{myport}..."
EM.start_server myhost, myport, EchoServer
end
html file:
<!DOCTYPE html> <html> <head><title>Test</title>
<script type="text/javascript">
var myWebSocket = new WebSocket("ws://localhost:8000");
myWebSocket.onopen = function(evt) {
console.log("Connection open. Sending message...");
myWebSocket.send("Hello WebSockets!"); };
myWebSocket.onmessage = function(evt) {
console.log(evt.data);
myWebSocket.close(); };
myWebSocket.onclose = function(evt) {
console.log("Connection closed."); };
myWebSocket.onerror = function(err) {
alert(err.name + " => " + err.message); } </script>
</head> <body> <div>Hello</div> </body> </html>
And it does work in Safari 5.1.9 (which is an older browser): I see the expected output on both the server and the client. However, the code does not work in Firefox 21: I get the error message...
Firefox can't establish a connection to the server at ws://localhost:8000/.
var myWebSocket = new WebSocket("ws://localhost:8000");
I notice that in both Firebug and Safari Developer Tools, the server does not send a Sec-WebSocket-Accept header:
Response Headers
Connection Upgrade
Upgrade WebSocket
WebSocket-Location ws://localhost:8000/
WebSocket-Origin null
Request Headers
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Cache-Control no-cache
Connection keep-alive, Upgrade
DNT 1
Host localhost:8000
Origin null
Pragma no-cache
Sec-WebSocket-Key r9xT+ywe533EHF09wxelkg==
Sec-WebSocket-Version 13
Upgrade websocket
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:21.0) Gecko/20100101 Firefox/21.0
Nothing I tried would make the code work in Firefox 21.0. To check whether Firefox 21.0 even supports websockets, I went to:
http://www.websocket.org/echo.html
and it said my browser does support websockets.
Is there any reason you have to use the em-websocket-server module? The last modification for that module on github was three years ago. And whenever you see require rubygems in ruby code, that should alert you that the code is old. I tried the newer em-websocket module, and I was able to successfully transfer data back and forth using websockets on both Firefox 21.0 and Safari 5.1.9:
require 'em-websocket'
myhost = "0.0.0.0"
myport = 8000
EM.run {
puts "Listening on port #{myport}..."
EM::WebSocket.run(:host => myhost, :port => myport, :debug => false) do |ws|
ws.onopen do |handshake|
path = handshake.path
query_str = handshake.query
origin = handshake.origin
puts "WebSocket opened:"
puts "\t path \t\t -> #{path}"
puts "\t query_str \t -> #{query_str}"
puts "\t origin \t -> #{origin}"
end
ws.onmessage { |msg|
ws.send "Pong: #{msg}"
}
ws.onclose {
puts "WebSocket closed"
}
ws.onerror { |e|
puts "Error: #{e.message}"
}
end
}
Same client side code. Now the response headers include Sec-WebSocket-Accept:
Response Headers
Connection Upgrade
Sec-WebSocket-Accept LyIm6d+kAAqkcTR744tVK9HMepY=
Upgrade websocket
Request Headers
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Cache-Control no-cache
Connection keep-alive, Upgrade
DNT 1
Host localhost:8000
Origin null
Pragma no-cache
Sec-WebSocket-Key pbK8lFHQAF+arl9tFvHn/Q==
Sec-WebSocket-Version 13
Upgrade websocket
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:21.0) Gecko/20100101 Firefox/21.0
In your code, I don't think you are setting any headers. Instead, you are just sending messages back and forth that happen to contain characters that look like headers. Apparently, your browser requires the Sec-WebSocket-Accept header in the response before it will allow the connection, and when the em-websocket-server module fails to set that header in the response, your browser refuses the connection.
The relevant source code for em-websockets-server looks like this:
module EM
module WebSocket
module Protocol
module Version76
# generate protocol 76 compatible response headers
def response
response = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
response << "Upgrade: WebSocket\r\n"
response << "Connection: Upgrade\r\n"
response << "Sec-WebSocket-Origin: #{origin}\r\n"
response << "Sec-WebSocket-Location: #{scheme}://#{host}#{path}\r\n"
if protocol
response << "Sec-WebSocket-Protocol: #{protocol}\r\n"
end
response << "\r\n"
response << Digest::MD5.digest(keyset)
response
end
As you can see, it doesn't set the Sec-WebSocket-Accept header. That code is in a module called Version76, and searching google for websockets version 76 yields an obsolete protocol(which contains an example of a request and response):
https://datatracker.ietf.org/doc/html/draft-hixie-thewebsocketprotocol-76
Here is the current websockets protocol(which also contains an example of a request and response):
https://www.rfc-editor.org/rfc/rfc6455
Conclusion: em-websockets-server is obsolete.
I'm writing my own script to connect to a websocket server with JavaScript using the WebSocket API. I'm having problems with the connection closing straight away.
Here's the client side script:
var host = 'ws://localhost:8080';
try
{
debug.add('Connection request submitted for ' + host);
socket = new WebSocket(host);
debug.readyStateListener();
debug.add('Socket request started');
socket.onopen = function()
{
debug.add('Connection opened');
}
socket.onmessage = function(message)
{
debug.add('data received ' + message.data);
}
socket.onclose = function()
{
debug.add('Connection closed');
}
}
catch(e)
{
debug.add('WebSockets error ' + e.toString() );
}
This is the debug I receive:
Connection request submitted for ws://localhost:8080
socket readyState change to 0
Socket request started
socket readyState change to 3
Connection closed
The debug.readyStateListener() polls socket.readyState for changes. What's happening is it changes to 0 meaning the connection is opening, then straight away changes to 3 that the connection has been closed.
The server receives the connection fine but the connection is then closed straight away by the client.
I've tried it in Opera 11 with WebSockets enabled and in the latest version of Chrome. Both time's I get the same result.
I can communicate perfectly with the server through a raw connection, or simply by visiting http://localhost:8080/ in my browser this is the result:
GET / HTTP/1.1
User-Agent: Opera/9.80 (Windows NT 6.1; U; IBM EVV/3.0/EAK01AG9/LE; en) Presto/2.9.168 Version/11.51
Host: localhost:8080
Accept: application/xhtml+voice+xml;version=1.2, application/x-xhtml+voice+xml;version=1.2, text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: nl-NL,nl;q=0.9,en;q=0.8
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
The connection also stays alive without any flaws by sending a request through http until I end it.
Going through the JavaScript WebSocket API the server receives this request:
GET / HTTP/1.1
Host: localhost:8080
Origin: http://localhost
Upgrade: WebSocket
Sec-WebSocket-key1: L58(b Q]'9 4 9\ 0 *+ 6 a4
Connection: Upgrade
Sec-WebSocket-Key2: \+ 1 5d/9541840N*4
My last guess would be Connection: upgrade or Upgrade: WebSocket not being supported properly by the client. To me it would be more logical to receive Connection: keep-alive but I have no idea how to reslove this.