Skip to content

Commit

Permalink
RSPY-304: fix redirect response for asset download
Browse files Browse the repository at this point in the history
  • Loading branch information
vprivat-ads committed Jun 13, 2024
1 parent 7031ade commit 1623526
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 11 deletions.
24 changes: 17 additions & 7 deletions services/catalog/rs_server_catalog/user_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,15 @@
from rs_server_common.utils.logging import Logging
from starlette.middleware.base import BaseHTTPMiddleware, StreamingResponse
from starlette.requests import Request
from starlette.responses import JSONResponse, Response
from starlette.status import HTTP_200_OK, HTTP_400_BAD_REQUEST, HTTP_401_UNAUTHORIZED
from starlette.responses import JSONResponse, RedirectResponse, Response
from starlette.status import (
HTTP_200_OK,
HTTP_302_FOUND,
HTTP_400_BAD_REQUEST,
HTTP_401_UNAUTHORIZED,
)

PRESIGNED_URL_EXPIRATION_TIME = 1800 # 30 minutes
PRESIGNED_URL_EXPIRATION_TIME = int(os.environ.get("RSPY_PRESIGNED_URL_EXPIRATION_TIME", "1800")) # 30 minutes
CATALOG_BUCKET = os.environ.get("RSPY_CATALOG_BUCKET", "rs-cluster-catalog")


Expand Down Expand Up @@ -165,8 +170,11 @@ def adapt_links(self, content: dict, user: str, collection_id: str, object_name:
content[object_name][i] = self.adapt_object_links(content[object_name][i], user)
return content

def update_stac_item_publication( # pylint: disable=too-many-locals
self, content: dict, user: str, netloc: str
def update_stac_item_publication( # pylint: disable=too-many-locals
self,
content: dict,
user: str,
netloc: str,
) -> Any:
"""Update json body of feature push to catalog"""

Expand Down Expand Up @@ -274,7 +282,7 @@ def generate_presigned_url(self, content, path):
return "Could not find s3 credentials", HTTP_400_BAD_REQUEST
except botocore.exceptions.ClientError:
return "Could not generate presigned url", HTTP_400_BAD_REQUEST
return response, 302
return response, HTTP_302_FOUND

def find_owner_id(self, ecql_ast: Node) -> str:
"""Browse an abstract syntax tree (AST) to find the owner_id.
Expand Down Expand Up @@ -620,7 +628,7 @@ async def manage_get_response( # pylint: disable=too-many-locals, too-many-bran
content = self.adapt_object_links(content, user)
return JSONResponse(content, status_code=response.status_code)

async def manage_download_response(self, request: Request, response: StreamingResponse) -> JSONResponse:
async def manage_download_response(self, request: Request, response: StreamingResponse) -> Response:
"""
Manage download response and handle requests that should generate a presigned URL.
Expand Down Expand Up @@ -658,6 +666,8 @@ async def manage_download_response(self, request: Request, response: StreamingRe
if content.get("code", True) != "NotFoundError":
# Only generate presigned url if the item is found
content, code = self.generate_presigned_url(content, request.url.path)
if code == HTTP_302_FOUND:
return RedirectResponse(url=content, status_code=code)
return JSONResponse(content, status_code=code)
return JSONResponse(content, status_code=response.status_code)

Expand Down
2 changes: 1 addition & 1 deletion services/catalog/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def start_database_fixture(docker_services, db_url):
def client_fixture(start_database): # pylint: disable=missing-function-docstring, unused-argument
# A .env file is read automatically
# to setup the env to start the app.
with TestClient(app) as client:
with TestClient(app, follow_redirects=False) as client:
yield client


Expand Down
6 changes: 3 additions & 3 deletions services/catalog/tests/test_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,11 +571,11 @@ def test_generate_download_presigned_url(self, client):
"/catalog/collections/toto:S1_L1/items/fe916452-ba6f-4631-9154-c249924a122d/download/COG",
)
assert response.status_code == 302
# Check that response is a url not file content!
assert response.content != object_content
# Check that response body is empty
assert response.content == b""

# call the redirected url
product_content = requests.get(response.content.decode().replace('"', "").strip("'"), timeout=10)
product_content = requests.get(response.headers["location"], timeout=10)
assert product_content.status_code == 200
# check that content is the same as the original file
assert product_content.content.decode() == object_content
Expand Down

0 comments on commit 1623526

Please sign in to comment.