66 lines
1.7 KiB
Markdown
66 lines
1.7 KiB
Markdown
|
|
# External Mealie hostname via Cloudflare
|
||
|
|
|
||
|
|
## Symptom
|
||
|
|
Authenticated API calls to `https://recept.famfallman.com` can fail with:
|
||
|
|
|
||
|
|
- HTTP `403 Forbidden`
|
||
|
|
- response body: `error code: 1010`
|
||
|
|
- `Server: cloudflare` header
|
||
|
|
|
||
|
|
This is not the same as a bad Mealie token (`401`).
|
||
|
|
|
||
|
|
## Reproduction
|
||
|
|
Python `urllib` with its default user-agent may trigger the block:
|
||
|
|
|
||
|
|
```python
|
||
|
|
import os, urllib.request
|
||
|
|
base = 'https://recept.famfallman.com'
|
||
|
|
token = os.environ['MEALIE_API_TOKEN']
|
||
|
|
req = urllib.request.Request(
|
||
|
|
f'{base}/api/users/self',
|
||
|
|
headers={'Authorization': f'Bearer {token}'},
|
||
|
|
)
|
||
|
|
urllib.request.urlopen(req, timeout=30)
|
||
|
|
```
|
||
|
|
|
||
|
|
Observed failure pattern:
|
||
|
|
- default `Python-urllib/...` user-agent -> `403`
|
||
|
|
- explicit `User-Agent: Hermes-Debug/1.0` -> `200`
|
||
|
|
- `curl` with explicit user-agent -> `200`
|
||
|
|
|
||
|
|
## Working patterns
|
||
|
|
|
||
|
|
### curl
|
||
|
|
```bash
|
||
|
|
BASE_URL="${MEALIE_BASE_URL:-https://recept.famfallman.com}"
|
||
|
|
AUTH=(-H "Authorization: Bearer $MEALIE_API_TOKEN")
|
||
|
|
UA=(-H "User-Agent: Hermes-Debug/1.0")
|
||
|
|
curl -s "$BASE_URL/api/users/self" "${AUTH[@]}" "${UA[@]}"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Python
|
||
|
|
```python
|
||
|
|
headers={
|
||
|
|
'Authorization': f'Bearer {token}',
|
||
|
|
'User-Agent': 'Hermes-Debug/1.0',
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Interpretation
|
||
|
|
If the same token works on the LAN URL and the external host returns Cloudflare `403/1010`, suspect edge/WAF bot filtering before suspecting Mealie auth, DNS, or the token.
|
||
|
|
|
||
|
|
## Import-response quirk discovered in the same session
|
||
|
|
`POST /api/recipes/create/url` may return a JSON string slug like:
|
||
|
|
|
||
|
|
```json
|
||
|
|
"grillat-laxpaket-med-sparris"
|
||
|
|
```
|
||
|
|
|
||
|
|
Do not assume the import response is a full object. Follow with:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl -s "$BASE_URL/api/recipes/<slug>" "${AUTH[@]}" "${UA[@]}"
|
||
|
|
```
|
||
|
|
|
||
|
|
to verify title, image, and parsed ingredients.
|