Server Sent Event connection not staying open with Apache/Thin/Sinatra - apache

I'm trying to setup basic server side event ability using Apache/Thin/Sinatra. Everything works as exepcted when I run the Thin server directly. When I run the Thin server through Apache using the RackBaseURI config setting, everything still works, but the connection is not persisted. It goes through a cycle of opening, writing some data to the browser and immediately closing. Seems like an Apache configuration issue?
I've gone through the Apache config and don't see anything that seems like it would prevent an open connection. Because I'm not sure where the error is, I don't want to post endless configuration data, so I can include more if I'm missing something...
sinatra (1.3.4),
thin (1.5.0),
Apache/2.2.22 (Ubuntu),
ruby 1.8.7
The JavaScript...
$j(function(){
console.log("Starting...");
var es = new EventSource("/stream_event");
es.addEventListener('message', function(e) {
console.log(e.data);
}, false);
es.addEventListener('open', function(e) {
console.log("Connection Open");
}, false);
es.addEventListener('error', function(e) {
console.log("error = " + e.eventPhase)
if (e.eventPhase == EventSource.CLOSED) {
console.log("Connection Closed");
}
}, false);
}
The server side sinatra/ruby..
set :server, :thin
connections = []
get '/' do
content_type 'text/event-stream'
stream(:keep_open) { |out|
connections << out
out << "data: hello\n\n"
}
end
get '/post_message' do
connections.each { |out| out << params[:message] << "\n" }
"message sent"
end
EDIT:
And here's the output I see in the browser console ...
Connection Open
hello
error = 2
Connection Closed
Connection Open
hello
error = 2
Connection Closed
Connection Open
hello
error = 2
Connection Closed
Connection Open
hello
error = 2
Connection Closed
Connection Open
hello
error = 2
Connection Closed

Seems to be something related to the RackBaseURI configuration setting. I was able to get things working by removing that attribute and directing the traffic to my Sinatra app using Apache's proxy abilities...
ProxyPass /stream_event http://127.0.0.1:9292
ProxyPassReverse /stream_event http://127.0.0.1:9292
The primary disadvantage here is that I need to startup and monitor the running Sinatra app manually using some other process.

Related

Blazor WebAssembly MQTT over websockets not working

I'm trying to implement an mqtt over websocket client subscriber in Blazor using Paho. The problem is it insists on using wss instead of ws and throws an ERR_SSL_PROTOCOL_ERROR error upon connection.
Here's a simplified code block:
var mqtt;
var host = "api.mydomainexample.com";
var port = 1884;
function onConnect(){
console.log("connected ! Now listening for messages ..");
mqtt.subscribe("someTopic");
}
function onFailure(message){
console.log("connection to host failed: " + message);
}
function onMessageArrived(msg){
var message = "Message received on topic '"+ msg.destinationName +"': "+ msg.payloadString;
console.log(message);
}
function mqttConnect() {
console.log("connecting to " + host + " ..");
mqtt = new Paho.MQTT.Client(host, port, clientid);
var options = {
timeout: 3,
onSuccess: onConnect,
onFailure: onFailure,
useSSL: false
};
mqtt.onMessageArrived = onMessageArrived;
mqtt.connect(options);
}
I copied this code into an html page created in notepad, called the function from the html body and ran the file in browser. It worked and subscribed well.
Also I added useSSL: false in the connection options although I didnt have it before but still didnt work.
here's the error I'm having from console:
WebSocket connection to 'wss://api.mydomainexample:1884/mqtt' failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR
I also changed my projects launch settings so that it launches as http and not https because based on this answer, I cannot use a ws from a page loaded through https.
Any ideas ? Can't I just connect to a websocket without certificate in blazor?
Ok it turns out that when creating the blazor application, there is an option to 'configure on https' where this option causes requests redirection from http to https and consequently asks for secure wss instead of ws.
Hope this helps someone!

WebSocket connection to 'wss://tracker.btorrent.xyz/' failed: Error during WebSocket handshake: Unexpected response code: 522 {webtorrent}

Hello fellow homo sapiens, I seem to have reached a dead end here and would require your assistance. I am using webtorrent-hybrid to display a torrent, however when I use client.add to download my torrent, I get this error,
ICE failed, add a TURN server and see about:webrtc for more details 10
Firefox can’t establish a connection to the server at wss://tracker.btorrent.xyz/.
and this is the code if you are curious,
client.add(torrentId, function (torrent) {
var file = torrent.files.find(function (file) {
return file.name.endsWith('.mp4')
})
var info = torrent.ready
console.log(info)
file.appendTo('body')
console.log(file)
// Display the file by adding it to the DOM. Supports video, audio, image, etc. files
})
I would thankful if you could assist me in my problem.

BrowserMob Proxy and Webdriverio minimal, empty HAR file

I was wondering if anyone has any idea as to what could be the problem or additional steps I could take in resolving the following issue.
I have a requirement to capture the network traffic so I can write some selenium tests verifying certain request headers.
The problem is when trying to use Webdriver.io + Browsermob proxy the HAR file created contains very minimal information.
I have tried using the C# bindings of the proxy and that resulted in the same issue as the Javascript ones. The only bindings that I got to work which returned data in the HAR file were the Java ones. There's a business requirement though that I must use Webdriver.io to implement this.
I have checked a number of other Questions and Answers from stack overflow but to no avail. Most have not been answered and the ones that have been have not worked for me just yet.
The code I am currently running is very similar to this one with the difference being the URL I'm trying to get the information from.
The difference between my Java code which worked and the Javascript and C# ones was that the Java one sets up the proxy programmatically whereas the other two expect the proxy to be already running and just connect to it.
Even with that in mind, when I start the C# or Javascript tests the proxy registers the new connection. The selenium server also starts up fine. Both cleanup with no issues according to their respective consoles once the tests are finished.
Are there any other ways to potentially debug this? Or even alternatives to capture the network traffic (Must work cross browser - already have a solution which works for chrome using chrome-remote-interface but we saw suggestions to use browsermob proxy for cross browser network capture).
Thanks for your time
Something I forgot to mention which is pretty important. Below is the npm package I am using for the browsermob-proxy :
https://www.npmjs.com/package/browsermob-proxy
Okay so, I figured out why I wasn't getting any data. I hope this saves others some time and hassle.
The problem is the way browsermob proxy handles localhost. I instead switched the proxy to use my IPV4 address and it started capturing all the HAR data.
See the code below:
//BroswerMobProxy + webdriver.io
//npm package used https://www.npmjs.com/package/browsermob-proxy
var webdriverio = require('webdriverio');
//proxy settings, host is IPV4 address
var Proxy = require('browsermob-proxy').Proxy
, fs = require('fs')
, proxy = new Proxy({host: 'Put IPV4 Address Here', proxyPort: 8081 , selHost: 'Put IPV4 Address Here'});
;
//convenience method that
proxy.cbHAR({captureHeaders: true, captureContent: true, captureBinaryContent: true }, doSeleniumStuff, function(err, data) {
if (err) {
console.error('ERR: ' + err);
} else {
/* Make sure har results are in the correct shape
* for any further processing
*/
var harResultsString = JSON.stringify(data);
var harResultsJson = JSON.parse(harResultsString);
//Write HAR file
fs.writeFileSync('DemoFile.json', harResultsJson, 'utf8');
//Print to console
console.log(harResultsJson);
}
});
//webdriver.io options
const opts = {
desiredCapabilities:{
browserName: 'chrome',
proxy: {
proxyType: 'MANUAL',
httpProxy: String(proxy.host)+":"+String(proxy.proxyPort),
sslProxy: String(proxy.host)+":"+String(proxy.proxyPort),
socksProxy:String(proxy.host)+":"+String(proxy.proxyPort),
socksVersion: 4,
autodetect: false
},
acceptSslCerts: true,
acceptInsecureCerts: true
},
host: 'Put IPV4 Address here',
port: 4444,
protocol: 'http',
coloredLogs: true,
proxy: 'http://'+String(proxy.host)+":"+String(proxy.proxyPort),
}
function doSeleniumStuff(proxy, cb) {
var browser = webdriverio.remote(opts);
// console.log(browser.options);
browser
.init()
.url('http://yahoo.com.au')
.getTitle().then(function(title) {
console.log('Title was: ' + title);
})
.end().then(cb).catch(e => console.log(e));
}

Unexpected server response (0) while retrieving pdf

We are specifically getting this error when using Amazon ec2 instance. Configuration on aws instance is Tomcat 7, Ubuntu 16.04 and memory is 8gb. It occurs when the user tries to view pdf file. In our application, we are having one functionality where the user can only view PDF file onto browser, but won't be able to download it. PDF file is on the same server. We are using cors minimal configuration. We have tried it locally with Ubuntu and it is working fine.
Code snippet:
var fileSplitContent = fileName.split(".");
if ($('#viewImageOnlyForm')[0] != undefined && $('#viewPdfOnlyForm')[0] != undefined) {
if (fileSplitContent[fileSplitContent.length - 1].toLowerCase() != "pdf") {
$('#imageSource').val(requestURL + $.param(inputData));
$('#viewImageOnlyForm').submit();
} else {
var requestURL = "rest/file/getCapitalRaiseFile?";
$('#pdFSource').val(requestURL + $.param(inputData));
$('#viewPdfOnlyForm').submit();
}
} else {
// pop up download attachment dialog box
downloadIFrame.attr("src", requestURL + $.param(inputData));
}
}
Jan 04, 2017 5:07:31 AM org.glassfish.jersey.server.ServerRuntime$Responder writeResponse
SEVERE: An I/O error has occurred while writing a response message entity to the container output stream.
org.glassfish.jersey.server.internal.process.MappableException: org.apache.catalina.connector.ClientAbortException: java.net.SocketException: Connection reset
Caused by: org.apache.catalina.connector.ClientAbortException: java.net.SocketException: Broken pipe (Write failed)
Depending where you access the document this can be because of you have a download manager installed on your browser. This sometimes causes problems - maybe take a look at your extensions. You should try by disabling downloader manager extension in your browser.

WebSockets : Getting Safari to work with pywebsockets Apache extension

I am trying to get WebSocket running on an Apache server with the help of pywebsocket.
The server is now setup and I am able to make a Websocket connection through Chrome. However, when I try to make a connection through Safari I am getting a "Unexpected response code: 404" and it doesn't appear that the WebSocket connection is able to be established with the server.
Any pointers here would be appreciated. Below is the client side JS code I am invoking to make a connection and the safari header tags vs the Chrome header tags.
function connect() {
if ('WebSocket' in window) {
socket = new WebSocket("ws://localhost/mystream");
} else if ('MozWebSocket' in window) {
socket = new MozWebSocket("ws://localhost/mystream");
} else {
return;
}
socket.onopen = function () {
showResult('Opened');
};
socket.onmessage = function (event) {
showResult(event.data);
};
socket.onerror = function () {
showResult('Error in connection');
};
socket.onclose = function (event) {
var logMessage = 'Closed (';
if ((arguments.length == 1) && ('CloseEvent' in window) && (event instanceof CloseEvent)) {
logMessage += 'wasClean = ' + event.wasClean;
if ('code' in event) {
logMessage += ', code = ' + event.code;
}
if ('reason' in event) {
logMessage += ', reason = ' + event.reason;
}
} else {
logMessage += 'CloseEvent is not available';
}
showResult(logMessage + ')');
};
showResult('Successfully Connected ');
}
Safari Headers :
Origin: http://192.168.1.8
Sec-WebSocket-Key1: 26 ~ 5 75G3 36< 0 U8T
Connection: Upgrade
Host: localhost
Sec-WebSocket-Key2: 1<A 9 4 4l865P5/6L5
Upgrade: WebSocket
Chrome Headers :
Connection:Upgrade
Host:localhost
Origin:http://192.168.1.8
Sec-WebSocket-Key:IAkX9XGWsCZHPQepzYjwxA==
Sec-WebSocket-Version:13
Upgrade:websocket
(Key3):00:00:00:00:00:00:00:00
Managed to get it working now. Safari (5.1) and mobile safari both require the Hixie-75 flag which has experimental support in pywebsockets. The issue was with the entry in the apache conf file, the entry is supposed to be in all lowercase (i.e on) but the sample entry had it in CamelCase (On) . Reverting to all lowercase has solved the issue.
Updated
Those Safari headers are for an older revision of the protocol: Hixie-76. Hixie-76 is a lot less friendly to integration with web servers because there is special data (key3) sent after the headers. I suspect Safari will be updated to the newer version of the protocol (HyBi) in the next release or two.
The HyBi-76 handshake happens in handshake/hybi00.py You might try adding some debug to try and figure out where it is failing. In particular make sure that _get_challenge is actually getting the final 8 bytes (key3) of the challenge that are sent after the headers (this is the part that makes it complicated to handle Hixie-76 in a web server).