All files / src/handlers handleIngressAPI.ts

100% Statements 37/37
80% Branches 4/5
100% Functions 8/8
100% Lines 34/34

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 804x 4x                   40x               40x 40x 40x 40x 40x   40x               30x   30x 30x 30x 30x 30x 30x 30x 30x   30x               10x   10x 10x 10x   10x 10x   10x     4x 40x 10x 10x   2x       30x 30x   3x      
import { getIngressBaseHost, WorkerEnv } from '../env'
import {
  addProxyIntegrationHeaders,
  addTrafficMonitoringSearchParamsForVisitorIdRequest,
  createErrorResponseForIngress,
  filterCookies,
  getVisitorIdEndpoint,
  createFallbackErrorResponse,
} from '../utils'
 
function copySearchParams(oldURL: URL, newURL: URL): void {
  newURL.search = new URLSearchParams(oldURL.search).toString()
}
 
function createRequestURL(
  ingressBaseUrl: string,
  receivedRequestURL: string,
  routeMatches: RegExpMatchArray | undefined
) {
  const routeSuffix = routeMatches ? routeMatches[1] : undefined
  const oldURL = new URL(receivedRequestURL)
  const endpoint = getVisitorIdEndpoint(ingressBaseUrl, oldURL.searchParams, routeSuffix)
  const newURL = new URL(endpoint)
  copySearchParams(oldURL, newURL)
 
  return newURL
}
 
async function makeIngressRequest(
  receivedRequest: Request,
  env: WorkerEnv,
  routeMatches: RegExpMatchArray | undefined
) {
  const ingressBaseUrl = getIngressBaseHost(env)!
 
  const requestURL = createRequestURL(ingressBaseUrl, receivedRequest.url, routeMatches)
  addTrafficMonitoringSearchParamsForVisitorIdRequest(requestURL)
  let headers = new Headers(receivedRequest.headers)
  headers = filterCookies(headers, (key) => key === '_iidt')
  addProxyIntegrationHeaders(headers, receivedRequest.url, env)
  const body = await (receivedRequest.headers.get('Content-Type') ? receivedRequest.blob() : Promise.resolve(null))
  console.log(`sending ingress request to ${requestURL}...`)
  const request = new Request(requestURL, new Request(receivedRequest, { headers, body }))
 
  return fetch(request).then((oldResponse) => new Response(oldResponse.body, oldResponse))
}
 
function makeCacheEndpointRequest(
  receivedRequest: Request,
  env: WorkerEnv,
  routeMatches: RegExpMatchArray | undefined
) {
  const ingressBaseUrl = getIngressBaseHost(env)!
 
  const requestURL = createRequestURL(ingressBaseUrl, receivedRequest.url, routeMatches)
  const headers = new Headers(receivedRequest.headers)
  headers.delete('Cookie')
 
  console.log(`sending cache request to ${requestURL}...`)
  const request = new Request(requestURL, new Request(receivedRequest, { headers }))
 
  return fetch(request).then((oldResponse) => new Response(oldResponse.body, oldResponse))
}
 
export async function handleIngressAPI(request: Request, env: WorkerEnv, routeMatches: RegExpMatchArray | undefined) {
  if (request.method === 'GET') {
    try {
      return await makeCacheEndpointRequest(request, env, routeMatches)
    } catch (e) {
      return createFallbackErrorResponse(e)
    }
  }
 
  try {
    return await makeIngressRequest(request, env, routeMatches)
  } catch (e) {
    return createErrorResponseForIngress(request, e)
  }
}