feat: content too large
This commit is contained in:
@@ -8,6 +8,7 @@ ENV HOST=localhost
|
|||||||
ENV PORT=8080
|
ENV PORT=8080
|
||||||
ENV BIND=0.0.0.0
|
ENV BIND=0.0.0.0
|
||||||
ENV DATA_DIR=/data
|
ENV DATA_DIR=/data
|
||||||
|
ENV MAX_SIZE=2000000
|
||||||
|
|
||||||
RUN PIP_ROOT_USER_ACTION=ignore python3 -m pip install uv
|
RUN PIP_ROOT_USER_ACTION=ignore python3 -m pip install uv
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Stapler
|
# Stapler
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
usage: stapler [-h] [-p PORT] [--host HOST] [-d DATA_DIR] [-b BIND] [-t TOKEN]
|
usage: stapler [-h] [-p PORT] [--host HOST] [-d DATA_DIR] -t TOKEN [--max-size-bytes MAX_SIZE_BYTES] [-b BIND]
|
||||||
|
|
||||||
Static pages as simple as a gzip file
|
Static pages as simple as a gzip file
|
||||||
|
|
||||||
@@ -11,8 +11,10 @@ options:
|
|||||||
--host HOST server default host (default: localhost) (env var: HOST)
|
--host HOST server default host (default: localhost) (env var: HOST)
|
||||||
-d, --data-dir DATA_DIR
|
-d, --data-dir DATA_DIR
|
||||||
directory where files are/will be stored (default: ./data) (env var: DATA_DIR)
|
directory where files are/will be stored (default: ./data) (env var: DATA_DIR)
|
||||||
-b, --bind BIND server bind address (default: 0.0.0.0) (env var: BIND)
|
|
||||||
-t, --token TOKEN secret token for update requests (env var: TOKEN)
|
-t, --token TOKEN secret token for update requests (env var: TOKEN)
|
||||||
|
--max-size-bytes MAX_SIZE_BYTES
|
||||||
|
max size of accepted archives (in bytes) (default: 2000000 -> 2MB) (env var: MAX_SIZE)
|
||||||
|
-b, --bind BIND server bind address (default: 0.0.0.0) (env var: BIND)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Endpoints
|
## Endpoints
|
||||||
@@ -51,7 +53,7 @@ curl -X DELETE \
|
|||||||
- [x] env instead of args when available
|
- [x] env instead of args when available
|
||||||
- [x] PUT gzip data into /data/xxx
|
- [x] PUT gzip data into /data/xxx
|
||||||
- [x] DELETE request
|
- [x] DELETE request
|
||||||
- [ ] max file size
|
- [x] max file size
|
||||||
- [ ] CNAME in /data/xxx can be translated as host in GET /
|
- [ ] CNAME in /data/xxx can be translated as host in GET /
|
||||||
- [ ] header to setup CNAME file instead of in archive
|
- [ ] header to setup CNAME file instead of in archive
|
||||||
- [ ] cerbot install in container + path env/arg
|
- [ ] cerbot install in container + path env/arg
|
||||||
|
|||||||
+13
-6
@@ -13,6 +13,7 @@ class Parameters:
|
|||||||
data_dir: str
|
data_dir: str
|
||||||
bind: str
|
bind: str
|
||||||
token: str
|
token: str
|
||||||
|
max_size_bytes: int
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_namespace(cls, args: argparse.Namespace) -> "Parameters":
|
def from_namespace(cls, args: argparse.Namespace) -> "Parameters":
|
||||||
@@ -54,12 +55,6 @@ def parse_parameters() -> Parameters:
|
|||||||
default=__get_env_str("DATA_DIR", os.path.join(os.getcwd(), "data")),
|
default=__get_env_str("DATA_DIR", os.path.join(os.getcwd(), "data")),
|
||||||
help="directory where files are/will be stored (default: ./data) (env var: DATA_DIR)",
|
help="directory where files are/will be stored (default: ./data) (env var: DATA_DIR)",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
"-b",
|
|
||||||
"--bind",
|
|
||||||
default=__get_env_str("BIND", "0.0.0.0"),
|
|
||||||
help="server bind address (default: 0.0.0.0) (env var: BIND)",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-t",
|
"-t",
|
||||||
"--token",
|
"--token",
|
||||||
@@ -67,5 +62,17 @@ def parse_parameters() -> Parameters:
|
|||||||
default=os.getenv("TOKEN"),
|
default=os.getenv("TOKEN"),
|
||||||
help="secret token for update requests (env var: TOKEN)",
|
help="secret token for update requests (env var: TOKEN)",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--max-size-bytes",
|
||||||
|
type=int,
|
||||||
|
default=__get_env_int("MAX_SIZE", 2000000),
|
||||||
|
help="max size of accepted archives (in bytes) (default: 2000000 -> 2MB) (env var: MAX_SIZE)",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-b",
|
||||||
|
"--bind",
|
||||||
|
default=__get_env_str("BIND", "0.0.0.0"),
|
||||||
|
help="server bind address (default: 0.0.0.0) (env var: BIND)",
|
||||||
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
return Parameters.from_namespace(args)
|
return Parameters.from_namespace(args)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class _StaplerRequestHandler(http.server.SimpleHTTPRequestHandler):
|
|||||||
self.default_host = params.host
|
self.default_host = params.host
|
||||||
self.token = params.token
|
self.token = params.token
|
||||||
self.data_dir = params.data_dir
|
self.data_dir = params.data_dir
|
||||||
|
self.max_size_bytes = params.max_size_bytes
|
||||||
super().__init__(*args, directory=params.data_dir, **kwargs)
|
super().__init__(*args, directory=params.data_dir, **kwargs)
|
||||||
|
|
||||||
def list_directory(self, *_, **__):
|
def list_directory(self, *_, **__):
|
||||||
@@ -36,6 +37,8 @@ class _StaplerRequestHandler(http.server.SimpleHTTPRequestHandler):
|
|||||||
content_length = int(self.headers["Content-Length"])
|
content_length = int(self.headers["Content-Length"])
|
||||||
if content_length == 0:
|
if content_length == 0:
|
||||||
return self.send_error(http.HTTPStatus.LENGTH_REQUIRED, "No body found")
|
return self.send_error(http.HTTPStatus.LENGTH_REQUIRED, "No body found")
|
||||||
|
if content_length > self.max_size_bytes:
|
||||||
|
return self.send_error(http.HTTPStatus.CONTENT_TOO_LARGE, "Archive too large")
|
||||||
try:
|
try:
|
||||||
file_bytes = io.BytesIO(self.rfile.read(content_length))
|
file_bytes = io.BytesIO(self.rfile.read(content_length))
|
||||||
target_path = os.path.join(self.data_dir, sub_path)
|
target_path = os.path.join(self.data_dir, sub_path)
|
||||||
|
|||||||
Reference in New Issue
Block a user