From 74446029f21b70898d75b35aeade41a2e698cc13 Mon Sep 17 00:00:00 2001 From: bellamer Date: Tue, 2 Jun 2026 13:20:47 +0200 Subject: [PATCH 1/4] TASK-008: Render deployment - render.yaml already committed (TASK-001); verified correct spec - Add DEPLOY.md: PM steps, post-deploy verification commands, known limitations - Placeholder URL in DEPLOY.md to be updated by PM after Render service creation Co-Authored-By: Claude Sonnet 4.6 --- DEPLOY.md | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 DEPLOY.md diff --git a/DEPLOY.md b/DEPLOY.md new file mode 100644 index 0000000..9a1ec25 --- /dev/null +++ b/DEPLOY.md @@ -0,0 +1,132 @@ +# Deployment: url-inspector + +**Platform:** Render (free tier) +**Deploy method:** Docker container +**Public URL:** _To be filled in by PM after Render service creation_ + +--- + +## Public Render URL + +``` +https://url-inspector.onrender.com +``` + +> **Note:** Replace the URL above with the actual URL from the Render dashboard after the service is created. +> Render-assigned hostnames follow the pattern `https://.onrender.com`. +> If the name `url-inspector` is taken, Render will assign a suffix (e.g., `url-inspector-abc1`). + +--- + +## render.yaml + +`render.yaml` is committed at the repository root. It defines the service as code: + +```yaml +services: + - type: web + name: url-inspector + env: docker + plan: free + healthCheckPath: /health + dockerfilePath: ./Dockerfile +``` + +--- + +## PM Steps to Deploy + +These steps require access to the Render dashboard. They cannot be automated from this repository. + +### 1. Confirm CI is green on main + +Before creating the Render service, verify the GitHub Actions CI badge in README.md shows passing. +The CI runs `ruff check .` and `pytest tests/` on every push. + +### 2. Create the Render Web Service + +1. Log in to [render.com](https://render.com) +2. Click **New** → **Web Service** +3. Connect your GitHub account if not already connected +4. Select the `url-inspector` repository +5. Configure the service: + - **Name:** `url-inspector` + - **Region:** Choose nearest to you + - **Branch:** `main` + - **Runtime:** Docker + - **Dockerfile path:** `./Dockerfile` + - **Plan:** Free +6. Under **Advanced**: + - **Health Check Path:** `/health` +7. Click **Create Web Service** + +### 3. Wait for first build + +- Render will pull the repo, build the Docker image, and start the container. +- Build typically takes 2–5 minutes on first run. +- Watch the build log in the Render dashboard for any errors. +- The service is ready when the status shows **Live**. + +### 4. Update this file + +Once deployed, replace the placeholder URL above with the actual Render URL shown in the dashboard. + +--- + +## Post-Deployment Verification + +Run each check after the service is live. All must pass before marking TASK-008 done. + +### Health check + +```bash +curl -s https:///health +# Expected: {"status":"ok"} +``` + +### Frontend + +Open `https:///` in a browser. The URL Inspector page must load without errors. + +### Metadata fetch (valid public URL) + +```bash +curl -s -X POST https:///api/inspect \ + -H "Content-Type: application/json" \ + -d '{"url": "https://example.com"}' | python3 -m json.tool +# Expected: HTTP 200, title field is non-null +``` + +### SSRF rejection + +```bash +curl -s -o /dev/null -w "%{http_code}" -X POST https:///api/inspect \ + -H "Content-Type: application/json" \ + -d '{"url": "http://127.0.0.1"}' +# Expected: 422 + +curl -s -X POST https:///api/inspect \ + -H "Content-Type: application/json" \ + -d '{"url": "http://127.0.0.1"}' | python3 -m json.tool +# Expected: {"error": "Forbidden Target", "error_detail": "..."} +``` + +--- + +## Known Limitations + +| Limitation | Impact | +|---|---| +| Cold starts | Render free tier spins down after ~15 min of inactivity. First request may take up to 30 s. | +| Bot-blocking | Sites that detect automated clients return 403 or a bot-detection page. The tool returns what the server returns. | +| JS-rendered metadata | Metadata injected by JavaScript is not captured. Raw HTML fetch only. Affects SPAs. | +| 5 MB body cap | Pages larger than 5 MB are rejected with `Response Too Large`. | + +--- + +## Redeployment + +Render auto-deploys on every push to `main` (configured in the Render dashboard). +No manual action required for subsequent deploys after initial service creation. + +To trigger a manual redeploy: **Render dashboard → url-inspector → Manual Deploy → Deploy latest commit**. From 3dc44bfbda9a5c67d23e6f9b4a8612694a104e4c Mon Sep 17 00:00:00 2001 From: bellamer Date: Tue, 2 Jun 2026 13:52:26 +0200 Subject: [PATCH 2/4] TASK-008: update DEPLOY.md with actual Render URL Replace placeholder URL with https://url-inspector-t6tm.onrender.com. All curl examples updated. All four live endpoint tests passed. Co-Authored-By: Claude Sonnet 4.6 --- DEPLOY.md | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/DEPLOY.md b/DEPLOY.md index 9a1ec25..d8c0315 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -2,20 +2,16 @@ **Platform:** Render (free tier) **Deploy method:** Docker container -**Public URL:** _To be filled in by PM after Render service creation_ +**Public URL:** https://url-inspector-t6tm.onrender.com --- ## Public Render URL ``` -https://url-inspector.onrender.com +https://url-inspector-t6tm.onrender.com ``` -> **Note:** Replace the URL above with the actual URL from the Render dashboard after the service is created. -> Render-assigned hostnames follow the pattern `https://.onrender.com`. -> If the name `url-inspector` is taken, Render will assign a suffix (e.g., `url-inspector-abc1`). - --- ## render.yaml @@ -67,10 +63,6 @@ The CI runs `ruff check .` and `pytest tests/` on every push. - Watch the build log in the Render dashboard for any errors. - The service is ready when the status shows **Live**. -### 4. Update this file - -Once deployed, replace the placeholder URL above with the actual Render URL shown in the dashboard. - --- ## Post-Deployment Verification @@ -80,32 +72,32 @@ Run each check after the service is live. All must pass before marking TASK-008 ### Health check ```bash -curl -s https:///health +curl -s https://url-inspector-t6tm.onrender.com/health # Expected: {"status":"ok"} ``` ### Frontend -Open `https:///` in a browser. The URL Inspector page must load without errors. +Open `https://url-inspector-t6tm.onrender.com/` in a browser. The URL Inspector page must load without errors. ### Metadata fetch (valid public URL) ```bash -curl -s -X POST https:///api/inspect \ +curl -s -X POST https://url-inspector-t6tm.onrender.com/api/inspect \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com"}' | python3 -m json.tool -# Expected: HTTP 200, title field is non-null +# Expected: HTTP 200, title field is non-null ("Example Domain") ``` ### SSRF rejection ```bash -curl -s -o /dev/null -w "%{http_code}" -X POST https:///api/inspect \ +curl -s -o /dev/null -w "%{http_code}" -X POST https://url-inspector-t6tm.onrender.com/api/inspect \ -H "Content-Type: application/json" \ -d '{"url": "http://127.0.0.1"}' # Expected: 422 -curl -s -X POST https:///api/inspect \ +curl -s -X POST https://url-inspector-t6tm.onrender.com/api/inspect \ -H "Content-Type: application/json" \ -d '{"url": "http://127.0.0.1"}' | python3 -m json.tool # Expected: {"error": "Forbidden Target", "error_detail": "..."} @@ -126,7 +118,7 @@ curl -s -X POST https:///api/inspect \ ## Redeployment -Render auto-deploys on every push to `main` (configured in the Render dashboard). +Render auto-deploys on every push to the tracked branch (configured in the Render dashboard). No manual action required for subsequent deploys after initial service creation. To trigger a manual redeploy: **Render dashboard → url-inspector → Manual Deploy → Deploy latest commit**. From 38bffe2768e401998c17fa02c67b6d8552743599 Mon Sep 17 00:00:00 2001 From: bellamer Date: Tue, 2 Jun 2026 14:26:33 +0200 Subject: [PATCH 3/4] - CVE fix - add idea folder to gitignore --- .gitignore | 1 + requirements.txt | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5cb2ac2..51f6777 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ __pycache__/ dist/ .pytest_cache/ .ruff_cache/ +.idea/* \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 245decf..f7eae18 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,8 @@ fastapi==0.115.6 uvicorn==0.32.1 httpx==0.28.1 beautifulsoup4==4.12.3 -lxml==5.3.0 +lxml==6.1.0 +starlette>=0.47.2 pydantic==2.10.3 ruff==0.9.1 pytest==8.3.4 From 818f2738667714ae62bd08874633404e9b3b68aa Mon Sep 17 00:00:00 2001 From: bellamer Date: Tue, 2 Jun 2026 14:37:27 +0200 Subject: [PATCH 4/4] - adjust dependencies --- requirements.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index f7eae18..ede9f86 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,8 @@ -fastapi==0.115.6 +fastapi==0.136.3 uvicorn==0.32.1 httpx==0.28.1 beautifulsoup4==4.12.3 lxml==6.1.0 -starlette>=0.47.2 pydantic==2.10.3 ruff==0.9.1 pytest==8.3.4