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 | 5x 5x 5x 5x 5x 5x 198x 66x 66x 121x 86x 86x 6x 86x 66x 66x 66x 66x 66x 66x 66x 66x 11x 11x 37x 37x 18x 18x 66x 66x 66x 66x 66x 66x 66x 66x 39x 66x | import { CloudFrontRequest, CloudFrontResultResponse } from 'aws-lambda'
import { getBehaviorPathNestLevel, getFpIngressBaseHost } from '../utils/customer-variables/selectors'
import { CustomerVariables } from '../utils/customer-variables/customer-variables'
import { addTrafficMonitoring, prepareHeadersForIngressRequest } from '../utils'
import { getValidRegion, isMethodAuthorized } from '../utils/request'
import { extractIngressPath, getIngressAPIHost, getV3AgentPath, INGRESS_CDN_PATH } from '../utils/paths'
import { sendIngressRequest } from '../utils/transport'
import { Region } from '../model'
export type RequestType = 'agentV3' | 'ingressV3' | 'v4'
export function createIngressHandler(requestType: RequestType) {
return (
incomingRequest: CloudFrontRequest,
customerVariables: CustomerVariables,
pathMatches: RegExpMatchArray | undefined
) => handleIngress(incomingRequest, customerVariables, pathMatches, requestType)
}
/**
* Processes a query string and appends the parameters to the URL's search params,
* replacing the value of the "region" parameter if found.
*
* @param {string} queryString - The query string containing key-value pairs to be processed.
* @param {URL} url - The URL object to which the search parameters will be appended.
* @param {Region} region - The region value to insert or replace in the query string.
*/
function setupSearchParams(queryString: string, url: URL, region: Region) {
decodeURIComponent(queryString)
.split('&')
.filter((it) => it.includes('='))
.forEach((it) => {
const kv = it.split('=')
if (kv[0] === 'region') {
kv[1] = region
}
url.searchParams.append(kv[0], kv[1])
})
}
/**
* Handles an ingress request by preparing the request's path, headers, and forwarding it to the appropriate API destination.
*
* @param {CloudFrontRequest} incomingRequest - The incoming request object provided by CloudFront, containing details such as URI, method, and query string.
* @param {CustomerVariables} customerVariables - Configuration and settings specific to the customer, used to determine handling behavior.
* @param {RegExpMatchArray | undefined} pathMatches - A regular expression match array for the request path, used to extract specific components of the path.
* @param {RequestType} requestType - The type of request to handle, which governs behavior such as path handling and endpoint resolution.
* @return {Promise<CloudFrontResultResponse>} A Promise resolving to the resulting CloudFront response after forwarding the request to the target API endpoint.
*/
async function handleIngress(
incomingRequest: CloudFrontRequest,
customerVariables: CustomerVariables,
pathMatches: RegExpMatchArray | undefined,
requestType: RequestType
): Promise<CloudFrontResultResponse> {
// In V4, we need to leverage the new behavior path nest level variable to figure out the path for the ingress request
const useBehaviorPathNestLevel = requestType === 'v4'
const behaviorPathNestLevel = useBehaviorPathNestLevel ? await getBehaviorPathNestLevel(customerVariables) : 0
const ingressBaseHost = await getFpIngressBaseHost(customerVariables)
Iif (!ingressBaseHost) {
return {
status: '500',
}
}
const requestUrlParams = new URLSearchParams(incomingRequest.querystring)
const region = getValidRegion(requestUrlParams.get('region'))
let suffix = ''
switch (requestType) {
// For V3 request, we need to prepend the INGRESS_CDN_PATH to the request path
case 'agentV3':
suffix = `${INGRESS_CDN_PATH}/${getV3AgentPath(requestUrlParams)}`
break
// For V4 request, we just use the path from incoming request and leverage the behavior path nest level
case 'v4':
suffix = incomingRequest.uri
break
default:
// For the rest, so the "ingressV3" request, we'll extract path using path matches. It's an approach that was used in the old ingress handler.
if (pathMatches && pathMatches.length >= 1) {
suffix = pathMatches[1] ?? ''
}
}
const requestPathSegments = extractIngressPath(suffix, behaviorPathNestLevel)
const requestPath = requestPathSegments.join('/')
const isAuthorizedMethodCall = isMethodAuthorized(incomingRequest.method)
const requestHeaders = await prepareHeadersForIngressRequest(
incomingRequest,
customerVariables,
isAuthorizedMethodCall
)
const requestUrl = new URL(getIngressAPIHost(region, ingressBaseHost))
requestUrl.pathname = requestPath
setupSearchParams(incomingRequest.querystring, requestUrl, region)
if (isAuthorizedMethodCall) {
addTrafficMonitoring(requestUrl)
}
return sendIngressRequest(incomingRequest, requestHeaders, requestUrl)
}
|