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 | 162x 138x 138x 138x 138x 138x 24x 24x 24x 24x 24x 6x 138x 166x 166x 74x 24x 74x 166x 75x 75x 166x 166x 166x 1x 1x 191x 191x 191x 190x 252x 92x 92x 98x 1x 166x 166x | 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)
}
|