FAQ | This is a LIVE service | Changelog

Skip to content
Snippets Groups Projects
Commit 31c3ec03 authored by Dave Hart's avatar Dave Hart :pizza:
Browse files

feat: add max HTTP request size setting and increase default

Default maximum size of an HTTP request to be proxied is now 100MiB (was
1MiB), and is a setting that can be viewed in the UI and set and run time
via the `GATEWAY_MAX_REQUEST_SIZE` environment variable.

Run linting via pre-commit hook (or manually).

Update version of Auto-DevOps used in CI.
parent a58c9355
No related branches found
No related tags found
1 merge request!1Add max HTTP request size setting and increase default
Pipeline #408025 passed
include:
- project: 'uis/devops/continuous-delivery/ci-templates'
file: '/auto-devops/common-pipeline.yml'
ref: v2.4.0
ref: v3.0.0
variables:
DAST_DISABLED: "1"
......
......@@ -3,7 +3,7 @@
This is an _experimental_ emulator for the API Gateway
The docker packaging in this repo will spin up a proxy listening on port 9000
which forward requests to the URL pointed to by the
which forwards requests to the URL pointed to by the
`GATEWAY_PROXY_DESTINATION_URL` environment variable.
A proxy configuration UI is at port 9001.
......@@ -37,6 +37,30 @@ of the incoming request as a JSON document.
The issuer for the JWT is set such that you should be able to copy the JWT passed to the backend and
paste it into the https://jwt.io/ debugger and be able to validate the signature.
## Backend development
Install pipx following [the instructions on their site](https://pypa.github.io/pipx/), then
install the Python dependency manager and task runner:
```bash
$ pipx install poetry
$ pipx install poethepoet
```
The development environment can then be setup:
```bash
$ poetry install
$ poe setup
```
The pre-commit code checks (linting) should be performed automatically when committing to git
(assuming `poe setup` has previously been run). To run the checks manually:
```bash
$ poe fix
```
## Frontend development
You can install and start a development server as usual by running `yarn install` and `yarn start`
......
......@@ -47,6 +47,9 @@ class Settings(pydantic.BaseSettings):
jwt_key_id: str = pydantic.Field(default_factory=token_hex)
# Max size (in bytes) of an HTTP request that can be proxied
max_request_size = 100 * (2**20)
class Config:
env_prefix = "gateway_"
......@@ -73,6 +76,7 @@ reverse_proxy = ReverseProxy(
application_id=settings.application_id,
application_class=settings.application_class,
organisation_id=settings.organisation_id,
max_request_size=settings.max_request_size,
)
......@@ -110,6 +114,7 @@ class ProxyStatus(pydantic.BaseModel):
application_id: str
application_class: str
organisation_id: str
max_request_size: int
class Config:
alias_generator = camelcase
......
......@@ -28,6 +28,7 @@ class ReverseProxy:
application_id="",
application_class="",
organisation_id="",
max_request_size=0,
):
self.destination_url = destination_url
self.jwt_factory = jwt_factory
......@@ -41,10 +42,11 @@ class ReverseProxy:
self.application_id = application_id
self.application_class = application_class
self.organisation_id = organisation_id
self.max_request_size = max_request_size
async def serve(self):
# Configure the aiohttp web server application for the proxy.
proxy_app = aiohttp.web.Application()
proxy_app = aiohttp.web.Application(client_max_size=self.max_request_size)
proxy_app.router.add_route("*", "/{path:.*}", self._handle_request)
proxy_runner = aiohttp.web.AppRunner(proxy_app)
await proxy_runner.setup()
......
......@@ -2,7 +2,11 @@ import React from "react";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Card from '@mui/material/Card';
import Grid from "@mui/material/Grid";
import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem";
import ListItemText from "@mui/material/ListItemText";
import MenuItem from "@mui/material/MenuItem";
import InputAdornment from "@mui/material/InputAdornment";
import TextField from "@mui/material/TextField";
......@@ -24,6 +28,7 @@ interface FormState {
applicationId: string;
applicationClass: "public" | "confidential";
organisationId: string;
maxRequestSize: number;
}
const INITIAL_FORM_STATE: FormState = {
......@@ -38,6 +43,7 @@ const INITIAL_FORM_STATE: FormState = {
applicationId: "",
applicationClass: "public",
organisationId: "",
maxRequestSize: 0,
};
const USER_SUFFICES = {
......@@ -309,6 +315,22 @@ const ProxyForm = () => {
error={!!errors.organisationId}
helperText={errors.organisationId}
/>
<Typography variant="subtitle1">Read-only settings</Typography>
<Card variant="outlined">
<List dense>
<ListItem
secondaryAction={
<Typography variant="body2">
{fetchedState ? fetchedState.maxRequestSize : ""}
</Typography>
}
>
<ListItemText
primary="Maximum HTTP request size (bytes)"
/>
</ListItem>
</List>
</Card>
<Grid container spacing={2} marginTop={1}>
<Grid item xs={6}>
<Button
......
......@@ -19,6 +19,7 @@ export interface ProxyState {
applicationId: string;
applicationClass: string;
organisationId: string;
maxRequestSize: number;
}
export interface ProxyConfigurationPatch {
......
......@@ -22,6 +22,16 @@ case-converter = "^1.1.0"
cryptography = "^41.0.4"
jwcrypto = "^1.5.0"
[tool.poetry.group.dev.dependencies]
pre-commit = "^3.4.0"
[tool.poe.tasks.setup]
help = "Setup the application for local development"
cmd = "pre-commit install"
[tool.poe.tasks.fix]
help = "Run pre-commit checks to fix formatting errors"
cmd = "pre-commit run --all-files"
[build-system]
requires = ["poetry-core"]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment