fix: no message on bare curl
This commit is contained in:
@@ -112,33 +112,33 @@ PUT /{page}/
|
|||||||
```bash
|
```bash
|
||||||
# create archive from 'dist' dir and upload it to /my-project/
|
# create archive from 'dist' dir and upload it to /my-project/
|
||||||
tar -czC dist -f dist.tar.gz .
|
tar -czC dist -f dist.tar.gz .
|
||||||
curl -v -X PUT \
|
curl -X PUT \
|
||||||
-H 'X-Token: <TOKEN>' \
|
-H 'X-Token: <TOKEN>' \
|
||||||
--data-binary "@dist.tar.gz" \
|
--data-binary "@dist.tar.gz" \
|
||||||
https://stapler-host/my-project/
|
https://stapler-host/my-project/
|
||||||
|
|
||||||
# same thing but one-liner
|
# same thing but one-liner
|
||||||
tar -czC dist . | curl -v -X PUT \
|
tar -czC dist . | curl -X PUT \
|
||||||
-H 'X-Token: <TOKEN>' \
|
-H 'X-Token: <TOKEN>' \
|
||||||
--data-binary @- \
|
--data-binary @- \
|
||||||
https://stapler-host/my-project/
|
https://stapler-host/my-project/
|
||||||
|
|
||||||
# make stapler server identify myproject.example.com and /my-project/
|
# make stapler server identify myproject.example.com and /my-project/
|
||||||
tar -czC dist . | curl -v -X PUT \
|
tar -czC dist . | curl -X PUT \
|
||||||
--data-binary @- \
|
--data-binary @- \
|
||||||
-H 'X-Token: <TOKEN>' \
|
-H 'X-Token: <TOKEN>' \
|
||||||
-H 'X-Host: myproject.example.com' \
|
-H 'X-Host: myproject.example.com' \
|
||||||
https://stapler-host/my-project/
|
https://stapler-host/my-project/
|
||||||
|
|
||||||
# make stapler server identifiers myproject.example.com only
|
# make stapler server identifiers myproject.example.com only
|
||||||
tar -czC dist . | curl -v -X PUT \
|
tar -czC dist . | curl -X PUT \
|
||||||
--data-binary @- \
|
--data-binary @- \
|
||||||
-H 'X-Token: <TOKEN>' \
|
-H 'X-Token: <TOKEN>' \
|
||||||
-H 'X-Host-Only: myproject.example.com' \
|
-H 'X-Host-Only: myproject.example.com' \
|
||||||
https://stapler-host/my-project/
|
https://stapler-host/my-project/
|
||||||
|
|
||||||
# make a SPA site at /my-project/index.html
|
# make a SPA site at /my-project/index.html
|
||||||
tar -czC dist . | curl -v -X PUT \
|
tar -czC dist . | curl -X PUT \
|
||||||
--data-binary @- \
|
--data-binary @- \
|
||||||
-H 'X-Token: <TOKEN>' \
|
-H 'X-Token: <TOKEN>' \
|
||||||
-H 'X-SPA: index.html' \
|
-H 'X-SPA: index.html' \
|
||||||
@@ -160,13 +160,13 @@ PUT /{page}/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# create /my-project/ that redirects to https://github.com/my-project
|
# create /my-project/ that redirects to https://github.com/my-project
|
||||||
curl -v -X PUT \
|
curl -X PUT \
|
||||||
-H 'X-Token: <TOKEN>' \
|
-H 'X-Token: <TOKEN>' \
|
||||||
-H 'X-Redirect: https://github.com/my-project' \
|
-H 'X-Redirect: https://github.com/my-project' \
|
||||||
https://stapler-host/my-project/
|
https://stapler-host/my-project/
|
||||||
|
|
||||||
# simple redirect from root host to www
|
# simple redirect from root host to www
|
||||||
curl -v -X PUT \
|
curl -X PUT \
|
||||||
-H 'X-Token: <TOKEN>' \
|
-H 'X-Token: <TOKEN>' \
|
||||||
-H 'X-Proxy: https://www.my-website.com' \
|
-H 'X-Proxy: https://www.my-website.com' \
|
||||||
-H 'X-Host: my-website.com' \
|
-H 'X-Host: my-website.com' \
|
||||||
@@ -185,7 +185,7 @@ PUT /{page}/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# create /my-website/ that proxies to http://host.containers.internal:8000
|
# create /my-website/ that proxies to http://host.containers.internal:8000
|
||||||
curl -v -X PUT \
|
curl -X PUT \
|
||||||
-H 'X-Token: <TOKEN>' \
|
-H 'X-Token: <TOKEN>' \
|
||||||
-H 'X-Proxy: http://host.containers.internal:8000' \
|
-H 'X-Proxy: http://host.containers.internal:8000' \
|
||||||
https://stapler-host/my-project/
|
https://stapler-host/my-project/
|
||||||
@@ -200,7 +200,7 @@ DELETE /{page}/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# delete /my-project/
|
# delete /my-project/
|
||||||
curl -v -X DELETE \
|
curl -X DELETE \
|
||||||
-H 'X-Token: <TOKEN>' \
|
-H 'X-Token: <TOKEN>' \
|
||||||
https://stapler-host/my-project/
|
https://stapler-host/my-project/
|
||||||
```
|
```
|
||||||
@@ -226,7 +226,11 @@ curl -v -X DELETE \
|
|||||||
- name: Create archive
|
- name: Create archive
|
||||||
run: tar -czC dist -f dist.tar.gz .
|
run: tar -czC dist -f dist.tar.gz .
|
||||||
- name: Deploy to Stapler server
|
- name: Deploy to Stapler server
|
||||||
run: curl -v -X PUT -H 'X-Token: ${{ secrets.STAPLER_TOKEN }}' -H 'X-Host: ${{ vars.TARGET_HOST }}' --data-binary "@dist.tar.gz" https://stapler-host/my-project/
|
run: |
|
||||||
|
curl -X PUT --data-binary "@dist.tar.gz" \
|
||||||
|
-H 'X-Token: ${{ secrets.STAPLER_TOKEN }}' \
|
||||||
|
-H 'X-Host: ${{ vars.TARGET_HOST }}' \
|
||||||
|
${{ vars.STAPLER_URL }}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Redirecting hosts with DNS
|
### Redirecting hosts with DNS
|
||||||
|
|||||||
+72
-57
@@ -45,13 +45,25 @@ class BaseHandler(abc.ABC, http.server.BaseHTTPRequestHandler):
|
|||||||
code: int,
|
code: int,
|
||||||
message: str | None = None,
|
message: str | None = None,
|
||||||
explain: str | None = None,
|
explain: str | None = None,
|
||||||
|
) -> None:
|
||||||
|
self.send_status(code, message, explain)
|
||||||
|
|
||||||
|
def send_status(
|
||||||
|
self,
|
||||||
|
code: int,
|
||||||
|
message: str | None = None,
|
||||||
|
explain: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
shortmsg, longmsg = self.responses[code]
|
shortmsg, longmsg = self.responses[code]
|
||||||
if message is None:
|
if message is None:
|
||||||
message = shortmsg
|
message = shortmsg
|
||||||
if explain is None:
|
if explain is None:
|
||||||
explain = longmsg
|
explain = longmsg
|
||||||
if "text/" in self._get_header("Accept"):
|
if (
|
||||||
|
not self._has_header("Accept")
|
||||||
|
or self._get_header("Accept").startswith("*/")
|
||||||
|
or self._get_header("Accept").startswith("text/")
|
||||||
|
):
|
||||||
self.send_basic_body(
|
self.send_basic_body(
|
||||||
f"{code} {message}\n{explain}\n\n{self.server_signature()}",
|
f"{code} {message}\n{explain}\n\n{self.server_signature()}",
|
||||||
code=code,
|
code=code,
|
||||||
@@ -339,28 +351,26 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler, BaseHandler):
|
|||||||
def do_PUT(self) -> None:
|
def do_PUT(self) -> None:
|
||||||
self._pre_log_request()
|
self._pre_log_request()
|
||||||
if self._proxy_or_redirect():
|
if self._proxy_or_redirect():
|
||||||
return None
|
return
|
||||||
if (path := self.__check_update_request()) is None:
|
if (path := self.__check_put_request()) is None:
|
||||||
return None
|
return
|
||||||
if not self.__check_put_headers():
|
|
||||||
return None
|
|
||||||
if (
|
|
||||||
self.has_target_host
|
|
||||||
and (page := self.registry.get_from_host(self.target_host)) is not None
|
|
||||||
and page.path != path
|
|
||||||
):
|
|
||||||
return self.send_error(http.HTTPStatus.FORBIDDEN, "Host already taken")
|
|
||||||
if self.has_target_redirect:
|
if self.has_target_redirect:
|
||||||
self._update_redirect(path)
|
if not self._update_redirect(path):
|
||||||
|
return
|
||||||
elif self.has_target_proxy:
|
elif self.has_target_proxy:
|
||||||
self._update_proxy(path)
|
if not self._update_proxy(path):
|
||||||
else:
|
return
|
||||||
self._update_extract(path)
|
elif not self._update_extract(path):
|
||||||
|
return
|
||||||
if self.has_request_host:
|
if self.has_request_host:
|
||||||
self.registry.set_host(path, self.target_host)
|
self.registry.set_host(path, self.target_host)
|
||||||
if self.has_request_host_only:
|
if self.has_request_host_only:
|
||||||
self.registry.set_host_only(path, self.target_host)
|
self.registry.set_host_only(path, self.target_host)
|
||||||
return None
|
self.send_status(
|
||||||
|
http.HTTPStatus.CREATED,
|
||||||
|
"Resource updated",
|
||||||
|
str(self.registry.get_from_path(path)),
|
||||||
|
)
|
||||||
|
|
||||||
def do_POST(self) -> None:
|
def do_POST(self) -> None:
|
||||||
self.do_PUT() # be gentle on them
|
self.do_PUT() # be gentle on them
|
||||||
@@ -371,10 +381,15 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler, BaseHandler):
|
|||||||
def do_DELETE(self) -> None:
|
def do_DELETE(self) -> None:
|
||||||
self._pre_log_request()
|
self._pre_log_request()
|
||||||
if self._proxy_or_redirect():
|
if self._proxy_or_redirect():
|
||||||
return None
|
return
|
||||||
if (path := self.__check_update_request()) is None:
|
if (path := self.__check_update_request()) is None:
|
||||||
return None
|
return
|
||||||
return self._update_remove(path)
|
if self._update_remove(path):
|
||||||
|
self.send_status(
|
||||||
|
http.HTTPStatus.OK,
|
||||||
|
f"Resource /{path}/ removed",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
def do_CONNECT(self) -> None:
|
def do_CONNECT(self) -> None:
|
||||||
self._pre_log_request()
|
self._pre_log_request()
|
||||||
@@ -391,73 +406,64 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler, BaseHandler):
|
|||||||
if not self._proxy_or_redirect():
|
if not self._proxy_or_redirect():
|
||||||
self.send_error(http.HTTPStatus.METHOD_NOT_ALLOWED)
|
self.send_error(http.HTTPStatus.METHOD_NOT_ALLOWED)
|
||||||
|
|
||||||
def _update_extract(self, path: str) -> None:
|
def _update_extract(self, path: str) -> bool:
|
||||||
if self.in_size == 0:
|
if self.in_size == 0:
|
||||||
return self.send_error(http.HTTPStatus.LENGTH_REQUIRED, "No body found")
|
self.send_error(http.HTTPStatus.LENGTH_REQUIRED, "No body found")
|
||||||
|
return False
|
||||||
if self.in_size > self.max_size_bytes:
|
if self.in_size > self.max_size_bytes:
|
||||||
return self.send_error(
|
self.send_error(
|
||||||
http.HTTPStatus.CONTENT_TOO_LARGE,
|
http.HTTPStatus.CONTENT_TOO_LARGE,
|
||||||
"Archive too large",
|
"Archive too large",
|
||||||
)
|
)
|
||||||
|
return False
|
||||||
try:
|
try:
|
||||||
file_bytes = io.BytesIO(self.rfile.read(self.in_size))
|
file_bytes = io.BytesIO(self.rfile.read(self.in_size))
|
||||||
self.data_dir.extract_tar_bytes(path, file_bytes)
|
self.data_dir.extract_tar_bytes(path, file_bytes)
|
||||||
except tarfile.TarError:
|
except tarfile.TarError:
|
||||||
return self.send_error(http.HTTPStatus.BAD_REQUEST, "Invalid tar archive")
|
self.send_error(http.HTTPStatus.BAD_REQUEST, "Invalid tar archive")
|
||||||
|
return False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return self.send_error(http.HTTPStatus.INTERNAL_SERVER_ERROR, str(e))
|
self.send_error(http.HTTPStatus.INTERNAL_SERVER_ERROR, str(e))
|
||||||
|
return False
|
||||||
self.registry.add(path)
|
self.registry.add(path)
|
||||||
self.token_manager.set_token(path, self.token)
|
self.token_manager.set_token(path, self.token)
|
||||||
if self.has_target_spa:
|
if self.has_target_spa:
|
||||||
self.registry.set_spa(path, self.target_spa)
|
self.registry.set_spa(path, self.target_spa)
|
||||||
self.send_status_only(
|
return True
|
||||||
http.HTTPStatus.CREATED,
|
|
||||||
f"Resource /{path}/ updated",
|
|
||||||
)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _update_redirect(self, path: str) -> None:
|
def _update_redirect(self, path: str) -> bool:
|
||||||
if self.in_size > 0:
|
if self.in_size > 0:
|
||||||
return self.send_error(
|
self.send_error(
|
||||||
http.HTTPStatus.BAD_REQUEST,
|
http.HTTPStatus.BAD_REQUEST,
|
||||||
f"No content must be sent with {self.REDIRECT_HEADER}",
|
f"No content must be sent with {self.REDIRECT_HEADER}",
|
||||||
)
|
)
|
||||||
|
return False
|
||||||
self.registry.set_redirect(path, self.target_redirect)
|
self.registry.set_redirect(path, self.target_redirect)
|
||||||
self.token_manager.set_token(path, self.token)
|
self.token_manager.set_token(path, self.token)
|
||||||
self.send_status_only(
|
return True
|
||||||
http.HTTPStatus.CREATED,
|
|
||||||
f"Resource /{path}/ updated",
|
|
||||||
)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _update_proxy(self, path: str) -> None:
|
def _update_proxy(self, path: str) -> bool:
|
||||||
if self.in_size > 0:
|
if self.in_size > 0:
|
||||||
return self.send_error(
|
self.send_error(
|
||||||
http.HTTPStatus.BAD_REQUEST,
|
http.HTTPStatus.BAD_REQUEST,
|
||||||
f"No content must be sent with {self.PROXY_HEADER}",
|
f"No content must be sent with {self.PROXY_HEADER}",
|
||||||
)
|
)
|
||||||
|
return False
|
||||||
self.registry.set_proxy(path, self.target_proxy)
|
self.registry.set_proxy(path, self.target_proxy)
|
||||||
self.token_manager.set_token(path, self.token)
|
self.token_manager.set_token(path, self.token)
|
||||||
self.send_status_only(
|
return True
|
||||||
http.HTTPStatus.CREATED,
|
|
||||||
f"Resource /{path}/ updated",
|
|
||||||
)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _update_remove(self, path: str) -> None:
|
def _update_remove(self, path: str) -> bool:
|
||||||
if not self.data_dir.exists(path):
|
if not self.data_dir.exists(path):
|
||||||
self.send_error(http.HTTPStatus.NOT_FOUND, "Not found")
|
self.send_error(http.HTTPStatus.NOT_FOUND, "Not found")
|
||||||
return None
|
return False
|
||||||
try:
|
try:
|
||||||
self.data_dir.remove(path)
|
self.data_dir.remove(path)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return self.send_error(http.HTTPStatus.INTERNAL_SERVER_ERROR, str(e))
|
self.send_error(http.HTTPStatus.INTERNAL_SERVER_ERROR, str(e))
|
||||||
self.send_status_only(
|
return False
|
||||||
http.HTTPStatus.NO_CONTENT,
|
|
||||||
f"Resource /{path}/ removed",
|
|
||||||
)
|
|
||||||
self.registry.remove(path)
|
self.registry.remove(path)
|
||||||
return None
|
return True
|
||||||
|
|
||||||
def _proxy_or_redirect(self) -> bool:
|
def _proxy_or_redirect(self) -> bool:
|
||||||
if self.has_token or self.path.startswith(self.CERTBOT_CHALLENGE_PATH):
|
if self.has_token or self.path.startswith(self.CERTBOT_CHALLENGE_PATH):
|
||||||
@@ -518,23 +524,32 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler, BaseHandler):
|
|||||||
return None
|
return None
|
||||||
return sub_path
|
return sub_path
|
||||||
|
|
||||||
def __check_put_headers(self) -> bool:
|
def __check_put_request(self) -> str | None:
|
||||||
|
if (path := self.__check_update_request()) is None:
|
||||||
|
return None
|
||||||
if self.has_request_host and self.has_request_host_only:
|
if self.has_request_host and self.has_request_host_only:
|
||||||
self.send_error(
|
self.send_error(
|
||||||
http.HTTPStatus.BAD_REQUEST,
|
http.HTTPStatus.BAD_REQUEST,
|
||||||
f"Cannot use {self.HOST_ONLY_HEADER} with {self.HOST_HEADER}",
|
f"Cannot use {self.HOST_ONLY_HEADER} with {self.HOST_HEADER}",
|
||||||
)
|
)
|
||||||
return False
|
return None
|
||||||
if self.has_target_host and not self.__valid_host(self.target_host):
|
if self.has_target_host and not self.__valid_host(self.target_host):
|
||||||
self.send_error(http.HTTPStatus.BAD_REQUEST, "Invalid requested host")
|
self.send_error(http.HTTPStatus.BAD_REQUEST, "Invalid requested host")
|
||||||
return False
|
return None
|
||||||
if self.has_target_proxy and self.has_target_redirect:
|
if self.has_target_proxy and self.has_target_redirect:
|
||||||
self.send_error(
|
self.send_error(
|
||||||
http.HTTPStatus.BAD_REQUEST,
|
http.HTTPStatus.BAD_REQUEST,
|
||||||
f"Cannot use {self.PROXY_HEADER} with {self.REDIRECT_HEADER}",
|
f"Cannot use {self.PROXY_HEADER} with {self.REDIRECT_HEADER}",
|
||||||
)
|
)
|
||||||
return False
|
return None
|
||||||
return True
|
if (
|
||||||
|
self.has_target_host
|
||||||
|
and (page := self.registry.get_from_host(self.target_host)) is not None
|
||||||
|
and page.path != path
|
||||||
|
):
|
||||||
|
self.send_error(http.HTTPStatus.FORBIDDEN, "Host already taken")
|
||||||
|
return None
|
||||||
|
return path
|
||||||
|
|
||||||
def __get_path(self, path: str, regex: re.Pattern) -> str | None:
|
def __get_path(self, path: str, regex: re.Pattern) -> str | None:
|
||||||
if (match := regex.match(path.lower())) is not None:
|
if (match := regex.match(path.lower())) is not None:
|
||||||
|
|||||||
+25
-11
@@ -136,6 +136,8 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
) -> RequestHandler:
|
) -> RequestHandler:
|
||||||
if headers is None:
|
if headers is None:
|
||||||
headers = {}
|
headers = {}
|
||||||
|
if "Accept" not in headers:
|
||||||
|
headers["Accept"] = "nothing"
|
||||||
with self.patch("http.server.BaseHTTPRequestHandler.__init__"):
|
with self.patch("http.server.BaseHTTPRequestHandler.__init__"):
|
||||||
handler = RequestHandler(
|
handler = RequestHandler(
|
||||||
unittest.mock.MagicMock(),
|
unittest.mock.MagicMock(),
|
||||||
@@ -433,8 +435,9 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
self.mock_call_unchecked(self.data_dir.extract_tar_bytes),
|
self.mock_call_unchecked(self.data_dir.extract_tar_bytes),
|
||||||
self.mock_call(self.registry.add, ["path"]),
|
self.mock_call(self.registry.add, ["path"]),
|
||||||
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
||||||
|
self.mock_call(self.registry.get_from_path, ["path"]),
|
||||||
self.expects_status_only(
|
self.expects_status_only(
|
||||||
handler, http.HTTPStatus.CREATED, "Resource /path/ updated"
|
handler, http.HTTPStatus.CREATED, "Resource updated"
|
||||||
),
|
),
|
||||||
self.seal_mocks(),
|
self.seal_mocks(),
|
||||||
):
|
):
|
||||||
@@ -458,8 +461,9 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
self.mock_call(self.registry.add, ["path"]),
|
self.mock_call(self.registry.add, ["path"]),
|
||||||
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
||||||
self.mock_call(self.registry.set_host, ["path", "example.com"]),
|
self.mock_call(self.registry.set_host, ["path", "example.com"]),
|
||||||
|
self.mock_call(self.registry.get_from_path, ["path"]),
|
||||||
self.expects_status_only(
|
self.expects_status_only(
|
||||||
handler, http.HTTPStatus.CREATED, "Resource /path/ updated"
|
handler, http.HTTPStatus.CREATED, "Resource updated"
|
||||||
),
|
),
|
||||||
self.seal_mocks(),
|
self.seal_mocks(),
|
||||||
):
|
):
|
||||||
@@ -481,8 +485,9 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
self.mock_call(self.registry.add, ["path"]),
|
self.mock_call(self.registry.add, ["path"]),
|
||||||
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
||||||
self.mock_call(self.registry.set_spa, ["path", "index.html"]),
|
self.mock_call(self.registry.set_spa, ["path", "index.html"]),
|
||||||
|
self.mock_call(self.registry.get_from_path, ["path"]),
|
||||||
self.expects_status_only(
|
self.expects_status_only(
|
||||||
handler, http.HTTPStatus.CREATED, "Resource /path/ updated"
|
handler, http.HTTPStatus.CREATED, "Resource updated"
|
||||||
),
|
),
|
||||||
self.seal_mocks(),
|
self.seal_mocks(),
|
||||||
):
|
):
|
||||||
@@ -530,8 +535,9 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
),
|
),
|
||||||
self.mock_call(self.registry.set_redirect, ["path", "https://example.com"]),
|
self.mock_call(self.registry.set_redirect, ["path", "https://example.com"]),
|
||||||
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
||||||
|
self.mock_call(self.registry.get_from_path, ["path"]),
|
||||||
self.expects_status_only(
|
self.expects_status_only(
|
||||||
handler, http.HTTPStatus.CREATED, "Resource /path/ updated"
|
handler, http.HTTPStatus.CREATED, "Resource updated"
|
||||||
),
|
),
|
||||||
self.seal_mocks(),
|
self.seal_mocks(),
|
||||||
):
|
):
|
||||||
@@ -557,8 +563,9 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
self.mock_call(self.registry.set_redirect, ["path", "https://example.com"]),
|
self.mock_call(self.registry.set_redirect, ["path", "https://example.com"]),
|
||||||
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
||||||
self.mock_call(self.registry.set_host, ["path", "example.com"]),
|
self.mock_call(self.registry.set_host, ["path", "example.com"]),
|
||||||
|
self.mock_call(self.registry.get_from_path, ["path"]),
|
||||||
self.expects_status_only(
|
self.expects_status_only(
|
||||||
handler, http.HTTPStatus.CREATED, "Resource /path/ updated"
|
handler, http.HTTPStatus.CREATED, "Resource updated"
|
||||||
),
|
),
|
||||||
self.seal_mocks(),
|
self.seal_mocks(),
|
||||||
):
|
):
|
||||||
@@ -584,8 +591,9 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
self.mock_call(self.registry.set_redirect, ["path", "https://example.com"]),
|
self.mock_call(self.registry.set_redirect, ["path", "https://example.com"]),
|
||||||
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
||||||
self.mock_call(self.registry.set_host_only, ["path", "example.com"]),
|
self.mock_call(self.registry.set_host_only, ["path", "example.com"]),
|
||||||
|
self.mock_call(self.registry.get_from_path, ["path"]),
|
||||||
self.expects_status_only(
|
self.expects_status_only(
|
||||||
handler, http.HTTPStatus.CREATED, "Resource /path/ updated"
|
handler, http.HTTPStatus.CREATED, "Resource updated"
|
||||||
),
|
),
|
||||||
self.seal_mocks(),
|
self.seal_mocks(),
|
||||||
):
|
):
|
||||||
@@ -633,8 +641,9 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
),
|
),
|
||||||
self.mock_call(self.registry.set_proxy, ["path", "https://example.com"]),
|
self.mock_call(self.registry.set_proxy, ["path", "https://example.com"]),
|
||||||
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
||||||
|
self.mock_call(self.registry.get_from_path, ["path"]),
|
||||||
self.expects_status_only(
|
self.expects_status_only(
|
||||||
handler, http.HTTPStatus.CREATED, "Resource /path/ updated"
|
handler, http.HTTPStatus.CREATED, "Resource updated"
|
||||||
),
|
),
|
||||||
self.seal_mocks(),
|
self.seal_mocks(),
|
||||||
):
|
):
|
||||||
@@ -660,8 +669,9 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
self.mock_call(self.registry.set_proxy, ["path", "https://example.com"]),
|
self.mock_call(self.registry.set_proxy, ["path", "https://example.com"]),
|
||||||
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
self.mock_call(self.token_manager.set_token, ["path", "secret"]),
|
||||||
self.mock_call(self.registry.set_host, ["path", "example.com"]),
|
self.mock_call(self.registry.set_host, ["path", "example.com"]),
|
||||||
|
self.mock_call(self.registry.get_from_path, ["path"]),
|
||||||
self.expects_status_only(
|
self.expects_status_only(
|
||||||
handler, http.HTTPStatus.CREATED, "Resource /path/ updated"
|
handler, http.HTTPStatus.CREATED, "Resource updated"
|
||||||
),
|
),
|
||||||
self.seal_mocks(),
|
self.seal_mocks(),
|
||||||
):
|
):
|
||||||
@@ -783,9 +793,7 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
self.mock_call(self.data_dir.exists, ["path"], True), # noqa: FBT003
|
self.mock_call(self.data_dir.exists, ["path"], True), # noqa: FBT003
|
||||||
self.mock_call(self.data_dir.remove, ["path"]),
|
self.mock_call(self.data_dir.remove, ["path"]),
|
||||||
self.mock_call(self.registry.remove, ["path"]),
|
self.mock_call(self.registry.remove, ["path"]),
|
||||||
self.expects_error(
|
self.expects_error(handler, http.HTTPStatus.OK, "Resource /path/ removed"),
|
||||||
handler, http.HTTPStatus.NO_CONTENT, "Resource /path/ removed"
|
|
||||||
),
|
|
||||||
self.seal_mocks(),
|
self.seal_mocks(),
|
||||||
):
|
):
|
||||||
handler.do_DELETE()
|
handler.do_DELETE()
|
||||||
@@ -813,6 +821,7 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
"data": None,
|
"data": None,
|
||||||
"headers": {
|
"headers": {
|
||||||
"Host": "example.com",
|
"Host": "example.com",
|
||||||
|
"Accept": "nothing",
|
||||||
"X-Real-IP": "127.0.0.1",
|
"X-Real-IP": "127.0.0.1",
|
||||||
"X-Forwarded-Host": "localhost",
|
"X-Forwarded-Host": "localhost",
|
||||||
"X-Forwarded-For": "127.0.0.1",
|
"X-Forwarded-For": "127.0.0.1",
|
||||||
@@ -855,6 +864,7 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
"data": b"hello",
|
"data": b"hello",
|
||||||
"headers": {
|
"headers": {
|
||||||
"Host": "example.com",
|
"Host": "example.com",
|
||||||
|
"Accept": "nothing",
|
||||||
"X-Real-IP": "127.0.0.1",
|
"X-Real-IP": "127.0.0.1",
|
||||||
"X-Forwarded-Host": "localhost",
|
"X-Forwarded-Host": "localhost",
|
||||||
"X-Forwarded-For": "127.0.0.1",
|
"X-Forwarded-For": "127.0.0.1",
|
||||||
@@ -897,6 +907,7 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
"data": None,
|
"data": None,
|
||||||
"headers": {
|
"headers": {
|
||||||
"Host": "example.com",
|
"Host": "example.com",
|
||||||
|
"Accept": "nothing",
|
||||||
"X-Real-IP": "127.0.0.1",
|
"X-Real-IP": "127.0.0.1",
|
||||||
"X-Forwarded-Host": "localhost",
|
"X-Forwarded-Host": "localhost",
|
||||||
"X-Forwarded-For": "127.0.0.1",
|
"X-Forwarded-For": "127.0.0.1",
|
||||||
@@ -930,6 +941,7 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
"data": None,
|
"data": None,
|
||||||
"headers": {
|
"headers": {
|
||||||
"Host": "example.com",
|
"Host": "example.com",
|
||||||
|
"Accept": "nothing",
|
||||||
"X-Real-IP": "127.0.0.1",
|
"X-Real-IP": "127.0.0.1",
|
||||||
"X-Forwarded-Host": "localhost",
|
"X-Forwarded-Host": "localhost",
|
||||||
"X-Forwarded-For": "127.0.0.1",
|
"X-Forwarded-For": "127.0.0.1",
|
||||||
@@ -972,6 +984,7 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
"data": None,
|
"data": None,
|
||||||
"headers": {
|
"headers": {
|
||||||
"Host": "example.com",
|
"Host": "example.com",
|
||||||
|
"Accept": "nothing",
|
||||||
"X-Real-IP": "127.0.0.1",
|
"X-Real-IP": "127.0.0.1",
|
||||||
"X-Forwarded-Host": "localhost",
|
"X-Forwarded-Host": "localhost",
|
||||||
"X-Forwarded-For": "127.0.0.1",
|
"X-Forwarded-For": "127.0.0.1",
|
||||||
@@ -1011,6 +1024,7 @@ class TestRequestHandler(BaseHandlerTestCase):
|
|||||||
"data": None,
|
"data": None,
|
||||||
"headers": {
|
"headers": {
|
||||||
"Host": "example.com",
|
"Host": "example.com",
|
||||||
|
"Accept": "nothing",
|
||||||
"X-Real-IP": "127.0.0.1",
|
"X-Real-IP": "127.0.0.1",
|
||||||
"X-Forwarded-Host": "host",
|
"X-Forwarded-Host": "host",
|
||||||
"X-Forwarded-For": "127.0.0.1",
|
"X-Forwarded-For": "127.0.0.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user