@hardlydifficult/http 1.0.4 → 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 +74 -45
  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, including constant-time string comparison, body reading with size limits, and JSON responses with CORS headers.
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,75 +11,104 @@ npm install @hardlydifficult/http
11
11
  ## Quick Start
12
12
 
13
13
  ```typescript
14
- import { readBody, sendJson, safeCompare } from '@hardlydifficult/http';
15
-
16
- // Safe string comparison
17
- const isMatch = safeCompare('secret', 'secret'); // true
18
-
19
- // Read request body with 1MB limit
20
- const body = await readBody(req); // max 1MB
21
-
22
- // Send JSON response with CORS headers
23
- sendJson(res, { status: 'ok' });
14
+ import { createServer } from "http";
15
+ import { readBody, sendJson, safeCompare } from "@hardlydifficult/http";
16
+
17
+ const server = createServer(async (req, res) => {
18
+ // Read request body safely
19
+ const body = await readBody(req);
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");
31
+ });
32
+
33
+ server.listen(3000);
24
34
  ```
25
35
 
26
- ## HTTP Utilities
36
+ ## Request Handling
27
37
 
28
- ### Safe String Comparison
38
+ ### `readBody`
29
39
 
30
- Performs constant-time comparison of two strings to prevent timing attacks.
40
+ Reads the full request body as a string, rejecting if it exceeds `maxBytes`.
31
41
 
32
42
  ```typescript
33
- import { safeCompare } from '@hardlydifficult/http';
43
+ import { readBody } from "@hardlydifficult/http";
34
44
 
35
- const result = safeCompare('abc123', 'abc123'); // true
36
- const fail = safeCompare('abc123', 'abc124'); // false
45
+ // Default limit is 1 MB
46
+ const body = await readBody(req);
47
+
48
+ // Custom limit (e.g., 500 KB)
49
+ const body = await readBody(req, 500 * 1024);
37
50
  ```
38
51
 
39
- | Parameter | Type | Description |
40
- |-----------|--------|---------------------|
41
- | a | string | First string to compare |
42
- | b | string | Second string to compare |
52
+ | Parameter | Type | Description |
53
+ |---------|------|-------------|
54
+ | `req` | `IncomingMessage` | Node.js HTTP request |
55
+ | `maxBytes?` | `number` | Maximum body size in bytes (default: `1048576`) |
56
+
57
+ Throws `"Payload too large"` error when body exceeds limit.
43
58
 
44
- ### Reading Request Body
59
+ ### `MAX_BODY_BYTES`
45
60
 
46
- Reads and returns the request body as a string, enforcing a maximum size limit of 1 MB.
61
+ Default maximum body size: `1024 * 1024` (1 MB).
47
62
 
48
63
  ```typescript
49
- import { readBody, MAX_BODY_BYTES } from '@hardlydifficult/http';
64
+ import { MAX_BODY_BYTES } from "@hardlydifficult/http";
50
65
 
51
- const body = await readBody(req); // max 1,048,576 bytes (1 MB)
52
- // Throws Error if body exceeds MAX_BODY_BYTES
66
+ console.log(MAX_BODY_BYTES); // 1048576
53
67
  ```
54
68
 
55
- | Parameter | Type | Description |
56
- |-----------|--------------------|--------------------------------|
57
- | req | IncomingMessage | Node.js HTTP request object |
69
+ ## Response Handling
58
70
 
59
- ### Sending JSON Responses
71
+ ### `sendJson`
60
72
 
61
- Sends a JSON response with appropriate `Content-Type` and `Access-Control-Allow-Origin` headers.
73
+ Sends a JSON response with CORS headers.
62
74
 
63
75
  ```typescript
64
- import { sendJson } from '@hardlydifficult/http';
76
+ import { sendJson } from "@hardlydifficult/http";
65
77
 
66
- sendJson(res, { message: 'Hello world' });
67
- // Sends: {"message":"Hello world"} with CORS headers
78
+ sendJson(res, 200, { data: "example" }, "https://example.com");
68
79
  ```
69
80
 
70
- | Parameter | Type | Description |
71
- |-----------|----------|---------------------------------|
72
- | res | ServerResponse | Node.js HTTP response object |
73
- | data | unknown | Data to serialize as JSON |
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 |
87
+
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`
74
93
 
75
- ## Appendix
94
+ ## Security
76
95
 
77
- ### Body Size Limit Behavior
96
+ ### `safeCompare`
78
97
 
79
- The `readBody` function enforces a strict 1 MB (`MAX_BODY_BYTES = 1024 * 1024`) limit. If the request body exceeds this, it throws an error:
98
+ Constant-time string comparison to prevent timing attacks.
80
99
 
81
100
  ```typescript
82
- if (received > MAX_BODY_BYTES) {
83
- throw new Error(`Body exceeded maximum size of ${MAX_BODY_BYTES} bytes`);
84
- }
85
- ```
101
+ import { safeCompare } from "@hardlydifficult/http";
102
+
103
+ const isValid = safeCompare(userInput, secretToken);
104
+ ```
105
+
106
+ Returns `true` for identical strings (including empty strings) and `false` otherwise, regardless of string length or content differences.
107
+
108
+ Handles:
109
+ - Equal/unequal strings
110
+ - Different-length strings
111
+ - Unicode characters
112
+ - Empty strings
113
+
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.4",
3
+ "version": "1.0.5",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [