@hardlydifficult/http 1.0.1 → 1.0.3

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.
Files changed (2) hide show
  1. package/README.md +51 -54
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -11,88 +11,85 @@ npm install @hardlydifficult/http
11
11
  ## Quick Start
12
12
 
13
13
  ```typescript
14
- import { safeCompare, readBody, sendJson, MAX_BODY_BYTES } from "@hardlydifficult/http";
15
- import http from "http";
14
+ import { readBody, sendJson, safeCompare, MAX_BODY_BYTES } from "@hardlydifficult/http";
15
+ import { createServer } from "http";
16
16
 
17
- const server = http.createServer(async (req, res) => {
18
- // Read request body with default 1MB limit
17
+ const server = createServer(async (req, res) => {
19
18
  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");
19
+ const isValid = safeCompare(body, "expected-secret");
20
+
21
+ sendJson(res, isValid ? 200 : 403, { authorized: isValid }, "https://example.com");
26
22
  });
27
23
 
28
24
  server.listen(3000);
25
+ // → Server starts and safely compares incoming request bodies
29
26
  ```
30
27
 
31
- ## Constant-Time String Comparison
32
-
33
- Protects against timing attacks by using `crypto.timingSafeEqual` internally.
34
-
35
- ### `safeCompare(a: string, b: string): boolean`
28
+ ## Body Reading with Size Limit
36
29
 
37
- Compares two strings in constant time.
30
+ Reads the full HTTP request body as a string, enforcing a configurable maximum size (default 1 MB). Throws an error if the payload exceeds the limit.
38
31
 
39
32
  ```typescript
40
- import { safeCompare } from "@hardlydifficult/http";
33
+ import { readBody, MAX_BODY_BYTES } from "@hardlydifficult/http";
34
+
35
+ // Default limit: 1 MB
36
+ const body = await readBody(request);
41
37
 
42
- safeCompare("hello", "hello"); // true
43
- safeCompare("hello", "world"); // false
44
- safeCompare("", "something"); // false
45
- safeCompare("héllo", "héllo"); // true (unicode-safe)
38
+ // Custom limit: 500 KB
39
+ const body = await readBody(request, 1024 * 500);
46
40
  ```
47
41
 
48
- ## Request Body Reading
42
+ ### Error Handling
49
43
 
50
- Reads full request body as string with configurable size limit.
44
+ If the body exceeds the specified limit, the promise rejects with an `"Payload too large"` error.
51
45
 
52
- ### `readBody(req: IncomingMessage, maxBytes?: number): Promise<string>`
46
+ ## JSON Response with CORS
53
47
 
54
- Parses incoming request body up to `maxBytes` (default: `MAX_BODY_BYTES`).
48
+ Sends a JSON response with CORS headers enabled.
55
49
 
56
- ```typescript
57
- import { readBody, MAX_BODY_BYTES } from "@hardlydifficult/http";
58
- import type { IncomingMessage } from "http";
50
+ | Parameter | Type | Description |
51
+ |---------|------|-------------|
52
+ | `res` | `ServerResponse` | Node.js HTTP response object |
53
+ | `status` | `number` | HTTP status code |
54
+ | `body` | `unknown` | Any serializable data |
55
+ | `corsOrigin` | `string` | Allowed origin for CORS (e.g., `"*"` or `"https://example.com"`) |
59
56
 
60
- // Use default limit (1MB)
61
- const body1 = await readBody(req);
57
+ ```typescript
58
+ import { sendJson } from "@hardlydifficult/http";
62
59
 
63
- // Use custom limit (e.g., 512KB)
64
- const body2 = await readBody(req, 512 * 1024);
60
+ sendJson(
61
+ res,
62
+ 201,
63
+ { id: 123, message: "Created" },
64
+ "https://frontend.example.com"
65
+ );
66
+ // → Sets headers: Content-Type, Access-Control-Allow-Origin, etc.
65
67
  ```
66
68
 
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`
69
+ ## Constant-Time String Comparison
72
70
 
73
- Writes JSON response with proper headers and CORS support.
71
+ Performs secure string comparison using `crypto.timingSafeEqual` to prevent timing attacks.
74
72
 
75
73
  ```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"}
74
+ import { safeCompare } from "@hardlydifficult/http";
75
+
76
+ const isMatch = safeCompare(userProvidedToken, storedToken);
77
+ // true if strings are identical, false otherwise
86
78
  ```
87
79
 
88
- ## Constants
80
+ ### Behavior Details
89
81
 
90
- ### `MAX_BODY_BYTES`
82
+ - Returns `true` only for identical strings (including empty strings).
83
+ - Returns `false` for different-length strings, with constant-time behavior.
84
+ - Handles Unicode correctly by comparing UTF-8 encoded buffers.
91
85
 
92
- Default maximum body size in bytes (1 MB = 1048576).
86
+ ### Example Edge Cases
93
87
 
94
88
  ```typescript
95
- import { MAX_BODY_BYTES } from "@hardlydifficult/http";
96
-
97
- MAX_BODY_BYTES; // 1048576
89
+ safeCompare("", ""); // true
90
+ safeCompare("abc", "abc"); // true
91
+ safeCompare("abc", "abd"); // false
92
+ safeCompare("short", "longer"); // false
93
+ safeCompare("héllo", "héllo"); // true
94
+ safeCompare("héllo", "hello"); // false
98
95
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardlydifficult/http",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [