import { v4 as uuid } from "uuid" ; import { ITelemetryLogger } from "@fluidframework/common-definitions" ; import { PerformanceEvent } from "@fluidframework/telemetry-utils" ; import { InstrumentedStorageTokenFetcher , IOdspUrlParts } from "@fluidframework/odsp-driver-definitions" ; import { ISocketStorageDiscovery } from "./contracts" ; import { getOrigin , TokenFetchOptionsEx } from "./odspUtils" ; import { getApiRoot } from "./odspUrlHelper" ; import { EpochTracker } from "./epochTracker" ; import { runWithRetry } from "./retryUtils" ; interface IJoinSessionBody { requestSocketToken : boolean ; guestDisplayName : string ; } param urlParts param path param method param logger param getStorageToken param epochTracker param requestSocketToken param options param guestDisplayName export async function fetchJoinSession ( urlParts , path , method , logger , getStorageToken , epochTracker , requestSocketToken , options , guestDisplayName ? ) { const token = await getStorageToken ( options , "JoinSession" ) ; const extraProps = options . refresh ? { hasClaims : ! ! options . claims , hasTenantId : ! ! options . tenantId } : { } ; return PerformanceEvent . timedExecAsync ( logger , { eventName : "JoinSession" , attempts : options . refresh ? 2 : 1 , ... extraProps } , async ( event ) => { const siteOrigin = getOrigin ( urlParts . siteUrl ) ; const formBoundary = uuid ( ) ; let postBody = `--${ formBoundary }\r\n` ; postBody += `Authorization: Bearer ${ token }\r\n` ; postBody += `X-HTTP-Method-Override: POST\r\n` ; postBody += `Content-Type: application/json\r\n` ; postBody += `_post: 1\r\n` ; if ( requestSocketToken && guestDisplayName !== undefined ) { const body = { requestSocketToken : true , guestDisplayName } ; postBody += `\r\n${ JSON . stringify ( body ) }\r\n` ; } postBody += `\r\n--${ formBoundary }--` ; const headers = { "Content-Type" : `multipart/form-data;boundary=${ formBoundary }` } ; const response = await runWithRetry ( async ( ) => epochTracker . fetchAndParseAsJSON < ISocketStorageDiscovery > ( `${ getApiRoot ( siteOrigin ) }/drives/${ urlParts . driveId }/items/${ urlParts . itemId }/${ path }?ump=1` , { method , headers , body : postBody } , "joinSession" , true ) , "joinSession" , logger ) ; const socketUrl = response . content . deltaStreamSocketUrl ; const webSocketHostName = socketUrl . split ( "/" ) [ 2 ] ; event . end ( { ... response . commonSpoHeaders , pushv2 : socketUrl . includes ( "pushf" ) , webSocketHostName } ) ; if ( response . content . runtimeTenantId && ! response . content . tenantId ) { response . content . tenantId = response . content . runtimeTenantId ; } return response . content ; } ) ; }