forked from claw/flaskpaste
docs: add url shortener documentation
This commit is contained in:
@@ -459,6 +459,203 @@ X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
|
||||
|
||||
### POST /s
|
||||
|
||||
Create a new short URL. Requires proof-of-work and respects rate limits.
|
||||
|
||||
**Request (JSON):**
|
||||
```http
|
||||
POST /s HTTP/1.1
|
||||
Host: localhost:5000
|
||||
Content-Type: application/json
|
||||
X-PoW-Token: <token>
|
||||
X-PoW-Solution: <solution>
|
||||
|
||||
```
|
||||
|
||||
**Request (Raw):**
|
||||
```http
|
||||
POST /s HTTP/1.1
|
||||
Host: localhost:5000
|
||||
Content-Type: text/plain
|
||||
X-PoW-Token: <token>
|
||||
X-PoW-Solution: <solution>
|
||||
|
||||
```
|
||||
|
||||
**Optional Headers:**
|
||||
| Header | Description |
|
||||
|--------|-------------|
|
||||
| `X-Expiry` | Custom expiry in seconds |
|
||||
| `X-SSL-Client-SHA1` | Client certificate fingerprint (for ownership) |
|
||||
|
||||
**Response (201 Created):**
|
||||
```json
|
||||
{
|
||||
"id": "AbCdEfGh",
|
||||
"url": "/s/AbCdEfGh",
|
||||
"target_url": "https://example.com/some/long/path?query=value",
|
||||
"created_at": 1700000000,
|
||||
"owner": "a1b2c3d4...",
|
||||
"expires_at": 1700003600
|
||||
}
|
||||
```
|
||||
|
||||
**Errors:**
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 400 | No URL provided |
|
||||
| 400 | Invalid URL scheme (only http/https allowed) |
|
||||
| 400 | Invalid URL: missing host |
|
||||
| 400 | URL too long (max 2048 bytes) |
|
||||
| 400 | Proof-of-work required/failed |
|
||||
| 429 | Rate limit or duplicate URL limit exceeded |
|
||||
|
||||
**Security:**
|
||||
- Only `http` and `https` schemes are accepted (prevents `javascript:`, `data:`, `file:` etc.)
|
||||
- URLs must have a valid network location (host)
|
||||
- Maximum URL length: 2048 bytes (configurable via `FLASKPASTE_SHORT_URL_MAX`)
|
||||
|
||||
---
|
||||
|
||||
### GET /s
|
||||
|
||||
List short URLs owned by the authenticated user.
|
||||
|
||||
**Request:**
|
||||
```http
|
||||
GET /s HTTP/1.1
|
||||
Host: localhost:5000
|
||||
X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
|
||||
```
|
||||
|
||||
**Query Parameters:**
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `limit` | int | Maximum results (default: 50, max: 200) |
|
||||
| `offset` | int | Pagination offset (default: 0) |
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"urls": [
|
||||
{
|
||||
"id": "AbCdEfGh",
|
||||
"target_url": "https://example.com",
|
||||
"created_at": 1700000000,
|
||||
"access_count": 42,
|
||||
"url": "/s/AbCdEfGh"
|
||||
}
|
||||
],
|
||||
"count": 1,
|
||||
"total": 1,
|
||||
"limit": 50,
|
||||
"offset": 0
|
||||
}
|
||||
```
|
||||
|
||||
**Errors:**
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 401 | Authentication required |
|
||||
|
||||
---
|
||||
|
||||
### GET /s/{id}
|
||||
|
||||
### HEAD /s/{id}
|
||||
|
||||
Redirect to the target URL. Returns HTTP 302 with `Location` header.
|
||||
|
||||
**Request:**
|
||||
```http
|
||||
GET /s/AbCdEfGh HTTP/1.1
|
||||
Host: localhost:5000
|
||||
```
|
||||
|
||||
**Response (302 Found):**
|
||||
```http
|
||||
HTTP/1.1 302 Found
|
||||
Location: https://example.com/some/long/path
|
||||
Cache-Control: no-store, no-cache, must-revalidate, private
|
||||
```
|
||||
|
||||
Each access increments the short URL's access counter.
|
||||
|
||||
**Errors:**
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 400 | Invalid short URL ID format |
|
||||
| 404 | Short URL not found or expired |
|
||||
|
||||
---
|
||||
|
||||
### GET /s/{id}/info
|
||||
|
||||
Retrieve short URL metadata without incrementing the access counter.
|
||||
|
||||
**Request:**
|
||||
```http
|
||||
GET /s/AbCdEfGh/info HTTP/1.1
|
||||
Host: localhost:5000
|
||||
```
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"id": "AbCdEfGh",
|
||||
"target_url": "https://example.com/some/long/path",
|
||||
"created_at": 1700000000,
|
||||
"last_accessed": 1700001000,
|
||||
"access_count": 42,
|
||||
"url": "/s/AbCdEfGh",
|
||||
"owner": "a1b2c3d4...",
|
||||
"expires_at": 1700086400
|
||||
}
|
||||
```
|
||||
|
||||
**Errors:**
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 400 | Invalid short URL ID format |
|
||||
| 404 | Short URL not found or expired |
|
||||
|
||||
---
|
||||
|
||||
### DELETE /s/{id}
|
||||
|
||||
Delete a short URL. Requires authentication and ownership (or admin rights).
|
||||
|
||||
**Request:**
|
||||
```http
|
||||
DELETE /s/AbCdEfGh HTTP/1.1
|
||||
Host: localhost:5000
|
||||
X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
|
||||
```
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"message": "Short URL deleted"
|
||||
}
|
||||
```
|
||||
|
||||
**Errors:**
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 400 | Invalid short URL ID format |
|
||||
| 401 | Authentication required |
|
||||
| 403 | Permission denied (not owner or admin) |
|
||||
| 404 | Short URL not found |
|
||||
|
||||
---
|
||||
|
||||
## MIME Type Detection
|
||||
|
||||
FlaskPaste automatically detects MIME types using:
|
||||
|
||||
1. **Magic byte signatures** (highest priority)
|
||||
|
||||
| Category | Formats |
|
||||
|----------|---------|
|
||||
| Images | PNG, JPEG, GIF, WebP, BMP, TIFF, ICO |
|
||||
| Video | MP4, WebM, FLV, Matroska |
|
||||
| Audio | MP3, FLAC, OGG |
|
||||
|
||||
Reference in New Issue
Block a user