Skip to content

Commit 0e04b84

Browse files
authored
Add x-amz-content-sha256 header to AskAi stream requests (#2137)
* Add x-amz-content-sha256 header to AskAi stream requests * Run prettier
1 parent 5d3b637 commit 0e04b84

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAi/useFetchEventSource.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ import {
55
} from '@microsoft/fetch-event-source'
66
import { useRef, useCallback } from 'react'
77

8+
/**
9+
* Computes SHA256 hash of the request body for CloudFront + Lambda Function URL with OAC.
10+
* Required by AWS CloudFront when using Origin Access Control with Lambda Function URLs.
11+
* See: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-lambda.html
12+
*/
13+
async function computeSHA256(data: string): Promise<string> {
14+
const encoder = new TextEncoder()
15+
const dataBuffer = encoder.encode(data)
16+
const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer)
17+
const hashArray = Array.from(new Uint8Array(hashBuffer))
18+
return hashArray.map((b) => ('0' + b.toString(16)).slice(-2)).join('')
19+
}
20+
821
// Simple wrapper interface around fetch-event-source
922
export interface UseFetchEventSourceOptions {
1023
apiEndpoint: string
@@ -47,13 +60,21 @@ export function useFetchEventSource<TPayload>({
4760
abortControllerRef.current = controller
4861

4962
try {
63+
// Stringify payload once to ensure hash matches the exact body sent
64+
const bodyString = JSON.stringify(payload)
65+
66+
// Compute SHA256 hash for CloudFront + Lambda Function URL with OAC
67+
// This proves body integrity from client to CloudFront
68+
const contentHash = await computeSHA256(bodyString)
69+
5070
await fetchEventSource(apiEndpoint, {
5171
method: 'POST',
5272
headers: {
5373
'Content-Type': 'application/json',
74+
'x-amz-content-sha256': contentHash, // Required for CloudFront OAC
5475
...headers,
5576
},
56-
body: JSON.stringify(payload),
77+
body: bodyString,
5778
signal: controller.signal, // Use local controller, not ref
5879
onopen: async (response: Response) => {
5980
if (

0 commit comments

Comments
 (0)