File size: 2,534 Bytes
1efb3e0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# Bug 002: HTTP vs HTTPS URL Mismatch Behind HF Spaces Proxy

**Status**: FIXED
**Date Found**: 2025-12-11
**Severity**: High (may cause mixed content errors or fetch failures)

---

## Symptoms

NiiVue viewer fails to load NIfTI files with "Failed to fetch" even after CORS is fixed.
Browser console may show mixed content warnings (HTTPS page loading HTTP resources).

## Root Cause

HuggingFace Spaces runs containers behind a reverse proxy that handles SSL termination.
When the app constructs URLs using `request.base_url`, it may return `http://` instead of `https://`
because uvicorn doesn't trust the proxy's `X-Forwarded-Proto` header by default.

**Reference**: [FastAPI Static Files over HTTPS Discussion](https://github.com/fastapi/fastapi/discussions/6670)

> "Starlette (FastAPI) returns http instead of https only inside containers"

## The Code Path

```python
# routes.py
def get_backend_base_url(request: Request) -> str:
    env_url = os.environ.get("BACKEND_PUBLIC_URL", "").rstrip("/")
    if env_url:
        return env_url
    return str(request.base_url).rstrip("/")  # May return http:// behind proxy!
```

## Fix

Add `--proxy-headers` flag to uvicorn in Dockerfile:

```dockerfile
# BEFORE (broken)
CMD ["uvicorn", "...:app", "--host", "0.0.0.0", "--port", "7860"]

# AFTER (fixed)
CMD ["uvicorn", "...:app", "--host", "0.0.0.0", "--port", "7860", "--proxy-headers"]
```

This tells uvicorn to trust headers like:
- `X-Forwarded-Proto: https`
- `X-Forwarded-For: client-ip`

## Alternative Fixes

1. **Set BACKEND_PUBLIC_URL**: Explicitly set the public URL in HF Space settings
   ```
   BACKEND_PUBLIC_URL=https://vibecodermcswaggins-stroke-deepisles-demo.hf.space
   ```

2. **Force HTTPS in code**: Override scheme detection
   ```python
   def get_backend_base_url(request: Request) -> str:
       base = str(request.base_url).rstrip("/")
       # Force HTTPS in production
       if os.environ.get("HF_SPACES"):
           base = base.replace("http://", "https://")
       return base
   ```

## Files Changed

- `Dockerfile` - Added `--proxy-headers` to uvicorn CMD

## Verification

1. Deploy to HF Spaces
2. Run segmentation
3. Check Network tab - file URLs should be `https://`
4. NiiVue should load volumes successfully

## Sources

- [FastAPI/Starlette HTTPS Discussion](https://github.com/fastapi/fastapi/discussions/6670)
- [Deploying FastAPI on HuggingFace Spaces](https://medium.com/@na.mazaheri/deploying-a-fastapi-app-on-hugging-face-spaces-and-handling-all-its-restrictions-d494d97a78fa)