From 0bddda34547e462f705b3bbe927c20feb3c76d7e Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Mon, 8 Jan 2024 19:15:19 +0100 Subject: [PATCH 1/3] fix: edge function should not operate if not targeting definition files --- netlify/edge-functions/serve-definitions.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index 3197f584478c..6ba8a4b8e8dd 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -21,14 +21,13 @@ export default async (request: Request, context: Context) => { let rewriteRequest = buildRewrite(request); let response: Response; if (rewriteRequest === null) { - rewriteRequest = request; - - response = await context.next(); - } else { - // Fetching the definition file - response = await fetch(rewriteRequest); + // This is not a legitimate request, let it go through. + return await context.next(); } + // Fetching the definition file + response = await fetch(rewriteRequest); + const isRequestingAFile = request.url.endsWith('.json'); if (isRequestingAFile) { var metricName: string @@ -56,6 +55,7 @@ export default async (request: Request, context: Context) => { default: // Notifying NR of the error. metricName = "asyncapi.jsonschema.download.error"; + console.log("Error downloading JSON Schema file: " + response.status + " " + response.statusText); break; } } From a2437087183a5a9d222657ce28333617388f5293 Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Mon, 8 Jan 2024 19:52:54 +0100 Subject: [PATCH 2/3] add flowchart to README --- README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 19643c67de9d..9c6fc698148a 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,33 @@ All AsyncAPI JSON Schema definition files are being served within the `/definiti This is possible thanks to the following: 1. A [Netlify Rewrite rule](https://docs.netlify.com/routing/redirects/rewrites-proxies/) located in the [netlify.toml](netlify.toml) file, which acts as proxy for all requests to the `/definitions/` path, serving the content from GH without having an HTTP redirect. -2. A [Netlify Edge Function](https://docs.netlify.com/netlify-labs/experimental-features/edge-functions/) that modifies the `Content-Type` header of the rewrite response to become `application/schema+json`. This lets tooling, such as [Hyperjump](https://json-schema.hyperjump.io), to fetch the schemas directly from their URL. +2. A [Netlify Edge Function](https://docs.netlify.com/netlify-labs/experimental-features/edge-functions/) that modifies the `Content-Type` header of the rewrite response to become `application/schema+json`. This lets tooling, such as [Hyperjump](https://json-schema.hyperjump.io), to fetch the schemas directly from their URL. + Please find a flowchart explaining the flow this edge function should accomplish: + ```mermaid + flowchart TD + Request(Request) -->legitimate{Is it legitimate?} + legitimate -->|No| req_no_legitimate[Let the original request go through] + req_no_legitimate --> Response(Response) + + legitimate -->|Yes| req_legitimate[Fetch from GitHub] + req_legitimate-->req_json{Was requesting a .json file?} + + req_json -->|No| Response(Response) + req_json -->|Yes| response_status{Response Status?} + + response_status -->|2xx| response_ok[OK] + response_status -->|304| response_cached[Not Modified] + response_status -->|Any other| response_ko + + response_ok --> set_headers[Set Response Content-Type header to application/schema+json] + set_headers --> send_metric_success[Send success metric] + response_cached -- cached:true --> send_metric_success + response_ko --> send_metric_error[Send error metric] + + send_metric_success -- file served from raw GH --> Response(Response) + send_metric_error --the errored response --> Response(Response) + ``` + ## Project structure From a121a9781832b1a61ca9059b9cabb16ef6fc5953 Mon Sep 17 00:00:00 2001 From: Sergio Moya <1083296+smoya@users.noreply.github.com> Date: Tue, 9 Jan 2024 10:59:55 +0100 Subject: [PATCH 3/3] rename legitimate word to a more friendly one --- README.md | 11 +++++------ netlify/edge-functions/serve-definitions.ts | 12 ++++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9c6fc698148a..a2e76dc63d25 100644 --- a/README.md +++ b/README.md @@ -166,12 +166,11 @@ This is possible thanks to the following: Please find a flowchart explaining the flow this edge function should accomplish: ```mermaid flowchart TD - Request(Request) -->legitimate{Is it legitimate?} - legitimate -->|No| req_no_legitimate[Let the original request go through] - req_no_legitimate --> Response(Response) - - legitimate -->|Yes| req_legitimate[Fetch from GitHub] - req_legitimate-->req_json{Was requesting a .json file?} + Request(Request) -->schema-related{Is it requesting Schemas?} + schema-related -->|No| req_no_schemas[Let the original request go through] + req_no_schemas --> Response(Response) + schema-related -->|Yes| req_schemas[Fetch from GitHub] + req_schemas-->req_json{Was requesting a .json file?} req_json -->|No| Response(Response) req_json -->|Yes| response_status{Response Status?} diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index 6ba8a4b8e8dd..77c3141ee86a 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -7,21 +7,21 @@ const NR_METRICS_ENDPOINT = Deno.env.get("NR_METRICS_ENDPOINT") || "https://metr const URL_DEST_SCHEMAS = "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/schemas"; const URL_DEST_DEFINITIONS = "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/definitions"; -// Legitimate request: +// Schemas-related request: // Patterns: / OR // OR /// // Examples: /definitions OR /schema-store/2.5.0-without-$id.json OR /definitions/2.4.0/info.json -// Non-legitimate request: +// Schemas-unrelated request: // Patterns: ///* // Examples: /definitions/asyncapi.yaml OR /schema-store/2.4.0.JSON (uppercase) // -// Non-legitimate requests should not use our GitHub Token and affect the rate limit. Those shouldn't send metrics to NR either as they just add noise. -const legitimateRequestRegex = /^\/[\w\-]*\/?(?:([\w\-\.]*\/)?([\w\-$%\.]*\.json))?$/ +// Schemas-unrelated requests should not use our GitHub Token and affect the rate limit. Those shouldn't send metrics to NR either as they just add noise. +const SchemasRelatedRequestRegex = /^\/[\w\-]*\/?(?:([\w\-\.]*\/)?([\w\-$%\.]*\.json))?$/ export default async (request: Request, context: Context) => { let rewriteRequest = buildRewrite(request); let response: Response; if (rewriteRequest === null) { - // This is not a legitimate request, let it go through. + // This is a Schema-unrelated request. Let it go through and do not intercept it. return await context.next(); } @@ -68,7 +68,7 @@ export default async (request: Request, context: Context) => { }; function buildRewrite(originalRequest: Request): (Request | null) { - const extractResult = legitimateRequestRegex.exec(new URL(originalRequest.url).pathname); + const extractResult = SchemasRelatedRequestRegex.exec(new URL(originalRequest.url).pathname); if (extractResult === null) { return null; }