@@ -23,6 +23,8 @@ const enum ConnectionState {
23
23
/** @private */
24
24
export interface INegotiateResponse {
25
25
connectionId ?: string ;
26
+ connectionToken ?: string ;
27
+ negotiateVersion ?: number ;
26
28
availableTransports ?: IAvailableTransport [ ] ;
27
29
url ?: string ;
28
30
accessToken ?: string ;
@@ -70,6 +72,8 @@ export class HttpConnection implements IConnection {
70
72
public onreceive : ( ( data : string | ArrayBuffer ) => void ) | null ;
71
73
public onclose : ( ( e ?: Error ) => void ) | null ;
72
74
75
+ private readonly negotiateVersion : number = 1 ;
76
+
73
77
constructor ( url : string , options : IHttpConnectionOptions = { } ) {
74
78
Arg . isRequired ( url , "url" ) ;
75
79
@@ -272,8 +276,6 @@ export class HttpConnection implements IConnection {
272
276
throw new Error ( "Negotiate redirection limit exceeded." ) ;
273
277
}
274
278
275
- this . connectionId = negotiateResponse . connectionId ;
276
-
277
279
await this . createTransport ( url , this . options . transport , negotiateResponse , transferFormat ) ;
278
280
}
279
281
@@ -322,53 +324,63 @@ export class HttpConnection implements IConnection {
322
324
return Promise . reject ( new Error ( `Unexpected status code returned from negotiate ${ response . statusCode } ` ) ) ;
323
325
}
324
326
325
- return JSON . parse ( response . content as string ) as INegotiateResponse ;
327
+ const negotiateResponse = JSON . parse ( response . content as string ) as INegotiateResponse ;
328
+ if ( ! negotiateResponse . negotiateVersion || negotiateResponse . negotiateVersion < 1 ) {
329
+ // Negotiate version 0 doesn't use connectionToken
330
+ // So we set it equal to connectionId so all our logic can use connectionToken without being aware of the negotiate version
331
+ negotiateResponse . connectionToken = negotiateResponse . connectionId ;
332
+ }
333
+ return negotiateResponse ;
326
334
} catch ( e ) {
327
335
this . logger . log ( LogLevel . Error , "Failed to complete negotiation with the server: " + e ) ;
328
336
return Promise . reject ( e ) ;
329
337
}
330
338
}
331
339
332
- private createConnectUrl ( url : string , connectionId : string | null | undefined ) {
333
- if ( ! connectionId ) {
340
+ private createConnectUrl ( url : string , connectionToken : string | null | undefined ) {
341
+ if ( ! connectionToken ) {
334
342
return url ;
335
343
}
336
- return url + ( url . indexOf ( "?" ) === - 1 ? "?" : "&" ) + `id=${ connectionId } ` ;
344
+
345
+ return url + ( url . indexOf ( "?" ) === - 1 ? "?" : "&" ) + `id=${ connectionToken } ` ;
337
346
}
338
347
339
348
private async createTransport ( url : string , requestedTransport : HttpTransportType | ITransport | undefined , negotiateResponse : INegotiateResponse , requestedTransferFormat : TransferFormat ) : Promise < void > {
340
- let connectUrl = this . createConnectUrl ( url , negotiateResponse . connectionId ) ;
349
+ let connectUrl = this . createConnectUrl ( url , negotiateResponse . connectionToken ) ;
341
350
if ( this . isITransport ( requestedTransport ) ) {
342
351
this . logger . log ( LogLevel . Debug , "Connection was provided an instance of ITransport, using that directly." ) ;
343
352
this . transport = requestedTransport ;
344
353
await this . startTransport ( connectUrl , requestedTransferFormat ) ;
345
354
355
+ this . connectionId = negotiateResponse . connectionId ;
346
356
return ;
347
357
}
348
358
349
359
const transportExceptions : any [ ] = [ ] ;
350
360
const transports = negotiateResponse . availableTransports || [ ] ;
361
+ let negotiate : INegotiateResponse | undefined = negotiateResponse ;
351
362
for ( const endpoint of transports ) {
352
363
const transportOrError = this . resolveTransportOrError ( endpoint , requestedTransport , requestedTransferFormat ) ;
353
364
if ( transportOrError instanceof Error ) {
354
365
// Store the error and continue, we don't want to cause a re-negotiate in these cases
355
366
transportExceptions . push ( `${ endpoint . transport } failed: ${ transportOrError } ` ) ;
356
367
} else if ( this . isITransport ( transportOrError ) ) {
357
368
this . transport = transportOrError ;
358
- if ( ! negotiateResponse . connectionId ) {
369
+ if ( ! negotiate ) {
359
370
try {
360
- negotiateResponse = await this . getNegotiationResponse ( url ) ;
371
+ negotiate = await this . getNegotiationResponse ( url ) ;
361
372
} catch ( ex ) {
362
373
return Promise . reject ( ex ) ;
363
374
}
364
- connectUrl = this . createConnectUrl ( url , negotiateResponse . connectionId ) ;
375
+ connectUrl = this . createConnectUrl ( url , negotiate . connectionToken ) ;
365
376
}
366
377
try {
367
378
await this . startTransport ( connectUrl , requestedTransferFormat ) ;
379
+ this . connectionId = negotiate . connectionId ;
368
380
return ;
369
381
} catch ( ex ) {
370
382
this . logger . log ( LogLevel . Error , `Failed to start the transport '${ endpoint . transport } ': ${ ex } ` ) ;
371
- negotiateResponse . connectionId = undefined ;
383
+ negotiate = undefined ;
372
384
transportExceptions . push ( `${ endpoint . transport } failed: ${ ex } ` ) ;
373
385
374
386
if ( this . connectionState !== ConnectionState . Connecting ) {
@@ -504,7 +516,7 @@ export class HttpConnection implements IConnection {
504
516
505
517
// Setting the url to the href propery of an anchor tag handles normalization
506
518
// for us. There are 3 main cases.
507
- // 1. Relative path normalization e.g "b" -> "http://localhost:5000/a/b"
519
+ // 1. Relative path normalization e.g "b" -> "http://localhost:5000/a/b"
508
520
// 2. Absolute path normalization e.g "/a/b" -> "http://localhost:5000/a/b"
509
521
// 3. Networkpath reference normalization e.g "//localhost:5000/a/b" -> "http://localhost:5000/a/b"
510
522
const aTag = window . document . createElement ( "a" ) ;
@@ -522,6 +534,11 @@ export class HttpConnection implements IConnection {
522
534
}
523
535
negotiateUrl += "negotiate" ;
524
536
negotiateUrl += index === - 1 ? "" : url . substring ( index ) ;
537
+
538
+ if ( negotiateUrl . indexOf ( "negotiateVersion" ) === - 1 ) {
539
+ negotiateUrl += index === - 1 ? "?" : "&" ;
540
+ negotiateUrl += "negotiateVersion=" + this . negotiateVersion ;
541
+ }
525
542
return negotiateUrl ;
526
543
}
527
544
}
0 commit comments