Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 41 additions & 2 deletions src/api/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export interface NewProjectResponseSchema {
export interface CompileResponseSchema {
status: 'success' | 'failure' | 'error';
compileGroup: string;
clsiServerId?: string;
pdfDownloadDomain?: string;
outputFiles: Array<OutputFileEntity>;
stats: {
"latexmk-errors":number, "pdf-size":number,
Expand Down Expand Up @@ -684,9 +686,20 @@ export class BaseAPI {
return this.request('POST', `project/${projectId}/settings`, setting);
}

async getFileFromClsi(identity:Identity, url:string, compileGroup:string) {
url = url.replace(/^\/+/g, '');
async getFileFromClsi(identity:Identity, url:string, compileGroup:string, clsiServerId?:string, pdfDownloadDomain?:string) {
// If we have a CDN download domain, construct the full URL with required query params.
// The CDN is cross-origin, so we must NOT send web frontend cookies.
if (pdfDownloadDomain && clsiServerId) {
const cdnUrl = `${pdfDownloadDomain.replace(/\/+$/, '')}/${url.replace(/^\/+/g, '')}` +
`?compileGroup=${encodeURIComponent(compileGroup)}` +
`&clsiserverid=${encodeURIComponent(clsiServerId)}` +
`&enable_pdf_caching=true`;
const content = await this._downloadAbsolute(cdnUrl, false);
return { type: 'success', content: new Uint8Array(content) };
}

// Fallback: download from web frontend (legacy path)
url = url.replace(/^\/+/g, '');
this.setIdentity(identity);
const content = await this.download(url);
return {
Expand All @@ -695,6 +708,32 @@ export class BaseAPI {
};
}

/** Download from an absolute URL, optionally including web frontend cookies. */
private async _downloadAbsolute(absoluteUrl: string, includeCookies: boolean): Promise<Buffer> {
const headers: Record<string, string> = {
'Connection': 'keep-alive',
};
if (includeCookies && this.identity) {
headers['Cookie'] = this.identity.cookies;
}
let content: Buffer[] = [];
while (true) {
const res = await fetch(absoluteUrl, {
method: 'GET', redirect: 'manual', agent: this.agent,
headers
});
if (res.status === 200) {
content.push(await res.buffer());
break;
} else if (res.status === 206) {
content.push(await res.buffer());
} else {
break;
}
}
return Buffer.concat(content);
}

async proxySyncPdf(identity:Identity, projectId:string, page:number, h:number, v:number, buildId:string) {
this.setIdentity(identity);
const request = `project/${projectId}/sync/pdf?page=${page}&h=${h.toFixed(2)}&v=${v.toFixed(2)}&editorId=${uuidv4()}&buildId=${buildId}`;
Expand Down
10 changes: 9 additions & 1 deletion src/core/remoteFileSystemProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ export class VirtualFileSystem extends vscode.Disposable {
private initializing?: Promise<ProjectEntity>;
private retryConnection: number = 0;
private outputBuildId?: string;
private compileGroup?: string;
private clsiServerId?: string;
private pdfDownloadDomain?: string;
private notify: (events:vscode.FileChangeEvent[])=>void;
private clientManagerItem?: {manager: ClientManager, triggers: vscode.Disposable[]};
private scmCollectionItem?: {collection: SCMCollectionProvider, triggers: vscode.Disposable[]};
Expand Down Expand Up @@ -531,9 +534,10 @@ export class VirtualFileSystem extends vscode.Disposable {
return new TextEncoder().encode(content);
}
} else if (fileType==='outputs') {
const {compileGroup, clsiServerId, pdfDownloadDomain} = this;
return GlobalStateManager.authenticate(this.context, this.serverName)
.then((identity) => {
return this.api.getFileFromClsi(identity, (fileEntity as OutputFileEntity).url, 'standard')
return this.api.getFileFromClsi(identity, (fileEntity as OutputFileEntity).url, compileGroup || 'standard', clsiServerId, pdfDownloadDomain)
.then((res) => {
if (res.type==='success') {
EventBus.fire('fileWillOpenEvent', {uri});
Expand Down Expand Up @@ -896,6 +900,10 @@ export class VirtualFileSystem extends vscode.Disposable {
}
const res = await this.api.compile(identity, this.projectId, rootResourcePath, draft, stopOnFirstError);
if (res.type==='success' && res.compile?.status==='success') {
// Store CDN download info from the response for subsequent output file requests
this.compileGroup = res.compile.compileGroup;
this.clsiServerId = res.compile.clsiServerId;
this.pdfDownloadDomain = res.compile.pdfDownloadDomain;
this.updateOutputs(res.compile.outputFiles);
return true;
} else {
Expand Down
Loading