From 81b38ceb60145cecb563ac173e32f7bc17297f68 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Mon, 7 Feb 2022 10:26:15 +0100 Subject: [PATCH 1/3] fix: gateway get durable object request function --- packages/gateway/src/gateway.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/gateway/src/gateway.js b/packages/gateway/src/gateway.js index 9d2f1937e3..2ff960aa15 100644 --- a/packages/gateway/src/gateway.js +++ b/packages/gateway/src/gateway.js @@ -352,7 +352,9 @@ async function updateCidsTracker(request, env, responses, cid) { function getDurableRequestUrl(request, route, data) { const reqUrl = new URL( route, - request.url.startsWith('http') ? request.url : `http://${request.url}` + request.url.startsWith('http') || request.url.startsWith('https') + ? request.url + : `https://${request.url}` ) const headers = new Headers() headers.append('Content-Type', 'application/json') From 2dd312fd3adfe48a7bdc2b648e8c9658afa715a3 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Mon, 7 Feb 2022 10:45:47 +0100 Subject: [PATCH 2/3] fix: error not tracking timeout gateway --- packages/gateway/src/constants.js | 1 - packages/gateway/src/gateway.js | 20 ++++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/gateway/src/constants.js b/packages/gateway/src/constants.js index c529b5600f..0506bf6b4c 100644 --- a/packages/gateway/src/constants.js +++ b/packages/gateway/src/constants.js @@ -6,4 +6,3 @@ export const REDIRECT_COUNTER_METRICS_ID = 'redirect-counter-metrics' export const HTTP_STATUS_RATE_LIMITED = 429 export const HTTP_STATUS_SUCCESS = 200 export const REQUEST_PREVENTED_RATE_LIMIT_CODE = 'RATE_LIMIT' -export const ABORT_ERR_CODE = 'ABORT_ERR' diff --git a/packages/gateway/src/gateway.js b/packages/gateway/src/gateway.js index 2ff960aa15..157ea716dc 100644 --- a/packages/gateway/src/gateway.js +++ b/packages/gateway/src/gateway.js @@ -1,14 +1,13 @@ /* eslint-env serviceworker, browser */ /* global Response caches */ -import pAny from 'p-any' +import pAny, { AggregateError } from 'p-any' import { FilterError } from 'p-some' import pSettle from 'p-settle' import { TimeoutError } from './errors.js' import { getCidFromSubdomainUrl } from './utils/cid.js' import { - ABORT_ERR_CODE, CIDS_TRACKER_ID, SUMMARY_METRICS_ID, REDIRECT_COUNTER_METRICS_ID, @@ -23,6 +22,7 @@ import { * @property {string} url * @property {number} [responseTime] * @property {string} [requestPreventedCode] + * @property {boolean} [aborted] * * @typedef {import('./env').Env} Env */ @@ -126,7 +126,7 @@ export async function gatewayGet(request, env, ctx) { } // Return the error response from gateway, error is not from nft.storage Gateway - if (err instanceof FilterError) { + if (err instanceof FilterError || err instanceof AggregateError) { const candidateResponse = responses.find((r) => r.value?.response) // Return first response with upstream error @@ -135,7 +135,7 @@ export async function gatewayGet(request, env, ctx) { } // Gateway timeout - if (responses[0].reason?.code === ABORT_ERR_CODE) { + if (responses[0].value?.aborted) { throw new TimeoutError() } } @@ -198,6 +198,14 @@ async function gatewayFetch( signal: controller.signal, headers: getHeaders(request), }) + } catch (error) { + if (controller.signal.aborted) { + return { + url: gwUrl, + aborted: true, + } + } + throw error } finally { clearTimeout(timer) } @@ -308,6 +316,10 @@ async function updateGatewayMetrics( gwResponse, isWinner = false ) { + if (!gwResponse.response?.status && !gwResponse.requestPreventedCode) { + return + } + // Get durable object for gateway const id = env.gatewayMetricsDurable.idFromName(gwResponse.url) const stub = env.gatewayMetricsDurable.get(id) From dcc29ba5d770355300ec1980d7b56369024d3f29 Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Tue, 8 Feb 2022 13:45:53 +0100 Subject: [PATCH 3/3] fix: address review comments --- packages/gateway/src/constants.js | 1 + packages/gateway/src/gateway.js | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/gateway/src/constants.js b/packages/gateway/src/constants.js index 0506bf6b4c..f159512bf2 100644 --- a/packages/gateway/src/constants.js +++ b/packages/gateway/src/constants.js @@ -6,3 +6,4 @@ export const REDIRECT_COUNTER_METRICS_ID = 'redirect-counter-metrics' export const HTTP_STATUS_RATE_LIMITED = 429 export const HTTP_STATUS_SUCCESS = 200 export const REQUEST_PREVENTED_RATE_LIMIT_CODE = 'RATE_LIMIT' +export const TIMEOUT_CODE = 'TIMEOUT' diff --git a/packages/gateway/src/gateway.js b/packages/gateway/src/gateway.js index 157ea716dc..5775da4ab6 100644 --- a/packages/gateway/src/gateway.js +++ b/packages/gateway/src/gateway.js @@ -14,6 +14,7 @@ import { CF_CACHE_MAX_OBJECT_SIZE, HTTP_STATUS_RATE_LIMITED, REQUEST_PREVENTED_RATE_LIMIT_CODE, + TIMEOUT_CODE, } from './constants.js' /** @@ -21,7 +22,7 @@ import { * @property {Response} [response] * @property {string} url * @property {number} [responseTime] - * @property {string} [requestPreventedCode] + * @property {string} [reason] * @property {boolean} [aborted] * * @typedef {import('./env').Env} Env @@ -105,7 +106,7 @@ export async function gatewayGet(request, env, ctx) { const wasRateLimited = responses.every( (r) => r.value?.response?.status === HTTP_STATUS_RATE_LIMITED || - r.value?.requestPreventedCode === REQUEST_PREVENTED_RATE_LIMIT_CODE + r.value?.reason === REQUEST_PREVENTED_RATE_LIMIT_CODE ) ctx.waitUntil( @@ -135,7 +136,10 @@ export async function gatewayGet(request, env, ctx) { } // Gateway timeout - if (responses[0].value?.aborted) { + if ( + responses[0].value?.aborted && + responses[0].value?.reason == TIMEOUT_CODE + ) { throw new TimeoutError() } } @@ -183,7 +187,8 @@ async function gatewayFetch( /** @type {GatewayResponse} */ return { url: gwUrl, - requestPreventedCode: REQUEST_PREVENTED_RATE_LIMIT_CODE, + aborted: true, + reason: REQUEST_PREVENTED_RATE_LIMIT_CODE, } } @@ -203,6 +208,7 @@ async function gatewayFetch( return { url: gwUrl, aborted: true, + reason: TIMEOUT_CODE, } } throw error @@ -316,10 +322,6 @@ async function updateGatewayMetrics( gwResponse, isWinner = false ) { - if (!gwResponse.response?.status && !gwResponse.requestPreventedCode) { - return - } - // Get durable object for gateway const id = env.gatewayMetricsDurable.idFromName(gwResponse.url) const stub = env.gatewayMetricsDurable.get(id) @@ -329,7 +331,7 @@ async function updateGatewayMetrics( status: gwResponse.response?.status, winner: isWinner, responseTime: gwResponse.responseTime, - requestPreventedCode: gwResponse.requestPreventedCode, + requestPreventedCode: gwResponse.reason, } await stub.fetch(getDurableRequestUrl(request, 'update', fetchStats))