Compare commits
2 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
12fd0b11a8 | 9 months ago |
|
|
03373bc7bb | 9 months ago |
@ -1,2 +0,0 @@ |
|||||||
*~ |
|
||||||
node_modules/ |
|
||||||
@ -1,109 +0,0 @@ |
|||||||
# Common HTTP Headers in REST APIs |
|
||||||
|
|
||||||
## Request Headers |
|
||||||
|
|
||||||
| Header Name | Purpose | Example Value | |
|
||||||
|-----------------------|-------------------------------------------------------|-----------------------------------------------| |
|
||||||
| `Authorization` | Carries auth credentials (token, Basic, Bearer) | `Bearer eyJhbGciOi...` | |
|
||||||
| `X-API-Key` | Custom API key for client authentication | `758b7d596dbc...` | |
|
||||||
| `X-Auth-Token` | Token-based session authentication | `d3f1c3a1-...` | |
|
||||||
| `X-Requested-With` | Identifies AJAX requests (legacy jQuery, CSRF checks) | `XMLHttpRequest` | |
|
||||||
| `Content-Type` | Declares request body format | `application/json` | |
|
||||||
| `Accept` | Declares expected response format | `application/json` | |
|
||||||
| `User-Agent` | Identifies client application | `MyApp/1.2.3` | |
|
||||||
| `X-Correlation-ID` | Tracks a request across distributed systems | `abc123-request-id` | |
|
||||||
| `X-Forwarded-For` | Shows originating IP behind proxies | `203.0.113.42` | |
|
||||||
| `X-Real-IP` | Alternate client IP header used by some proxies | `198.51.100.7` | |
|
||||||
| `If-None-Match` | Used with ETag for caching | `"abc123etag"` | |
|
||||||
| `If-Modified-Since` | Used for conditional GET requests | `Wed, 21 Oct 2015 07:28:00 GMT` | |
|
||||||
| `Cookie` | Sends session tokens or other state data | `session_id=abc123; logged_in=true` | |
|
||||||
|
|
||||||
--- |
|
||||||
|
|
||||||
## Response Headers |
|
||||||
|
|
||||||
| Header Name | Purpose | Example Value | |
|
||||||
|----------------------|-------------------------------------------------------|------------------------------------------------| |
|
||||||
| `Content-Type` | Format of the response body | `application/json` | |
|
||||||
| `Cache-Control` | Caching policy for the response | `no-cache`, `max-age=3600` | |
|
||||||
| `ETag` | Unique identifier for the response version | `"abc123etag"` | |
|
||||||
| `Last-Modified` | Timestamp of last modification | `Wed, 21 Oct 2015 07:28:00 GMT` | |
|
||||||
| `Expires` | Date/time when the response becomes stale | `Thu, 01 Dec 1994 16:00:00 GMT` | |
|
||||||
| `Location` | URL to newly created resource or redirect | `/users/123` or `https://api.example.com/...` | |
|
||||||
| `Retry-After` | Suggests wait time before retrying | `120` (seconds) or HTTP-date | |
|
||||||
| `WWW-Authenticate` | Declares required authentication scheme | `Bearer realm="example"` | |
|
||||||
| `Set-Cookie` | Sends cookies back to the client | `session_id=abc123; HttpOnly; Secure` | |
|
||||||
| `X-RateLimit-Limit` | Max requests allowed in current window | `1000` | |
|
||||||
| `X-RateLimit-Remaining` | Requests left in current window | `428` | |
|
||||||
| `X-RateLimit-Reset` | When rate limit resets (UNIX timestamp) | `1714684800` | |
|
||||||
| `X-Correlation-ID` | Unique ID for tracking this response (log tracing) | `abc123-response-id` | |
|
||||||
| `Access-Control-Allow-Origin` | CORS policy for allowed domains | `*` or `https://yourdomain.com` | |
|
||||||
| `Allow` | Accompanied with a 405 Response code | `GET,POST,PUT,DELETE` | |
|
||||||
|
|
||||||
--- |
|
||||||
|
|
||||||
## Nonce-Related Headers |
|
||||||
|
|
||||||
| Header Name | Purpose | Example Value | |
|
||||||
|---------------------------|-----------------------------------------------------|----------------------------------------------| |
|
||||||
| `Content-Security-Policy` | Allows inline scripts/styles with specific nonces | `script-src 'nonce-abc123'` | |
|
||||||
| `X-CSRF-Token` | Sends a per-request anti-CSRF token (often custom) | `e1f9e2d4-8f4b-4d2a-8450-c38a1fba57d4` | |
|
||||||
| `X-Nonce` (custom) | General-use nonce for replay prevention | `abc123noncevalue` | |
|
||||||
|
|
||||||
--- |
|
||||||
|
|
||||||
## Sample: Bearer Token in Authorization Header (PHP) |
|
||||||
|
|
||||||
```php |
|
||||||
$token = 'your-jwt-or-api-token'; |
|
||||||
$headers = [ |
|
||||||
'Authorization: Bearer ' . $token, |
|
||||||
# Alternately using API tokens |
|
||||||
# 'X-API-Key: ' . $apiKey, |
|
||||||
'Content-Type: application/json' |
|
||||||
]; |
|
||||||
|
|
||||||
$ch = curl_init('https://api.example.com/endpoint'); |
|
||||||
curl_setopt_array($ch, [ |
|
||||||
CURLOPT_RETURNTRANSFER => true, |
|
||||||
CURLOPT_HTTPHEADER => $headers |
|
||||||
]); |
|
||||||
|
|
||||||
$response = curl_exec($ch); |
|
||||||
curl_close($ch); |
|
||||||
``` |
|
||||||
|
|
||||||
## Sample: Bearer Token in Authorization Header (JavaScript / Fetch) |
|
||||||
|
|
||||||
```js |
|
||||||
const token = 'your-jwt-or-api-token'; |
|
||||||
|
|
||||||
fetch('https://api.example.com/endpoint', { |
|
||||||
method: 'GET', |
|
||||||
headers: { |
|
||||||
'Authorization': `Bearer ${token}`, |
|
||||||
'Content-Type': 'application/json', |
|
||||||
'Accept': 'application/json' |
|
||||||
} |
|
||||||
}) |
|
||||||
.then(response => response.json()) |
|
||||||
.then(data => console.log(data)) |
|
||||||
.catch(err => console.error('Request failed', err)); |
|
||||||
``` |
|
||||||
|
|
||||||
--- |
|
||||||
|
|
||||||
## Sample: Content-Security-Policy Nonce (PHP) |
|
||||||
|
|
||||||
### Server-side nonce generation: |
|
||||||
|
|
||||||
```php |
|
||||||
$nonce = base64_encode(random_bytes(16)); |
|
||||||
header("Content-Security-Policy: script-src 'self' 'nonce-$nonce'"); |
|
||||||
``` |
|
||||||
|
|
||||||
### Outputting safe inline script: |
|
||||||
|
|
||||||
```php |
|
||||||
echo "<script nonce="$nonce">console.log('Safe inline script');</script>"; |
|
||||||
``` |
|
||||||
@ -0,0 +1,8 @@ |
|||||||
|
ISC License: |
||||||
|
|
||||||
|
Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC") |
||||||
|
Copyright (c) 1995-2003 by Internet Software Consortium |
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||||
@ -1,39 +0,0 @@ |
|||||||
|
|
||||||
| Method | REST Purpose | Idempotent | Safe | Example | Typical Response Codes | |
|
||||||
|---------|----------------------------|------------|-------|------------------------------|--------------------------------------------------------| |
|
||||||
| GET | Retrieve a collection | ✔ Yes | ✔ Yes | `GET /users` | 200 OK, 204 No Content, 304 Not Modified | |
|
||||||
| GET | Retrieve a single resource | ✔ Yes | ✔ Yes | `GET /users/123` | 200 OK, 404 Not Found, 304 Not Modified | |
|
||||||
| POST | Create a new resource | ✖ No | ✖ No | `POST /users` | 201 Created, 400 Bad Request, 409 Conflict | |
|
||||||
| PUT | Replace a resource | ✔ Yes | ✖ No | `PUT /users/123` | 200 OK, 204 No Content, 400 Bad Request, 404 Not Found | |
|
||||||
| PATCH | Update part of a resource | ✖ No | ✖ No | `PATCH /users/123` | 200 OK, 204 No Content, 400 Bad Request, 404 Not Found | |
|
||||||
| DELETE | Remove a resource | ✔ Yes | ✖ No | `DELETE /users/123` | 204 No Content, 404 Not Found | |
|
||||||
| HEAD | Retrieve headers only | ✔ Yes | ✔ Yes | `HEAD /users/123` | 200 OK, 404 Not Found | |
|
||||||
| OPTIONS | Discover allowed methods | ✔ Yes | ✔ Yes | `OPTIONS /users` | 204 No Content, 405 Method Not Allowed | |
|
||||||
|
|
||||||
Typical Status codes to watch for: |
|
||||||
- 401 Unauthorized |
|
||||||
- 403 Forbidden |
|
||||||
- 500 Server Error |
|
||||||
|
|
||||||
| Status Code | Text Description | Typical REST Usage | |
|
||||||
|-------------|-------------------------|--------------------------------------------------------| |
|
||||||
| 200 | OK | Successful GET, PUT, or DELETE request | |
|
||||||
| 201 | Created | Resource successfully created (e.g., POST) | |
|
||||||
| 202 | Accepted | Request accepted for processing (async operations) | |
|
||||||
| 204 | No Content | Successful request with no response body (e.g., DELETE)| |
|
||||||
| 301 | Moved Permanently | Resource has moved (rare in REST APIs) | |
|
||||||
| 302 | Found | Temporary redirect (often avoided in APIs) | |
|
||||||
| 304 | Not Modified | Used with caching headers like ETag | |
|
||||||
| 400 | Bad Request | Malformed request, missing parameters, etc. | |
|
||||||
| 401 | Unauthorized | Authentication required or failed | |
|
||||||
| 403 | Forbidden | Authenticated but not authorized | |
|
||||||
| 404 | Not Found | Resource not found | |
|
||||||
| 405 | Method Not Allowed | HTTP method not supported for this endpoint | |
|
||||||
| 409 | Conflict | Request conflicts with current state (e.g., duplicate) | |
|
||||||
| 410 | Gone | Resource no longer available | |
|
||||||
| 415 | Unsupported Media Type | Content-Type not supported (e.g., expecting JSON) | |
|
||||||
| 422 | Unprocessable Entity | Validation error (common in POST/PUT with payloads) | |
|
||||||
| 429 | Too Many Requests | Rate limiting exceeded | |
|
||||||
| 500 | Internal Server Error | Generic server error | |
|
||||||
| 501 | Not Implemented | Endpoint or method not supported | |
|
||||||
| 503 | Service Unavailable | Server is down or overloaded | |
|
||||||
@ -1,55 +0,0 @@ |
|||||||
<?php |
|
||||||
class Redirect { |
|
||||||
__construct($endpoint, $apiKey) { |
|
||||||
$this->endpoint = $endpoint; |
|
||||||
$this->apiKey = $apiKey; |
|
||||||
} |
|
||||||
function _call() { |
|
||||||
$ch = curl_init($endpoint); |
|
||||||
|
|
||||||
curl_setopt_array($ch, [ |
|
||||||
CURLOPT_RETURNTRANSFER => true, |
|
||||||
CURLOPT_HTTPHEADER => [ |
|
||||||
'Accept: application/json', |
|
||||||
'Content-Type: application/json', |
|
||||||
"X-API-Key: $apikey", |
|
||||||
], |
|
||||||
]); |
|
||||||
|
|
||||||
$response = curl_exec($ch); |
|
||||||
|
|
||||||
if (curl_errno($ch)) { |
|
||||||
curl_close($ch); |
|
||||||
throw new Exception(curl_error($ch)); |
|
||||||
} else { |
|
||||||
curl_close($ch); |
|
||||||
print_r($httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); |
|
||||||
return (object)[ 'status' => httpCode, 'response' => json_decode($response)]; |
|
||||||
} |
|
||||||
function add($payload) { |
|
||||||
$ch = curl_init($endpoint); |
|
||||||
|
|
||||||
curl_setopt_array($ch, [ |
|
||||||
CURLOPT_RETURNTRANSFER => true, |
|
||||||
CURLOPT_POST => true, |
|
||||||
CURLOPT_HTTPHEADER => [ |
|
||||||
'Accept: application/json', |
|
||||||
'Content-Type: application/json', |
|
||||||
"X-API-Key: $apikey", |
|
||||||
], |
|
||||||
CURLOPT_POSTFIELDS => json_encode($payload), |
|
||||||
]); |
|
||||||
|
|
||||||
$response = curl_exec($ch); |
|
||||||
|
|
||||||
if (curl_errno($ch)) { |
|
||||||
curl_close($ch); |
|
||||||
throw new Exception(curl_error($ch)); |
|
||||||
} else { |
|
||||||
curl_close($ch); |
|
||||||
print_r($httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); |
|
||||||
return (object)[ 'status' => httpCode, 'response' => json_decode($response)]; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,74 +0,0 @@ |
|||||||
<?php |
|
||||||
|
|
||||||
/* |
|
||||||
* New PHP REST Framework |
|
||||||
* |
|
||||||
* Using Following SPECS |
|
||||||
* - HTTP Status Codes https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status |
|
||||||
* - HTTP Methods https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods |
|
||||||
* - REST API https://restfulapi.net/http-methods/ |
|
||||||
*/ |
|
||||||
|
|
||||||
/** |
|
||||||
* Determines whether the incoming request has a JSON-based Content-Type. |
|
||||||
* |
|
||||||
* @param string|null $contentType Optional override for testing or CLI use. |
|
||||||
* @return bool True if the Content-Type indicates JSON. |
|
||||||
*/ |
|
||||||
function req_isjson(?string $contentType = null): bool { |
|
||||||
// Get the header from the server if not provided |
|
||||||
$type = $contentType ?? ($_SERVER['CONTENT_TYPE'] ?? ''); |
|
||||||
|
|
||||||
// Normalize and strip parameters like "; charset=utf-8" |
|
||||||
$type = strtolower(trim(explode(';', $type)[0])); |
|
||||||
|
|
||||||
// Known JSON-based media types |
|
||||||
$jsonTypes = [ |
|
||||||
'application/json', |
|
||||||
'application/ld+json', |
|
||||||
'application/vnd.api+json', // JSON:API spec |
|
||||||
'text/json', // Rare but occasionally seen |
|
||||||
]; |
|
||||||
|
|
||||||
return in_array($type, $jsonTypes, true); |
|
||||||
} |
|
||||||
|
|
||||||
function req_method($supported = ['GET','PUT','POST','DELETE','HEAD','OPTIONS'],?string $method = null): string { |
|
||||||
// Get the header from the server if not provided |
|
||||||
$method = $method ?? ($_SERVER['REQUEST_METHOD'] ?? ''); |
|
||||||
if (!in_array($_SERVER['REQUEST_METHOD'], $supported)) { |
|
||||||
http_response_code(405); |
|
||||||
header('Allow: '. join(',',$supported)); |
|
||||||
exit; |
|
||||||
} |
|
||||||
return $method; |
|
||||||
} |
|
||||||
|
|
||||||
if (req_isjson()) { |
|
||||||
$raw = file_get_contents('php://input'); |
|
||||||
|
|
||||||
$post =json_decode($raw,true,1000,JSON_INVALID_UTF8_IGNORE); |
|
||||||
|
|
||||||
if (json_last_error() !== JSON_ERROR_NONE) { |
|
||||||
throw new JSONException('JSON: '.json_last_error_msg()); |
|
||||||
} |
|
||||||
} else { |
|
||||||
$post = $_REQUEST; |
|
||||||
} |
|
||||||
var_dump($_POST); |
|
||||||
$req = (object)[ |
|
||||||
'isjson' => req_isjson(), |
|
||||||
'method' => req_method(['GET','POST']), |
|
||||||
'path' => $_SERVER['PATH_INFO'] ?? '/', |
|
||||||
'post' => $post, |
|
||||||
]; |
|
||||||
|
|
||||||
$res = (object)[ |
|
||||||
'result' => 'ok', |
|
||||||
'req' => $req, |
|
||||||
]; |
|
||||||
|
|
||||||
|
|
||||||
header('Content-Type: application/json'); |
|
||||||
echo json_encode([$res], JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT); |
|
||||||
|
|
||||||
Loading…
Reference in new issue