Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The current implementation favors port 843 for socket policy files #49

Closed
jvshahid opened this issue Jan 8, 2011 · 18 comments
Closed

Comments

@jvshahid
Copy link
Contributor

jvshahid commented Jan 8, 2011

According to this article http://www.adobe.com/devnet/flashplayer/articles/fplayer9_security.html#_Configuring_Socket_Policy:

...that you need to provide more explicit guidance to Flash Player from ActionScript by calling loadPolicyFile to indicate the location of a socket policy file. When you call loadPolicyFile rather than allowing Flash Player to check locations by default, Flash Player will wait as long as necessary for a response from a socket policy file server, rather than timing out after 3 seconds. This may help your application's reliability in marginal network conditions. It can thus be helpful to call loadPolicyFile even for a default socket policy file location—simply to request that Flash Player wait patiently for the socket policy file server to respond.

It looks like asking flash to load the policy file from port 843 (WebSocketMain.as:53) will make it favor that port over the destination port. This will cause a problem if port 843 is blocked by a firewall. I noticed that flash will try port 843 three time and it waits the first time for 3 sec then it waits for 6 sec for the second and third retries (On Windows it's 3, 6 and 12 seconds resp.) That's about 15-21 seconds between the time the user loads the page and a connection being established.

I'm proposing to remove that line (WebSocketMain.as:53) since flash will try port 843 anyway. Without that line, it'll try port 843 only once with a timeout of 3 seconds. This is more acceptable than the 15 seconds delay in my opinion.

Thanks,

@gimite
Copy link
Owner

gimite commented Jan 9, 2011

Yeah it makes some sense. But I also have some reason to prefer the current way:

  • If we don't call loadPolicyFile() and socket policy file is provided only on port 843 (not on the connection port), connection fails if the server or network is slow and client cannot receive socket policy file in 3 sec.
  • If port 843 is not blocked, providing socket policy file on port 843 is the most efficient way, because anyway Flash Player tries port 843 first.

So the preference depends on how often port 843 is blocked. I don't have clear idea. I believe it's somewhat common to block everything and allow only connection to HTTP proxy, but in that case, anyway Flash socket is not available.

One option is to provide API to set policy file URL in JavaScript.

@jvshahid
Copy link
Contributor Author

jvshahid commented Jan 9, 2011

Yes, I was thinking about setting the policy file url through a method call in the API. That will make the library very flexible. Regarding port 843 I believe it's blocked in most corporate networks, at least this is the case for inbound traffic to my company's network. This is actually why I started investigating the reasons behind having higher load time in Firefox and IE than in Chrome.

@gimite
Copy link
Owner

gimite commented Jan 11, 2011

Now you can load policy file from other port by e.g.

WebSocket.loadFlashPolicyFile("xmlsocket://example.com:80");

@Vagabond
Copy link

What if you WANT it to fail in 3 seconds when 843 is blocked? I guess now I know this is why things are taking forever to time out I can just comment out the line that's doing the explicit loadPolicyFile, but it'd be nice if I could force it to fail-fast without a hack.

@jvshahid
Copy link
Contributor Author

Commits 0d8d903d8b3a2e0ce99a and 6640d9d806972ea1720a provide a way to override the default port. Take a look at the commit messages.

@Vagabond
Copy link

I have, but it doesn't address NOT setting the loadPolicyFile at all so that flash "fails fast" when 843 is blocked. I don't want to change the default port, I want to not set a port at all and fail fast if the port is blocked.

I commented out the call to loadPolicyFile for the default port, and it worked. I'm just going to do that in a local change.

@gimite
Copy link
Owner

gimite commented Jan 12, 2011

Did you try this?:

WebSocket.loadFlashPolicyFile("xmlsocket://example.com:80");

(You should replace the port number with your Web Socket port)

I guess not calling Security.loadPolicyFile() is equivalent to above, because it loads policy file from the port you are connecting to by default. Note that in both cases it first tries port 843 and gives up in 3 seconds.

@jvshahid
Copy link
Contributor Author

@Vagabond, I don't understand what you're trying to do here. If you're not changing the default port then I'm assuming you're policy file will be on port 843 (correct me if I'm wrong). If so why do you care about failing fast, the flash websocket implementation won't work anyway.

@Vagabond
Copy link

"When you call loadPolicyFile rather than allowing Flash Player to check locations by default, Flash Player will wait as long as necessary for a response from a socket policy file server, rather than timing out after 3 seconds."

Doesn't this mean that NOT calling loadPolicyFile at all will change the timeout behavior or am I reading it wrong?

@jvshahid
Copy link
Contributor Author

That's partially correct, flash won't wait as necessary. As it's pointed out in the issue, it will timeout after 15-21 sec depending on the flash version and the OS. My question was, what difference does it make in your app. In my case the policy file is served on the destination port so making flash timeout after 15 seconds wasn't acceptable. I'd like to hear your answer, just present your case.

@Vagabond
Copy link

I run the policy server on the default port. The policy server runs on an appliance device which may or may not be firewalled, I have no way to tell or mandate whether is it or not.

I have a websocket server that falls back to long-polling if websockets don't work. If websockets aren't native, I want to try flash websockets and if those don't work I fall back to long-polling. I need this to be as fast as possible, the 15 second timeout is unacceptable. That's why I want to avoid calling loadPolicyFile at all, so it does the 3 second timeout.

@gimite
Copy link
Owner

gimite commented Jan 12, 2011

I understand your situation. But Flash Player doesn't give option to "try port 843 for 3 seconds and then give up". As I mentioned in earlier post, the default behavior (without call to Security.loadPolicyFile) is:

  • Try port 843 for 3 seconds, then try loading policy file from the port you are connecting to (i.e. in this case the Web Socket port)

This worked for you probably because your Web Socket server doesn't provide socket policy file (so when it fails to connect to port 843, both attempts above fail).

And again, equivalence to default behavior above should be done by:

WebSocket.loadFlashPolicyFile("xmlsocket://example.com:80");

FYI Another way to achieve your purpose (to timeout quickly) is to timeout manually i.e. use setTimeout() to fall back to long poll if ws.onopen is not called in 3 seconds.

@ondrejmirtes
Copy link

I'm having a problem with setting a custom port for the flash policy file. I suppose that all ports beside 80 and 443 could be blocked by corporate firewalls, so I need to setup the policy file on either of them. Also, the policy file needs to be on the same domain where the page HTML is loaded from, otherwise Flash does not make the request.

But that's a deadlock situation - ports 80 and 443 are used by the HTTP server to serve the page, so I can't use them for serving the policy file. Serving it from a different domain does not work.

What can I do to/what technology can I use to resolve this situation?

@gimite
Copy link
Owner

gimite commented Aug 2, 2013

If you can modify the HTTP server, one idea is to modify the server to handle both HTTP request and socket policy file request. You can easily distinguish these two requests. Or maybe write a thin wrapper of existing HTTP server (e.g. Apache) which also handles socket policy file.

@stephenbunch
Copy link

Hey @gimite, I'm having trouble getting this to work.

I've got a Node server running on Heroku. The Heroku endpoint is HTTPS, but Node is listening on an HTTP port which the Heroku environment provided. So I have a few questions:

  1. Is it possible to load a policy file over HTTPS?
  2. Why is everyone so focused on creating a lightweight net server on 843 if all Flash needs to do is load an xml file from the domain in question?
  3. What exactly does the xmlsocket scheme mean, and why can't I put http or https in there?
  4. Is wss supported?

I've tried the following combinations, but I can't get any of them to work. Do either of these methods look right? I've also tried putting a crossdomain.xml file at the root, although it seems like I should be able to name this file whatever I want.

WebSocket.loadFlashPolicyFile("xmlsocket://example.com:443");
WebSocket.loadFlashPolicyFile("xmlsocket://example.com:443/crossdomain.xml");
WebSocket.loadFlashPolicyFile("example.com:443/crossdomain.xml");
WebSocket.loadFlashPolicyFile("example.com/crossdomain.xml");
WebSocket.loadFlashPolicyFile("https://example.com/crossdomain.xml");

Thanks!

@gimite
Copy link
Owner

gimite commented Nov 18, 2015

Does Heroku support listening on a port with a protocol other than HTTP or HTTPS? If not, I don't think you can make web-socket-js work on Heroku, unfortunately.

Is it possible to load a policy file over HTTPS?

No.

Why is everyone so focused on creating a lightweight net server on 843 if all Flash needs to do is load an xml file from the domain in question?

Because it's its own protocol, not HTTP.

What exactly does the xmlsocket scheme mean, and why can't I put http or https in there?

That's the name of its own protocol. Only xmlsocket is allowed. http and https are not supported. That's the spec of Flash.

Is wss supported?

Yes.

@stephenbunch
Copy link

Ugh.. okay. Makes sense. So theoretically, in order to use web-socket-js on Heroku, I could spin up my own machine on AWS or Digital Ocean and run a small Node server that talks the xmlsocket protocol and serves the insecure version of the SWF object over HTTP. That should work, right?

@gimite
Copy link
Owner

gimite commented Nov 19, 2015

I believe you need to host the web socket server in AWS too because the socket policy file and the web socket server must be in the same host. Socket policy file grants flash contents to access to the host where the policy file is located.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants