In a standalone XUL app, I'd like to catch the server not found exception. I've tried by checking state in onStateChange event of the nsIWebProgressListener, but this doesn't seem to work. My onStateChange event implementation is as shown below. I'm making the assumption that if STATE_START or STATE_STOP is not returning a valid value, then there's something wrong with page loading, and displays the error message to the user.
onStateChange: function(aProgress, aRequest, aFlag, aStatus) {
const STATE_START = Components.interfaces.nsIWebProgressListener.STATE_START;
const STATE_STOP = Components.interfaces.nsIWebProgressListener.STATE_STOP;
if(aFlag & STATE_START) {
document.getElementById("progressBar").hidden = false;
}
if(aFlag & STATE_STOP) {
setTimeout(function() { document.getElementById("progressBar").hidden = true; }, 2000);
}
if(aFlag & (!STATE_START | !STATE_STOP)) {
alert("Your connection seems to be down. Please confirm with your system admin.");
}
return 0;
},
Can someone kindly advice me on what I'm doing wrong? Thanks in advance.
The onStateChange parameter indicating whether there was a connection error is aStatus. For example you could use Components.isSuccessCode:
if ((aFlag & STATE_STOP) && !Components.isSuccessCode(aStatus))
{
alert("Your connection seems to be down. Please confirm with your system admin.");
}
You could also compare aStatus with Components.results.NS_ERROR_UNKNOWN_HOST which corresponds to the "Server not found" error. If the connection is down there could be a number of other errors however, e.g. NS_ERROR_CONNECTION_REFUSED (connection failed), NS_ERROR_UNKNOWN_PROXY_HOST (proxy not found), NS_ERROR_OFFLINE (attempt to connect while in offline state). You can find the complete list of network error codes in nsNetError.h.
Related
Recently a post was featured in Hacker News about websites abusing WebSockets to find open ports on the client's machine.
The post does not go into any details, so I decided give it a try.
I opened a web server on port 8080 and tried running this script in Chrome's console:
function test(port) {
try {
var start = performance.now();
var socket = new WebSocket('ws://localhost:' + port);
socket.onerror = function (event) {
console.log('error', performance.now() - start, event);
}
socket.addEventListener('close', function(event) {
console.log('close', performance.now() - start, event);
})
socket.addEventListener('open', function (event) {
console.log('open', performance.now() - start, event);
socket.send('Hello Server!');
});
socket.addEventListener('message', function (event) {
console.log('message ', performance.now() - start, event);
});
} catch(ex) {
console.log(ex)
}
}
Indeed Chrome logs different a error message (ERR_CONNECTION_REFUSED) when I try to connect to a port that is not open:
test(8081)
VM1886:3 WebSocket connection to 'ws://127.0.0.1:8081/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
And when I try to connect to a port that is open but is not listening to WebSockets (Unexpected response code: 200):
test(8080)
WebSocket connection to 'ws://127.0.0.1:8080/' failed: Error during WebSocket handshake: Unexpected response code: 200
But I can't find any way to access and read these errors in JavaScript.
Control flow does not reach the catch clause catch(ex) { console.log(ex) } and the event objects that Chrome passes to socket.onerror do not seem to be any different whether the port is open or not.
Timing attacks also don't seem to be helping at least in Chrome. Delta time between onerror and new Socket() creation seems to increase after calling test(...) a few times.
So is there actually a way for a web page to determine if a port is open on my computer?
The presentation slides linked to below show it was well known in 2016 and lack of a timing difference in your tests show mitigations may have been applied upstream.
https://datatracker.ietf.org/meeting/96/materials/slides-96-saag-1/
It might only work on windows:
https://blog.avast.com/why-is-ebay-port-scanning-my-computer-avast
I have a Flex app that connects to a JBoss/MS-SQL back-end. Some of our customers have a proxy server in front of their JBoss with a timeout of 90 seconds. In our application there are searches that can take up to 2-3 minutes for complex criteria. Since the proxy isn't smart enough to recognize AMF's keep alive pings for what they are the proxy sends a 503 to the client, which in Flex land becomes a "Channel Call Failed" event. In searching SO and other places, this seems to be a common problem. We can't do anything about the proxy or lengthen the timeout, the application needs to handle it.
Of course the back-end continues to process and eventually ships the results to the client. But the user gets an ugly error message and assumes the app is broke.
The solution I have settled on is to consume the CCF error and have the client continue to wait. I have managed the first part, but I can't figure out how to keep the client's handlers active to receive the data (and/or consume another timeout if necessary).
Current error handler:
private function handleSearchError(event : FaultEvent) : void {
if (event.fault.faultCode == "Channel.Call.Failed") {
event.stopImmediatePropagation(); // doesn't seem to help
return;
}
if (searchProgress != null) {
PopUpManager.removePopUp(searchProgress);
searchProgress = null;
}
etc...
}
This is the setup:
<mx:Button id="btnSearch" label="
{resourceManager.getString('recon_perspective',
'ReconPerspective.ReconView.search')}" icon="{iconSearch}"
click="handleSearch()" includeIn="search, default"/>
And:
<mx:method name="search" result="event.token.resultHandler(event);"
fault="handleSearchError(event);"/>
Kicking off the call:
var token : AsyncToken = null;
token = sMSrv.search(searchType.toString(), getSearchMode(), criteria,
smartMatchParent.isArchiveMode);
searchProgress = LoadProgress(PopUpManager.createPopUp
(FlexGlobals.topLevelApplication as DisplayObject, LoadProgress, true));
searchProgress.title = resourceManager.getString('matching', 'smartmatch.loading.trans');
searchProgress.token = token;
searchProgress.showCancelButton = true;
PopUpManager.centerPopUp(searchProgress);
token.resultHandler = handleSearchResults;
token.cancelSearch = false;
So my question is how do I keep handleSearch and handleSearchError alive to consume the events from the server?
I verified that the data comes back from the server using WebDeveloper in the browser to watch the network traffic and if you cause the app to refresh that screen, the data gets displayed.
I'm very in experienced but would this help?
private function handleSearchError(event : FaultEvent) : void {
if (event.fault.faultCode == "Channel.Call.Failed") {
event.stopImmediatePropagation(); // doesn't seem to help
if(event.isImmediatePropagationStopped(true)) {
//After stopped do something here?
}
return;
}
if (searchProgress != null) {
PopUpManager.removePopUp(searchProgress);
searchProgress = null;
}
etc...
}
The script below works fine in FireFox and Chrome, but in Internet Explorer 11, it always fails (with POSITION_UNAVAILABLE).
I have set the browser to allow requests for position, and I agree to the prompt the browser presents me when requesting permission.
I'm almost certain that this worked fine a few months ago when I was last experimenting with it. What could I be missing as far as IE's settings?
<script type="text/javascript">
$(document).ready(function () {
if (Modernizr.geolocation)
{
navigator.geolocation.getCurrentPosition(positionSuccess, positionError, { enableHighAccuracy: true, maximumAge: 60000, timeout: 10000 })
}
else
{
$("#GeoError").html("Unable to retrieve current position.")
}
});
function positionSuccess(position)
{
$("#Latitude").val(position.coords.latitude);
$("#Longitude").val(position.coords.longitude);
}
function positionError(error)
{
var message = "";
// Check for known errors
switch (error.code) {
case error.PERMISSION_DENIED:
message = "This website does not have your permission to use the Geolocation API";
break;
case error.POSITION_UNAVAILABLE:
message = "Your current position could not be determined.";
break;
case error.PERMISSION_DENIED_TIMEOUT:
message = "Your current position could not be determined within the specified timeout period.";
break;
}
// If it's an unknown error, build a message that includes
// information that helps identify the situation, so that
// the error handler can be updated.
if (message == "") {
var strErrorCode = error.code.toString();
message = "Your position could not be determined due to " +
"an unknown error (Code: " + strErrorCode + ").";
}
$("#GeoError").html(message)
}
</script>
Also, I get the same failure in IE11 when I try http://html5demos.com/geo, where both FireFox and Chrome work fine.
Does you enable the Location Service?
I have had the same issue, it worked after I enabled the Location Service in my windows 2016.
This page shows how to enable the Location Service in windows 10.
I have had the same issue in IE11 only.
I had to set enableHighAccuracy to false to get it to work. Once I did that IE worked as expected.
In Internet Options, click on the Privacy tab. Uncheck the Never allow websites to request your physical location box, hit on OK.
After making these changes, the http://html5demos.com/geo now worked for me. Initially it didn't.
aha, just discovered something.
Chrome apparently uses the WIFI access points to help finding the location.
IE11 (and edge) just falls back to the default location in your windows settings, if there is no immediate GPS signal.
I have the following piece of code for using text to speech feature in Windows Phone 8. I am using ssml, with bookmarks. But when changing any UI element in the Bookmark event called function, raises Unauthorized Exception.
private void Initialise_synthesizer()
{
this.synthesizer = new SpeechSynthesizer();
synthesizer.BookmarkReached += new TypedEventHandler<SpeechSynthesizer, SpeechBookmarkReachedEventArgs>
(BookmarkReached);
}
void BookmarkReached(object sender, SpeechBookmarkReachedEventArgs e)
{
Debugger.Log(1, "Info", e.Bookmark + " mark reached\n");
switch (e.Bookmark)
{
case "START":
cur = start;
break;
case "LINE_BREAK":
cur++;
break;
}
**error here** t1.Text = cur.ToString();
}
But on running it gives the following error
A first chance exception of type 'System.UnauthorizedAccessException' occurred in System.Windows.ni.dll
An exception of type 'System.UnauthorizedAccessException' occurred in System.Windows.ni.dll and wasn't handled before a managed/native boundary
Invalid cross-thread access.
Any idea how to fix this error, or any work around.
Just got the answer.
Since the synthesizer.SpeakSsmlAsync() is an async function, to perform UI operations Dispatcher has to be used, something like this -
Dispatcher.BeginInvoke(() =>
t1.Text = cur.ToString());
It's pretty much unrelated to the speech recognition. It seems that it's related to accessing elements which are on the UI thread from a different thread.
Try this:
Dispatcher.BeginInvoke(() =>
{
t1.Text = cur.ToString();
}
);
From AppManifest.xml turn on capability ID_CAP_SPEECH_RECOGNITION.
During the caching of my offline webapp I receive a totally valid error which is displayed in the browser console like this:
Application Cache Error event: Manifest changed during update, scheduling retry
I can add a Listener to be informed that an error has occured.
window.applicationCache.addEventListener('error', function(e){
//handle error here
}, false);
How can I get the error detail, in this case "Manifest changed during update, scheduling retry"?
You must use window.onerror. The callback can have three parameters:
Error message (string)
Url where error was raised (string)
Line number where error was raised (number)
check this for more information:
https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onerror
Still a valid issue today. In my example, my error log does not return anything. I am using IE11.
<html xmlns="http://www.w3.org/1999/xhtml" manifest="icozum.appcache">
onChecking events fires but then onError with cache status = 0 which is nocached.
window.applicationCache.onchecking = function (e) {
var doc = document.getElementById("cachestatus");
if (doc != null) {
doc.innerHTML += "Checking the cache.\n";
}
}
Then onError
window.applicationCache.onerror = function (e) {
var doc = document.getElementById("cachestatus");
if (doc != null) {
doc.innerHTML += "Cache error occurred." + applicationCache.status.toString() + "\n";
console.log(e);
console.log("test");
}
}
The output on the screen is
Checking the cache.
Cache error occurred.0
There is no detail info about the error in onError event handler. I got the real error by pressing the F12. Here is the screen shot. Is there any way to capture this much detail in onError event handler.
And finally I figured out the problem. The error is not due to missing file. The app cache file does exist, however in windows , visual studio (2013)/IIS does not recognize the extension .appcache. The following section needs to be added to the web.config file.
<system.webServer>
<staticContent>
<mimeMap fileExtension=".appcache" mimeType="text/cache-manifest"/>
</staticContent>
</system.webServer>