fix(rgi): rgiDownload handles session expiry + re-login on 401/302/404
eTerra returns 404 (not 401) when session expires during file download because it redirects to login page. Now rgiDownload: - Uses validateStatus to catch all statuses - Re-logins and retries on 401/302/404 - Sets Accept: */* header for binary downloads Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1015,17 +1015,34 @@ export class EterraClient {
|
|||||||
*/
|
*/
|
||||||
async rgiDownload(path: string): Promise<{ data: Buffer; contentType: string; filename: string }> {
|
async rgiDownload(path: string): Promise<{ data: Buffer; contentType: string; filename: string }> {
|
||||||
const url = `${BASE_URL}/api/${path}`;
|
const url = `${BASE_URL}/api/${path}`;
|
||||||
const response = await this.requestWithRetry(() =>
|
const doRequest = () =>
|
||||||
this.client.get(url, {
|
this.client.get(url, {
|
||||||
timeout: this.timeoutMs,
|
timeout: this.timeoutMs,
|
||||||
responseType: "arraybuffer",
|
responseType: "arraybuffer",
|
||||||
}),
|
// Override Accept header for binary download
|
||||||
);
|
headers: { Accept: "*/*" },
|
||||||
const cd = (response as { headers?: Record<string, string> }).headers?.["content-disposition"] ?? "";
|
// Don't throw on any status — we'll check manually
|
||||||
|
validateStatus: () => true,
|
||||||
|
});
|
||||||
|
|
||||||
|
let response = await doRequest();
|
||||||
|
|
||||||
|
// If 401/302/404 (session expired → redirect to login), re-login and retry
|
||||||
|
if (response.status === 401 || response.status === 302 || response.status === 404) {
|
||||||
|
await this.login(this.username, this.password);
|
||||||
|
response = await doRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(`Download failed: HTTP ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers = response.headers as Record<string, string> | undefined;
|
||||||
|
const cd = headers?.["content-disposition"] ?? "";
|
||||||
const match = /filename="?([^"]+)"?/.exec(cd);
|
const match = /filename="?([^"]+)"?/.exec(cd);
|
||||||
return {
|
return {
|
||||||
data: Buffer.from(response.data as ArrayBuffer),
|
data: Buffer.from(response.data as ArrayBuffer),
|
||||||
contentType: (response as { headers?: Record<string, string> }).headers?.["content-type"] ?? "application/octet-stream",
|
contentType: headers?.["content-type"] ?? "application/octet-stream",
|
||||||
filename: match?.[1] ?? "document.pdf",
|
filename: match?.[1] ?? "document.pdf",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user