Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | 168x 141x 141x 141x 141x 141x 27x 27x 27x 27x 27x 7x 141x 172x 172x 77x 27x 77x 172x 78x 78x 172x 172x 172x 1x 1x 197x 197x 197x 196x 258x 95x 95x 101x 1x 172x 172x | import {
getScriptDownloadPath,
getGetResultPath,
WorkerEnv,
getStatusPagePath,
getIntegrationPathDepth,
getIngressBaseHost,
isScriptDownloadPathSet,
isGetResultPathSet,
} from './env'
import { handleApiRequest, handleStatusPage } from './handlers'
import { getIngressEndpoint, createRoutePathPrefix, stripPrefixPathSegments, getAgentScriptEndpoint } from './utils'
export type Route = {
/**
* The route will match if request URL path after the integration
* path is:
* - `/${pathPrefix}`
* - `/${pathPrefix}/.*`
*/
pathPrefix: string
/**
* The request handler for the route
*
* @param request the {@link Request} the worker received
* @param env the {@link WorkerEnv}
* @param receivedRequestURL the {@link URL} for the received request
* @param targetPath the URL path with the integration path removed
* @returns the {@link Response} to return to the client
*/
handler: (
request: Request,
env: WorkerEnv,
receivedRequestURL: URL,
targetPath: string
) => Response | Promise<Response>
}
function copySearchParams(oldURL: URL, newURL: URL): void {
newURL.search = new URLSearchParams(oldURL.search).toString()
}
function createIngressRequestURL(env: WorkerEnv, receivedRequestURL: URL, targetPath: string) {
const ingressBaseUrl = getIngressBaseHost(env)
const endpoint = getIngressEndpoint(ingressBaseUrl, receivedRequestURL.searchParams, targetPath)
const newURL = new URL(endpoint)
copySearchParams(receivedRequestURL, newURL)
return newURL
}
function createAgentScriptURL(env: WorkerEnv, receivedRequestURL: URL) {
const ingressBaseUrl = getIngressBaseHost(env)
// In V4, the Indentification API (Ingress) host also works as a proxy for the JavaScript agent CDN
// that's why we are passing it here
const agentScriptEndpoint = getAgentScriptEndpoint(ingressBaseUrl, receivedRequestURL.searchParams)
const newURL = new URL(agentScriptEndpoint)
copySearchParams(receivedRequestURL, newURL)
return newURL
}
const DEFAULT_ROUTE: Route['handler'] = (request, env, receivedRequestURL, targetPath) =>
handleApiRequest(request, env, createIngressRequestURL(env, receivedRequestURL, targetPath))
function createRoutes(env: WorkerEnv): Route[] {
const routes: Route[] = []
if (isScriptDownloadPathSet(env)) {
const downloadScriptRoute: Route = {
pathPrefix: createRoutePathPrefix(getScriptDownloadPath(env)),
handler: (request, env, receivedRequestURL) =>
handleApiRequest(request, env, createAgentScriptURL(env, receivedRequestURL)),
}
routes.push(downloadScriptRoute)
}
if (isGetResultPathSet(env)) {
const ingressAPIRoute: Route = {
pathPrefix: createRoutePathPrefix(getGetResultPath(env)),
handler: DEFAULT_ROUTE,
}
routes.push(ingressAPIRoute)
}
const statusRoute: Route = {
pathPrefix: createRoutePathPrefix(getStatusPagePath()),
handler: handleStatusPage,
}
routes.push(statusRoute)
return routes
}
function handleNoMatch(urlPathname: string): Response {
const responseHeaders = new Headers({
'content-type': 'application/json',
})
return new Response(JSON.stringify({ error: `unmatched path ${urlPathname}` }), {
status: 404,
headers: responseHeaders,
})
}
export function handleRequestWithRoutes(
request: Request,
env: WorkerEnv,
routes: Route[]
): Promise<Response> | Response {
const url = new URL(request.url)
const routeMatchingPath = stripPrefixPathSegments(url, getIntegrationPathDepth(env))
if (routeMatchingPath) {
for (const route of routes) {
if (routeMatchingPath === route.pathPrefix || routeMatchingPath.startsWith(`${route.pathPrefix}/`)) {
const targetPath = routeMatchingPath.slice(route.pathPrefix.length) || '/'
return route.handler(request, env, url, targetPath)
}
}
// If the request doesn't match any of the routes, handle it as an API request.
return DEFAULT_ROUTE(request, env, url, routeMatchingPath)
}
// This should not occur in practice because the route patterns for
// the worker are expected to prevent this case.
return handleNoMatch(url.pathname)
}
export async function handleRequest(request: Request, env: WorkerEnv): Promise<Response> {
const routes = createRoutes(env)
return handleRequestWithRoutes(request, env, routes)
}
|