Skip to content

Commit 096b8b4

Browse files
committed
Merge branch 'master' into v3
2 parents 978cec5 + d08310a commit 096b8b4

File tree

9 files changed

+133
-51
lines changed

9 files changed

+133
-51
lines changed

.gitignore

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
/vendor
22
/.idea
3-
/tests/Bridge/Symfony/var
4-
/tests/Bridge/Symfony/cache
5-
/tests/Bridge/Symfony/logs
63
/.bref/
74
/.phpcs-cache
85
/composer.lock
9-
/.couscous/
106
/website/node_modules/
11-
/website/template/output.css
12-
/.netlify/
137
.DS_Store
148
/.serverless/
159
.phpunit.result.cache

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2022 Matthieu Napoli
3+
Copyright (c) 2025 Matthieu Napoli
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

Makefile

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
.EXPORT_ALL_VARIABLES:
22

3-
trigger_runtimes:
4-
aws codepipeline start-pipeline-execution --name bref-php-binary
5-
6-
runtime_build_status:
7-
aws codepipeline get-pipeline-state --name=bref-php-binary | jq ".stageStates[1].latestExecution.status"
8-
93
layers.json:
104
php utils/layers.json/update.php
115

@@ -15,4 +9,4 @@ test-stack:
159
preview:
1610
cd website && make preview
1711

18-
.PHONY: demo layers.json test-stack
12+
.PHONY: layers.json test-stack

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"psr/http-message": "^1.0|^2.0",
3131
"psr/http-server-handler": "^1.0",
3232
"riverline/multipart-parser": "^2.1.2",
33-
"symfony/process": "^4.4|^5.0|^6.0|^7.0"
33+
"symfony/process": "^4.4|^5.0|^6.0|^7.0|^8.0"
3434
},
3535
"require-dev": {
3636
"async-aws/core": "^1.0",
@@ -42,8 +42,8 @@
4242
"guzzlehttp/guzzle": "^7.5",
4343
"phpstan/phpstan": "^1.10.26",
4444
"phpunit/phpunit": "^9.6.10",
45-
"symfony/console": "^4.4|^5.0|^6.0|^7.0",
46-
"symfony/yaml": "^4.4|^5.0|^6.0|^7.0"
45+
"symfony/console": "^4.4|^5.0|^6.0|^7.0|^8.0",
46+
"symfony/yaml": "^4.4|^5.0|^6.0|^7.0|^8.0"
4747
},
4848
"scripts": {
4949
"test": [

docs/laravel/caching.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ By default, the Bref bridge will move Laravel's storage and cache directories to
44

55
However, the `/tmp` directory isn't shared across Lambda instances. If you Lambda function scales up or is redeployed, the cache will be empty in new instances.
66

7-
If you want the cache to be shared across all Lambda instances, for example if your application caches a lot of data or if you use it for locking mechanisms (like API rate limiting), you can instead use Redis or DynamoDB.
7+
If you want the cache to be shared across all Lambda instances, for example if your application caches a lot of data or if you use it for locking mechanisms (like API rate limiting), you can instead use the database, Redis, or DynamoDB.
88

9-
DynamoDB is the easiest to set up and is "pay per use". Redis is a bit more complex as it requires a VPC and managing instances, but offers slightly faster response times.
9+
If you are using a database already, using it as the cache driver is the simplest option. DynamoDB is a good alternative: fairly easy to set up, and "pay per use". Redis is a bit more complex as it requires a VPC and managing instances, but offers slightly faster response times.
1010

1111
## DynamoDB Cache
1212

docs/setup/minimal-aws-policy.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Feel free to submit a PR if you have any suggestions for improvements.
6666
"iam:DeleteRolePolicy",
6767
"iam:DetachRolePolicy",
6868
"iam:GetRole",
69+
"iam:TagRole",
6970
"iam:PassRole",
7071
"iam:PutRolePolicy",
7172
"iot:CreateTopicRule",

src/Event/Http/HttpHandler.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ public function handle($event, Context $context): array
2525
$response = $this->handleRequest($httpEvent, $context);
2626

2727
if ($httpEvent->isFormatV2()) {
28-
return $response->toApiGatewayFormatV2();
28+
return $response->toApiGatewayFormatV2($context->getAwsRequestId());
2929
}
3030

31-
return $response->toApiGatewayFormat($httpEvent->hasMultiHeader());
31+
return $response->toApiGatewayFormat($httpEvent->hasMultiHeader(), $context->getAwsRequestId());
3232
}
3333
}

src/Event/Http/HttpResponse.php

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function __construct(string $body, array $headers = [], int $statusCode =
2121
$this->statusCode = $statusCode;
2222
}
2323

24-
public function toApiGatewayFormat(bool $multiHeaders = false): array
24+
public function toApiGatewayFormat(bool $multiHeaders = false, ?string $awsRequestId = null): array
2525
{
2626
$base64Encoding = (bool) getenv('BREF_BINARY_RESPONSES');
2727

@@ -38,6 +38,8 @@ public function toApiGatewayFormat(bool $multiHeaders = false): array
3838
}
3939
}
4040

41+
$this->checkHeadersSize($headers, $awsRequestId);
42+
4143
// The headers must be a JSON object. If the PHP array is empty it is
4244
// serialized to `[]` (we want `{}`) so we force it to an empty object.
4345
$headers = empty($headers) ? new \stdClass : $headers;
@@ -58,7 +60,7 @@ public function toApiGatewayFormat(bool $multiHeaders = false): array
5860
/**
5961
* See https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.response
6062
*/
61-
public function toApiGatewayFormatV2(): array
63+
public function toApiGatewayFormatV2(?string $awsRequestId = null): array
6264
{
6365
$base64Encoding = (bool) getenv('BREF_BINARY_RESPONSES');
6466

@@ -76,6 +78,11 @@ public function toApiGatewayFormatV2(): array
7678
}
7779
}
7880

81+
$this->checkHeadersSize(array_merge(
82+
$headers,
83+
['Set-Cookie' => $cookies], // include cookies in the size check
84+
), $awsRequestId);
85+
7986
// The headers must be a JSON object. If the PHP array is empty it is
8087
// serialized to `[]` (we want `{}`) so we force it to an empty object.
8188
$headers = empty($headers) ? new \stdClass : $headers;
@@ -98,4 +105,31 @@ private function capitalizeHeaderName(string $name): string
98105
$name = ucwords($name);
99106
return str_replace(' ', '-', $name);
100107
}
108+
109+
/**
110+
* API Gateway v1 and v2 have a headers total max size of 10 KB.
111+
* ALB has a max size of 32 KB.
112+
* It's hard to calculate the exact size of headers here, so we just
113+
* estimate it roughly: if above 9.5 KB we log a warning.
114+
*
115+
* @param array<string|string[]> $headers
116+
*/
117+
private function checkHeadersSize(array $headers, ?string $awsRequestId): void
118+
{
119+
$estimatedHeadersSize = 0;
120+
foreach ($headers as $name => $values) {
121+
$estimatedHeadersSize += strlen($name);
122+
if (is_array($values)) {
123+
foreach ($values as $value) {
124+
$estimatedHeadersSize += strlen($value);
125+
}
126+
} else {
127+
$estimatedHeadersSize += strlen($values);
128+
}
129+
}
130+
131+
if ($estimatedHeadersSize > 9_500) {
132+
echo "$awsRequestId\tWARNING\tThe total size of HTTP response headers is estimated to be above 10 KB, which is the API Gateway limit. If the limit is reached, the HTTP response will be a 500 error.\n";
133+
}
134+
}
101135
}

0 commit comments

Comments
 (0)