Skip to content

Commit 8747cd1

Browse files
authored
js: Apply workaround for incomplete fetch support in Cloudflare Worker (#1359)
Closes #1331.
2 parents e5dbc75 + 61cbb9e commit 8747cd1

File tree

1 file changed

+46
-42
lines changed

1 file changed

+46
-42
lines changed
Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,58 @@
1-
import {HttpLibrary, RequestContext, ResponseContext} from './http';
1+
import { HttpLibrary, RequestContext, ResponseContext } from './http';
22
import { from, Observable } from '../rxjsStub';
33
import "svix-fetch";
44

55
const numRetries = 2;
66
const sleep = (interval: number) => new Promise(resolve => setTimeout(resolve, interval));
77

88
export class IsomorphicFetchHttpLibrary implements HttpLibrary {
9+
public send(request: RequestContext): Observable<ResponseContext> {
10+
const resultPromise = this.sendWithRetry(request, numRetries, 50, 1);
11+
return from<Promise<ResponseContext>>(resultPromise);
12+
}
913

10-
public send(request: RequestContext): Observable<ResponseContext> {
11-
const resultPromise = this.sendWithRetry(request, numRetries, 50, 1);
12-
return from<Promise<ResponseContext>>(resultPromise);
13-
}
14+
private async sendWithRetry(request: RequestContext, triesLeft: number, nextInterval: number, retryCount: number): Promise<ResponseContext> {
15+
try {
16+
const response = await this.sendOnce(request);
17+
if (triesLeft <= 0 || response.httpStatusCode < 500) {
18+
return response;
19+
}
20+
} catch (e) {
21+
if (triesLeft <= 0) {
22+
throw e;
23+
}
24+
};
25+
await sleep(nextInterval);
26+
const headers = request.getHeaders();
27+
headers['svix-retry-count'] = retryCount.toString()
28+
return await this.sendWithRetry(request, --triesLeft, nextInterval * 2, ++retryCount);
29+
}
1430

15-
private async sendWithRetry(request: RequestContext, triesLeft: number, nextInterval: number, retryCount: number): Promise<ResponseContext> {
16-
try {
17-
const response = await this.sendOnce(request);
18-
if (triesLeft <= 0 || response.httpStatusCode < 500) {
19-
return response;
20-
}
21-
} catch (e) {
22-
if (triesLeft <= 0) {
23-
throw e;
24-
}
25-
};
26-
await sleep(nextInterval);
27-
const headers = request.getHeaders();
28-
headers['svix-retry-count'] = retryCount.toString()
29-
return await this.sendWithRetry(request, --triesLeft, nextInterval * 2, ++retryCount);
30-
}
31-
32-
private sendOnce(request: RequestContext): Promise<ResponseContext> {
33-
let method = request.getHttpMethod().toString();
34-
let body = request.getBody();
31+
private sendOnce(request: RequestContext): Promise<ResponseContext> {
32+
let method = request.getHttpMethod().toString();
33+
let body = request.getBody();
34+
35+
// Cloudflare Workers fail if the credentials option is used in a fetch call.
36+
// This work around that. Source:
37+
// https://github.com/cloudflare/workers-sdk/issues/2514#issuecomment-2178070014
38+
const isCredentialsSupported = "credentials" in Request.prototype;
3539

36-
return fetch(request.getUrl(), {
37-
method: method,
38-
body: body as any,
39-
headers: request.getHeaders(),
40-
credentials: "same-origin"
41-
}).then((resp: any) => {
42-
const headers: { [name: string]: string } = {};
43-
resp.headers.forEach((value: string, name: string) => {
44-
headers[name] = value;
45-
});
40+
return fetch(request.getUrl(), {
41+
method: method,
42+
body: body as any,
43+
headers: request.getHeaders(),
44+
credentials: isCredentialsSupported ? "same-origin" : undefined
45+
}).then((resp: any) => {
46+
const headers: { [name: string]: string } = {};
47+
resp.headers.forEach((value: string, name: string) => {
48+
headers[name] = value;
49+
});
4650

47-
const body = {
48-
text: () => resp.text(),
49-
binary: () => resp.blob()
50-
};
51-
return new ResponseContext(resp.status, headers, body);
52-
});
53-
}
51+
const body = {
52+
text: () => resp.text(),
53+
binary: () => resp.blob()
54+
};
55+
return new ResponseContext(resp.status, headers, body);
56+
});
57+
}
5458
}

0 commit comments

Comments
 (0)