@hardlydifficult/http 1.0.3 → 1.0.5

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 +67 -48
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @hardlydifficult/http
2
2
 
3
- HTTP utilities for safe request/response handling: constant-time string comparison, body reading with 1MB limit, and JSON responses with CORS.
3
+ HTTP utilities for safe request/response handling: constant-time string comparison, body reading with size limits, and JSON responses with CORS headers.
4
4
 
5
5
  ## Installation
6
6
 
@@ -11,85 +11,104 @@ npm install @hardlydifficult/http
11
11
  ## Quick Start
12
12
 
13
13
  ```typescript
14
- import { readBody, sendJson, safeCompare, MAX_BODY_BYTES } from "@hardlydifficult/http";
15
14
  import { createServer } from "http";
15
+ import { readBody, sendJson, safeCompare } from "@hardlydifficult/http";
16
16
 
17
17
  const server = createServer(async (req, res) => {
18
+ // Read request body safely
18
19
  const body = await readBody(req);
19
- const isValid = safeCompare(body, "expected-secret");
20
-
21
- sendJson(res, isValid ? 200 : 403, { authorized: isValid }, "https://example.com");
20
+ const token = JSON.parse(body).token;
21
+
22
+ // Compare tokens securely
23
+ const isMatch = safeCompare(token, process.env.SECRET_TOKEN ?? "");
24
+ if (!isMatch) {
25
+ sendJson(res, 401, { error: "Unauthorized" }, "https://example.com");
26
+ return;
27
+ }
28
+
29
+ // Send JSON response with CORS headers
30
+ sendJson(res, 200, { message: "Access granted" }, "https://example.com");
22
31
  });
23
32
 
24
33
  server.listen(3000);
25
- // → Server starts and safely compares incoming request bodies
26
34
  ```
27
35
 
28
- ## Body Reading with Size Limit
36
+ ## Request Handling
37
+
38
+ ### `readBody`
29
39
 
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.
40
+ Reads the full request body as a string, rejecting if it exceeds `maxBytes`.
31
41
 
32
42
  ```typescript
33
- import { readBody, MAX_BODY_BYTES } from "@hardlydifficult/http";
43
+ import { readBody } from "@hardlydifficult/http";
34
44
 
35
- // Default limit: 1 MB
36
- const body = await readBody(request);
45
+ // Default limit is 1 MB
46
+ const body = await readBody(req);
37
47
 
38
- // Custom limit: 500 KB
39
- const body = await readBody(request, 1024 * 500);
48
+ // Custom limit (e.g., 500 KB)
49
+ const body = await readBody(req, 500 * 1024);
40
50
  ```
41
51
 
42
- ### Error Handling
52
+ | Parameter | Type | Description |
53
+ |---------|------|-------------|
54
+ | `req` | `IncomingMessage` | Node.js HTTP request |
55
+ | `maxBytes?` | `number` | Maximum body size in bytes (default: `1048576`) |
43
56
 
44
- If the body exceeds the specified limit, the promise rejects with an `"Payload too large"` error.
57
+ Throws `"Payload too large"` error when body exceeds limit.
45
58
 
46
- ## JSON Response with CORS
59
+ ### `MAX_BODY_BYTES`
47
60
 
48
- Sends a JSON response with CORS headers enabled.
61
+ Default maximum body size: `1024 * 1024` (1 MB).
49
62
 
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"`) |
63
+ ```typescript
64
+ import { MAX_BODY_BYTES } from "@hardlydifficult/http";
65
+
66
+ console.log(MAX_BODY_BYTES); // 1048576
67
+ ```
68
+
69
+ ## Response Handling
70
+
71
+ ### `sendJson`
72
+
73
+ Sends a JSON response with CORS headers.
56
74
 
57
75
  ```typescript
58
76
  import { sendJson } from "@hardlydifficult/http";
59
77
 
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.
78
+ sendJson(res, 200, { data: "example" }, "https://example.com");
67
79
  ```
68
80
 
69
- ## Constant-Time String Comparison
81
+ | Parameter | Type | Description |
82
+ |---------|------|-------------|
83
+ | `res` | `ServerResponse` | Node.js HTTP response |
84
+ | `status` | `number` | HTTP status code |
85
+ | `body` | `unknown` | Serializable data to send |
86
+ | `corsOrigin` | `string` | `Access-Control-Allow-Origin` value |
70
87
 
71
- Performs secure string comparison using `crypto.timingSafeEqual` to prevent timing attacks.
88
+ Sets headers:
89
+ - `Content-Type: application/json`
90
+ - `Access-Control-Allow-Origin: corsOrigin`
91
+ - `Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS`
92
+ - `Access-Control-Allow-Headers: Content-Type, Authorization`
93
+
94
+ ## Security
95
+
96
+ ### `safeCompare`
97
+
98
+ Constant-time string comparison to prevent timing attacks.
72
99
 
73
100
  ```typescript
74
101
  import { safeCompare } from "@hardlydifficult/http";
75
102
 
76
- const isMatch = safeCompare(userProvidedToken, storedToken);
77
- // → true if strings are identical, false otherwise
103
+ const isValid = safeCompare(userInput, secretToken);
78
104
  ```
79
105
 
80
- ### Behavior Details
106
+ Returns `true` for identical strings (including empty strings) and `false` otherwise, regardless of string length or content differences.
81
107
 
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.
108
+ Handles:
109
+ - Equal/unequal strings
110
+ - Different-length strings
111
+ - Unicode characters
112
+ - Empty strings
85
113
 
86
- ### Example Edge Cases
87
-
88
- ```typescript
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
95
- ```
114
+ All comparisons run in time proportional to the first string's length.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardlydifficult/http",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [