@hardlydifficult/http 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# @hardlydifficult/http
|
|
2
|
+
|
|
3
|
+
HTTP utilities for safe request/response handling: constant-time string comparison, body reading with 1MB limit, and JSON responses with CORS.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @hardlydifficult/http
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { safeCompare, readBody, sendJson, MAX_BODY_BYTES } from "@hardlydifficult/http";
|
|
15
|
+
import http from "http";
|
|
16
|
+
|
|
17
|
+
const server = http.createServer(async (req, res) => {
|
|
18
|
+
// Read request body with default 1MB limit
|
|
19
|
+
const body = await readBody(req);
|
|
20
|
+
|
|
21
|
+
// Example: compare secrets safely
|
|
22
|
+
const isValid = safeCompare(body, "secret");
|
|
23
|
+
|
|
24
|
+
// Send JSON response with CORS support
|
|
25
|
+
sendJson(res, isValid ? 200 : 401, { valid: isValid }, "https://example.com");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
server.listen(3000);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Constant-Time String Comparison
|
|
32
|
+
|
|
33
|
+
Protects against timing attacks by using `crypto.timingSafeEqual` internally.
|
|
34
|
+
|
|
35
|
+
### `safeCompare(a: string, b: string): boolean`
|
|
36
|
+
|
|
37
|
+
Compares two strings in constant time.
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { safeCompare } from "@hardlydifficult/http";
|
|
41
|
+
|
|
42
|
+
safeCompare("hello", "hello"); // true
|
|
43
|
+
safeCompare("hello", "world"); // false
|
|
44
|
+
safeCompare("", "something"); // false
|
|
45
|
+
safeCompare("héllo", "héllo"); // true (unicode-safe)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Request Body Reading
|
|
49
|
+
|
|
50
|
+
Reads full request body as string with configurable size limit.
|
|
51
|
+
|
|
52
|
+
### `readBody(req: IncomingMessage, maxBytes?: number): Promise<string>`
|
|
53
|
+
|
|
54
|
+
Parses incoming request body up to `maxBytes` (default: `MAX_BODY_BYTES`).
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { readBody, MAX_BODY_BYTES } from "@hardlydifficult/http";
|
|
58
|
+
import type { IncomingMessage } from "http";
|
|
59
|
+
|
|
60
|
+
// Use default limit (1MB)
|
|
61
|
+
const body1 = await readBody(req);
|
|
62
|
+
|
|
63
|
+
// Use custom limit (e.g., 512KB)
|
|
64
|
+
const body2 = await readBody(req, 512 * 1024);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## JSON Response with CORS
|
|
68
|
+
|
|
69
|
+
Sends JSON responses with CORS headers enabled.
|
|
70
|
+
|
|
71
|
+
### `sendJson(res: ServerResponse, status: number, body: unknown, corsOrigin: string): void`
|
|
72
|
+
|
|
73
|
+
Writes JSON response with proper headers and CORS support.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { sendJson } from "@hardlydifficult/http";
|
|
77
|
+
import type { ServerResponse } from "http";
|
|
78
|
+
|
|
79
|
+
sendJson(res, 200, { message: "OK" }, "https://example.com");
|
|
80
|
+
// Sends:
|
|
81
|
+
// Content-Type: application/json
|
|
82
|
+
// Access-Control-Allow-Origin: https://example.com
|
|
83
|
+
// Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
|
|
84
|
+
// Access-Control-Allow-Headers: Content-Type, Authorization
|
|
85
|
+
// Body: {"message":"OK"}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Constants
|
|
89
|
+
|
|
90
|
+
### `MAX_BODY_BYTES`
|
|
91
|
+
|
|
92
|
+
Default maximum body size in bytes (1 MB = 1048576).
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { MAX_BODY_BYTES } from "@hardlydifficult/http";
|
|
96
|
+
|
|
97
|
+
MAX_BODY_BYTES; // 1048576
|
|
98
|
+
```
|