ably / ably-js

Javascript, Node, Typescript, React, React Native client library SDK for Ably realtime messaging service
https://ably.com/download
Apache License 2.0
316 stars 55 forks source link

Host fallback on unauthorized #250

Closed mattheworiordan closed 8 years ago

mattheworiordan commented 8 years ago

I came across a situation whereby the ably-js library failed to authenticate because of an expired token, yet instead of simply moving to the FAILED state because there was no means to correct this, it tried to use the fallback hosts. However, when doing that, it attempted to connect to hosts that do not exist. So I believe we have two issues here.

Router: Started with initial state: Object {token: "1YRBpA.DVaKKIuTQ00PbM9YYN9WoJkjsAvbqWnwUPckxnGNYOn…-S6l23K8v0q9UGT_WEAxtwexDgRxx8agUtALxSgrj31avImYW", channelName: "3VJW"}
2016-03-31 19:25:14.521 ably.min.js:81 Ably: Connection.connect(): 
2016-03-31 19:25:15.060 tracker.js:109 dom is ready button
2016-03-31 19:25:15.396 ably.min.js:81 Ably: ConnectionManager.chooseTransport(): 
2016-03-31 19:25:17.782 ably.min.js:250 GET https://rest.ably.io/comet/connect?access_token=1YRBpA.DVaKKIuTQ00PbM9YYN9W…6l23K8v0q9UGT_WEAxtwexDgRxx8agUtALxSgrj31avImYW&v=0.8&rnd=3740031630825631 401 (Unauthorized)c.exec @ ably.min.js:250(anonymous function) @ ably.min.js:166(anonymous function) @ ably.min.js:194(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.getAuthParams @ ably.min.js:194e.connect @ ably.min.js:165e.tryConnect @ ably.min.js:252c.chooseTransportForHost @ ably.min.js:121c.chooseHttpTransport @ ably.min.js:123c.chooseTransport @ ably.min.js:119l @ ably.min.js:143(anonymous function) @ ably.min.js:143(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.connectImpl @ ably.min.js:143(anonymous function) @ ably.min.js:140a.bugsnag @ bugsnag-2.min.js:1(anonymous function) @ bugsnag-2.min.js:1
2016-03-31 19:25:19.612 ably.min.js:250 GET https://a.ably-realtime.com%2Cb.ably-realtime.com%2Cc.ably-realtime.com/com…T_WEAxtwexDgRxx8agUtALxSgrj31avImYW&stream=false&v=0.8&rnd=555984124844418 net::ERR_NAME_NOT_RESOLVEDc.exec @ ably.min.js:250(anonymous function) @ ably.min.js:166(anonymous function) @ ably.min.js:194(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.getAuthParams @ ably.min.js:194e.connect @ ably.min.js:165e.tryConnect @ ably.min.js:252c.chooseTransportForHost @ ably.min.js:121(anonymous function) @ ably.min.js:122(anonymous function) @ ably.min.js:252g @ ably.min.js:77e.emit @ ably.min.js:79c.complete @ ably.min.js:246l.onreadystatechange @ ably.min.js:250
2016-03-31 19:25:19.613 ably.min.js:81 Ably: Request.onerror(): XHR error occurred, errorEvent type was error, current statusText is 
2016-03-31 19:25:19.708 ably.min.js:243 GET https://a.ably-realtime.com%2Cb.ably-realtime.com%2Cc.ably-realtime.com/com…tream=false&v=0.8&rnd=8765372676727552&callback=Ably._._(2)&envelope=jsonp net::ERR_NAME_NOT_RESOLVEDg.exec @ ably.min.js:243(anonymous function) @ ably.min.js:166(anonymous function) @ ably.min.js:194(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.getAuthParams @ ably.min.js:194e.connect @ ably.min.js:165e.tryConnect @ ably.min.js:241c.chooseTransportForHost @ ably.min.js:121(anonymous function) @ ably.min.js:122k @ ably.min.js:252g @ ably.min.js:77e.emit @ ably.min.js:79e.finish @ ably.min.js:153(anonymous function) @ ably.min.js:166g @ ably.min.js:77e.emit @ ably.min.js:79c.complete @ ably.min.js:246y @ ably.min.js:248l.onerror @ ably.min.js:248
2016-03-31 19:25:19.709 ably.min.js:81 Ably: ConnectionManager.chooseTransport(): Unexpected error establishing transport; err = {"message":"Unable to connect (no available host)","code":80000,"statusCode":404}
2016-03-31 19:25:19.710 ably.min.js:81 Ably: ConnectionManager.connectImpl(): Connection attempt failed with error; err = [d: Unable to connect (no available host); statusCode=404; code=80000]
2016-03-31 19:25:34.713 ably.min.js:81 Ably: ConnectionManager.chooseTransport(): 
2016-03-31 19:25:34.808 ably.min.js:250 GET https://rest.ably.io/comet/connect?access_token=1YRBpA.DVaKKIuTQ00PbM9YYN9W…l23K8v0q9UGT_WEAxtwexDgRxx8agUtALxSgrj31avImYW&v=0.8&rnd=19006262049774225 401 (Unauthorized)c.exec @ ably.min.js:250(anonymous function) @ ably.min.js:166(anonymous function) @ ably.min.js:194(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.getAuthParams @ ably.min.js:194e.connect @ ably.min.js:165e.tryConnect @ ably.min.js:252c.chooseTransportForHost @ ably.min.js:121c.chooseHttpTransport @ ably.min.js:123c.chooseTransport @ ably.min.js:119l @ ably.min.js:143(anonymous function) @ ably.min.js:143(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.connectImpl @ ably.min.js:143(anonymous function) @ ably.min.js:140a.bugsnag @ bugsnag-2.min.js:1(anonymous function) @ bugsnag-2.min.js:1
2016-03-31 19:25:36.792 ably.min.js:250 GET https://c.ably-realtime.com/comet/connect?access_token=1YRBpA.DVaKKIuTQ00Pb…WEAxtwexDgRxx8agUtALxSgrj31avImYW&stream=false&v=0.8&rnd=27092705245612114 401 (Unauthorized)c.exec @ ably.min.js:250(anonymous function) @ ably.min.js:166(anonymous function) @ ably.min.js:194(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.getAuthParams @ ably.min.js:194e.connect @ ably.min.js:165e.tryConnect @ ably.min.js:252c.chooseTransportForHost @ ably.min.js:121(anonymous function) @ ably.min.js:122(anonymous function) @ ably.min.js:252g @ ably.min.js:77e.emit @ ably.min.js:79c.complete @ ably.min.js:246l.onreadystatechange @ ably.min.js:250
2016-03-31 19:25:38.671 ably.min.js:250 GET https://a.ably-realtime.com%2Cb.ably-realtime.com/comet/connect?access_toke…T_WEAxtwexDgRxx8agUtALxSgrj31avImYW&stream=false&v=0.8&rnd=438900588052189 net::ERR_NAME_NOT_RESOLVEDc.exec @ ably.min.js:250(anonymous function) @ ably.min.js:166(anonymous function) @ ably.min.js:194(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.getAuthParams @ ably.min.js:194e.connect @ ably.min.js:165e.tryConnect @ ably.min.js:252c.chooseTransportForHost @ ably.min.js:121(anonymous function) @ ably.min.js:122(anonymous function) @ ably.min.js:252g @ ably.min.js:77e.emit @ ably.min.js:79c.complete @ ably.min.js:246l.onreadystatechange @ ably.min.js:250
2016-03-31 19:25:38.671 ably.min.js:81 Ably: Request.onerror(): XHR error occurred, errorEvent type was error, current statusText is 
2016-03-31 19:25:38.743 ably.min.js:243 GET https://a.ably-realtime.com%2Cb.ably-realtime.com/comet/connect?access_toke…tream=false&v=0.8&rnd=3544144479154774&callback=Ably._._(5)&envelope=jsonp net::ERR_NAME_NOT_RESOLVEDg.exec @ ably.min.js:243(anonymous function) @ ably.min.js:166(anonymous function) @ ably.min.js:194(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.getAuthParams @ ably.min.js:194e.connect @ ably.min.js:165e.tryConnect @ ably.min.js:241c.chooseTransportForHost @ ably.min.js:121(anonymous function) @ ably.min.js:122k @ ably.min.js:252g @ ably.min.js:77e.emit @ ably.min.js:79e.finish @ ably.min.js:153(anonymous function) @ ably.min.js:166g @ ably.min.js:77e.emit @ ably.min.js:79c.complete @ ably.min.js:246y @ ably.min.js:248l.onerror @ ably.min.js:248
2016-03-31 19:25:38.743 ably.min.js:81 Ably: ConnectionManager.chooseTransport(): Unexpected error establishing transport; err = {"message":"Unable to connect (no available host)","code":80000,"statusCode":404}
2016-03-31 19:25:38.743 ably.min.js:81 Ably: ConnectionManager.connectImpl(): Connection attempt failed with error; err = [d: Unable to connect (no available host); statusCode=404; code=80000]
2016-03-31 19:25:53.750 ably.min.js:81 Ably: ConnectionManager.chooseTransport(): 
2016-03-31 19:25:53.845 ably.min.js:250 GET https://rest.ably.io/comet/connect?access_token=1YRBpA.DVaKKIuTQ00PbM9YYN9W…6l23K8v0q9UGT_WEAxtwexDgRxx8agUtALxSgrj31avImYW&v=0.8&rnd=7611468559437324 401 (Unauthorized)c.exec @ ably.min.js:250(anonymous function) @ ably.min.js:166(anonymous function) @ ably.min.js:194(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.getAuthParams @ ably.min.js:194e.connect @ ably.min.js:165e.tryConnect @ ably.min.js:252c.chooseTransportForHost @ ably.min.js:121c.chooseHttpTransport @ ably.min.js:123c.chooseTransport @ ably.min.js:119l @ ably.min.js:143(anonymous function) @ ably.min.js:143(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.connectImpl @ ably.min.js:143(anonymous function) @ ably.min.js:140a.bugsnag @ bugsnag-2.min.js:1(anonymous function) @ bugsnag-2.min.js:1
2016-03-31 19:25:54.285 ably.min.js:250 GET https://b.ably-realtime.com%2Cc.ably-realtime.com/comet/connect?access_toke…WEAxtwexDgRxx8agUtALxSgrj31avImYW&stream=false&v=0.8&rnd=08438414876536227 net::ERR_NAME_NOT_RESOLVEDc.exec @ ably.min.js:250(anonymous function) @ ably.min.js:166(anonymous function) @ ably.min.js:194(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.getAuthParams @ ably.min.js:194e.connect @ ably.min.js:165e.tryConnect @ ably.min.js:252c.chooseTransportForHost @ ably.min.js:121(anonymous function) @ ably.min.js:122(anonymous function) @ ably.min.js:252g @ ably.min.js:77e.emit @ ably.min.js:79c.complete @ ably.min.js:246l.onreadystatechange @ ably.min.js:250
2016-03-31 19:25:54.285 ably.min.js:81 Ably: Request.onerror(): XHR error occurred, errorEvent type was error, current statusText is 
2016-03-31 19:25:54.407 ably.min.js:243 GET https://b.ably-realtime.com%2Cc.ably-realtime.com/comet/connect?access_toke…tream=false&v=0.8&rnd=6966267795940724&callback=Ably._._(7)&envelope=jsonp net::ERR_NAME_NOT_RESOLVEDg.exec @ ably.min.js:243(anonymous function) @ ably.min.js:166(anonymous function) @ ably.min.js:194(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.getAuthParams @ ably.min.js:194e.connect @ ably.min.js:165e.tryConnect @ ably.min.js:241c.chooseTransportForHost @ ably.min.js:121(anonymous function) @ ably.min.js:122k @ ably.min.js:252g @ ably.min.js:77e.emit @ ably.min.js:79e.finish @ ably.min.js:153(anonymous function) @ ably.min.js:166g @ ably.min.js:77e.emit @ ably.min.js:79c.complete @ ably.min.js:246y @ ably.min.js:248l.onerror @ ably.min.js:248
2016-03-31 19:25:55.496 ably.min.js:250 GET https://a.ably-realtime.com/comet/connect?access_token=1YRBpA.DVaKKIuTQ00Pb…T_WEAxtwexDgRxx8agUtALxSgrj31avImYW&stream=false&v=0.8&rnd=959895088904706 401 (Unauthorized)c.exec @ ably.min.js:250(anonymous function) @ ably.min.js:166(anonymous function) @ ably.min.js:194(anonymous function) @ ably.min.js:186c.getTimestamp @ ably.min.js:195c.authorise @ ably.min.js:185c.getAuthParams @ ably.min.js:194e.connect @ ably.min.js:165e.tryConnect @ ably.min.js:252c.chooseTransportForHost @ ably.min.js:121(anonymous function) @ ably.min.js:122(anonymous function) @ ably.min.js:252g @ ably.min.js:77e.emit @ ably.min.js:79c.complete @ ably.min.js:246l.onreadystatechange @ ably.min.js:250
2016-03-31 19:25:56.391 ably.min.js:81 Ably: ConnectionManager.chooseTransport(): Unexpected error establishing transport; err = {"message":"Unable to connect (no available host)","code":80000,"statusCode":404}
2016-03-31 19:25:56.392 ably.min.js:81 Ably: ConnectionManager.connectImpl(): Connection attempt failed with error; err = [d: Unable to connect (no available host); statusCode=404; code=80000]

FYI, the first request responds with:

{
    "error": {
        "statusCode": 401,
        "code": 40142,
        "message": "Token expired",
        "serverId": "frontend.a84b.eu-central-1-A.i-ed1ec650"
    }
}

The internet up check is then made, however the next request made is:

https://b.ably-realtime.com%2Cc.ably-realtime.com/comet/connect?access_token=1YRBpA.DVaKKIuTQ00PbM9YYN9WoJkjsAvbqWnwUPckxnGNYOn3Lanko6ExmwG1DLUAqFoLZfzkyws8tAH6IUTo-S6l23K8v0q9UGT_WEAxtwexDgRxx8agUtALxSgrj31avImYW&stream=false&v=0.8&rnd=22041912457049873

This is wrong - look at the host. However, a fallback should not have been used in the first place.

A further internet up check i smade, is this necessary, surely one has just been made so we try all the fallback hosts?

The next request is made to a valid fallback:

https://a.ably-realtime.com/comet/connect?access_token=1YRBpA.DVaKKIuTQ00PbM9YYN9WoJkjsAvbqWnwUPckxnGNYOn3Lanko6ExmwG1DLUAqFoLZfzkyws8tAH6IUTo-S6l23K8v0q9UGT_WEAxtwexDgRxx8agUtALxSgrj31avImYW&stream=false&v=0.8&rnd=30447875024130644

Which too resonds with expired token, and then the lib tries the root host again:

https://rest.ably.io/comet/connect?access_token=1YRBpA.DVaKKIuTQ00PbM9YYN9WoJkjsAvbqWnwUPckxnGNYOn3Lanko6ExmwG1DLUAqFoLZfzkyws8tAH6IUTo-S6l23K8v0q9UGT_WEAxtwexDgRxx8agUtALxSgrj31avImYW&v=0.8&rnd=9783984097241547

And the cycle continues.

SimonWoolf commented 8 years ago

Fixed by https://github.com/ably/ably-js/pull/251