Skip to content
This repository

Add support for X-domain long-polling with JSONP #6

Closed
DamianEdwards opened this Issue August 01, 2011 · 15 comments

8 participants

Damian Edwards David Fowler gyf19 dsosunov Walter Poch Yvo van Beek stevozilik David E. Manske
Damian Edwards
Owner

Add support to the long-polling transport for doing cross-domain connections with JSONP.

gyf19

+

David Fowler
Owner

Are we still doing this for 0.4?

Walter Poch
wpoch commented March 01, 2012

+1

Yvo van Beek

+1

Don't really need JSONP solution.
<add name="Access-Control-Allow-Origin" solution in web.config is fine.

However the /signalr/hubs script should be more flexible, the url /signalr shouldn't be hardcoded

David Fowler
Owner

@Zyphrax you can change it via $.connection.hub.url there isn't a good default other than the relative path and that works for 90% of the cases

stevozilik

+1

David Fowler
Owner

This was implemented as a contribution (Thanks @codeputty).

To make this work with Persistent connections:

var connection = $.connection('http://somecrossdomainurl/echo')

connection.start({ transport: 'longPolling', xdomain: true });

We may tweak the api (i.e try to autodetect so you don't need to specify longpolling) but this is the current implementation.

David Fowler davidfowl closed this April 06, 2012
stevozilik

Thanks for this! Does this mean though that xdomain only works with long polling and no other transport protocol? If so, is it technically possible for it to work with other protocols?

David Fowler
Owner

This feature is specifically about long polling. Other protocols aren't supported. You can check out CORS for an alternative to jsonp longpolling:

http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing
http://stackoverflow.com/questions/9984534/signalr-cross-domain-connections

Yvo van Beek

The CORS solution is working quite well. It becomes problematic when you have signalr on a subdomain, more than one subdomain using it and using cookies.

The specification says that you can specify multiple domains for Access-Control-Allow-Origin, but that doesn't seem to work when you have Access-Control-Allow-Credentials set to true (for cookie support).

My workaround is (in Global.asax.cs of my SignalR hubs MVC website):

/// <summary>
/// Raises when the application processes a request.
/// </summary>
protected void Application_BeginRequest(object sender, EventArgs e) {
    string origin = Request.Headers["Origin"];
    Uri uri;

    // Validate the Request origin
    if (Uri.TryCreate(origin, UriKind.Absolute, out uri) &&
        uri.Host.EndsWith(FormsAuthentication.CookieDomain)) {
        Response.AddHeader("Access-Control-Allow-Origin", uri.Scheme + "://" + uri.Authority);
        Response.AddHeader("Access-Control-Allow-Credentials", "true");
    }
}

Another nice resource for CORS:
http://enable-cors.org/

Yvo van Beek

In AspNetHandler.cs I see that you've implemented it like this:

// https://developer.mozilla.org/En/HTTP_Access_Control
string origin = context.Request.Headers["Origin"];
if (!String.IsNullOrEmpty(origin))
{
        context.Response.AddHeader("Access-Control-Allow-Origin", origin);
        context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
}

This seems quite insecure. Now all origins are allowed. If you have a look at my code above you see that I compare the origin against the cookie domain. Could you implement something similar?

EDIT - one extra thing to note:
It would be better to somehow overwrite the Access-Control-Allow-Origin, instead of using AddHeader. Now if you have the Access-Control-Allow-Origin defined in your web.config, you'll end up with both values being sent to the client. Which will fail in almost all browsers (I think only Firefox supports that).

David Fowler
Owner
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.