Skip to content

Commit 2a7296b

Browse files
committed
Add a docs landing page
1 parent 48b3ce5 commit 2a7296b

42 files changed

Lines changed: 981 additions & 44 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/docs-page.ts

Lines changed: 560 additions & 0 deletions
Large diffs are not rendered by default.

src/endpoints/groups.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
export interface EndpointGroup {
2+
id: string;
3+
name: string;
4+
description?: string;
5+
combinedExamples?: string[];
6+
}
7+
8+
export interface EndpointMeta {
9+
path: string;
10+
description: string;
11+
examples?: string[];
12+
group?: EndpointGroup;
13+
}
14+
15+
// HTTP endpoint groups
16+
export const httpContentExamples: EndpointGroup = {
17+
id: 'content-examples',
18+
name: 'Response Content Formats'
19+
};
20+
21+
export const httpAuthentication: EndpointGroup = {
22+
id: 'authentication',
23+
name: 'Authentication'
24+
};
25+
26+
export const httpCookies: EndpointGroup = {
27+
id: 'cookies',
28+
name: 'Cookies'
29+
};
30+
31+
export const httpContentEncoding: EndpointGroup = {
32+
id: 'content-encoding',
33+
name: 'Response Content Encodings'
34+
};
35+
36+
export const httpErrors: EndpointGroup = {
37+
id: 'errors',
38+
name: 'Errors'
39+
};
40+
41+
// WebSocket endpoint groups
42+
export const wsMessaging: EndpointGroup = {
43+
id: 'messaging',
44+
name: 'Messaging'
45+
};
46+
47+
export const wsConnection: EndpointGroup = {
48+
id: 'connection',
49+
name: 'Connection'
50+
};
51+
52+
export const wsTiming: EndpointGroup = {
53+
id: 'timing',
54+
name: 'Timing'
55+
};
56+
57+
export const wsErrors: EndpointGroup = {
58+
id: 'errors',
59+
name: 'Errors'
60+
};
61+
62+
// TLS endpoint groups
63+
export const tlsCertificateModes: EndpointGroup = {
64+
id: 'certificate-modes',
65+
name: 'Certificate Modes'
66+
};
67+
68+
export const tlsProtocolNegotiation: EndpointGroup = {
69+
id: 'protocol-negotiation',
70+
name: 'Protocol Negotiation',
71+
description: 'Endpoints that negotiate specific protocols via ALPN. These can be used together, to simulate a server supporting specific combinations of protocols, in the preference order specified.'
72+
};
73+
74+
export const tlsVersions: EndpointGroup = {
75+
id: 'versions',
76+
name: 'TLS Versions',
77+
description: 'Endpoints that only accept specific TLS versions. These can be used together, to simulate a server supporting any specific combination of versions.'
78+
};

src/endpoints/http-index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { MaybePromise } from '@httptoolkit/util';
22
import * as http from 'http';
33
import * as http2 from 'http2';
44

5+
import { EndpointMeta, EndpointGroup } from './groups.js';
6+
export type { EndpointMeta, EndpointGroup };
7+
58
export type HttpRequest = http.IncomingMessage | http2.Http2ServerRequest;
69
export type HttpResponse = http.ServerResponse | http2.Http2ServerResponse;
710

@@ -19,6 +22,7 @@ export interface HttpEndpoint {
1922
handle: HttpHandler;
2023
needsRawData?: boolean;
2124
getRemainingPath?: (path: string) => string | undefined;
25+
meta?: EndpointMeta;
2226
}
2327

2428
export * from './http/echo.js';

src/endpoints/http/anything.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,9 @@ import { buildHttpBinAnythingEndpoint } from '../../httpbin-compat.js';
44
export const anything: HttpEndpoint = {
55
matchPath: (path) => path === '/anything' || path.startsWith('/anything/'),
66
handle: buildHttpBinAnythingEndpoint({}),
7+
meta: {
8+
path: '/anything',
9+
description: 'Returns JSON containing the parsed details of the request, including method, url, headers, args, data, files, form, and origin.',
10+
examples: ['/anything', '/anything/subpath']
11+
}
712
};

src/endpoints/http/basic-auth.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { serializeJson } from '../../util.js';
22
import { HttpEndpoint, HttpHandler } from '../http-index.js';
3+
import { httpAuthentication } from '../groups.js';
34

45
const matchPath = (path: string) =>
56
!!path.match(/^\/basic-auth\/([^\/]+)\/([^\/]+)$/);
@@ -34,5 +35,11 @@ const handle: HttpHandler = (req, res, { path }) => {
3435

3536
export const basicAuth: HttpEndpoint = {
3637
matchPath,
37-
handle
38+
handle,
39+
meta: {
40+
path: '/basic-auth/{username}/{password}',
41+
description: 'Challenges with HTTP Basic Auth, expecting the username & password from the URL. Returns 200 with user info on success, 401 if unauthenticated, 403 if wrong credentials.',
42+
examples: ['/basic-auth/admin/secret'],
43+
group: httpAuthentication
44+
}
3845
};

src/endpoints/http/cookies.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@ import * as Cookie from 'cookie';
22

33
import { HttpEndpoint } from '../http-index.js';
44
import { serializeJson } from '../../util.js';
5+
import { httpCookies } from '../groups.js';
56

67
export const getCookies: HttpEndpoint = {
78
matchPath: (path) => path === '/cookies',
89
handle: (req, res) => {
910
const cookies = Cookie.parse(req.headers.cookie || '');
1011
res.writeHead(200, { 'Content-Type': 'application/json' });
1112
res.end(serializeJson({ cookies }));
13+
},
14+
meta: {
15+
path: '/cookies',
16+
description: 'Returns the cookies sent with the request.',
17+
examples: ['/cookies'],
18+
group: httpCookies
1219
}
1320
}
1421

@@ -43,6 +50,12 @@ export const setCookies: HttpEndpoint = {
4350
];
4451
})).flat()
4552
] as any).end(); // Any because H2 types don't include string array
53+
},
54+
meta: {
55+
path: '/cookies/set',
56+
description: 'Sets cookies via query parameters or path segments, then redirects to /cookies.',
57+
examples: ['/cookies/set?name=value', '/cookies/set/name/value'],
58+
group: httpCookies
4659
}
4760
}
4861

@@ -58,5 +71,11 @@ export const deleteCookies: HttpEndpoint = {
5871
`${key}=; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/`
5972
]).flat()
6073
] as any).end(); // Any because H2 types don't include string array
74+
},
75+
meta: {
76+
path: '/cookies/delete',
77+
description: 'Deletes cookies specified in query parameters, then redirects to /cookies.',
78+
examples: ['/cookies/delete?name'],
79+
group: httpCookies
6180
}
6281
}

src/endpoints/http/delay.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,10 @@ export const delayEndpoint: HttpEndpoint = {
3939
return true;
4040
},
4141
handle,
42-
getRemainingPath
42+
getRemainingPath,
43+
meta: {
44+
path: '/delay/{seconds}',
45+
description: 'Delays the response by the specified number of seconds (max 10). Can be chained with other endpoints.',
46+
examples: ['/delay/1', '/delay/5', '/delay/2/status/200']
47+
}
4348
};

src/endpoints/http/echo.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,5 +162,10 @@ async function handle(req: HttpRequest, res: HttpResponse) {
162162
export const echo: HttpEndpoint = {
163163
matchPath,
164164
handle,
165-
needsRawData: true
165+
needsRawData: true,
166+
meta: {
167+
path: '/echo',
168+
description: 'Echoes back the raw HTTP request data. For HTTP/2, returns parsed frame data as JSON lines.',
169+
examples: ['/echo']
170+
}
166171
}

src/endpoints/http/encoding/brotli.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as zlib from 'node:zlib';
22
import { serializeJson } from '../../../util.js';
33
import { HttpEndpoint, HttpHandler } from '../../http-index.js';
4+
import { httpContentEncoding } from '../../groups.js';
45

56
// We pre-decode the data. Note that this differs from HTTPBin which returns
67
// dynamic data here - for this reason, we use a subdirectory. Dynamic encoding
@@ -24,5 +25,11 @@ const handle: HttpHandler = (req, res) => {
2425

2526
export const brotli: HttpEndpoint = {
2627
matchPath,
27-
handle
28+
handle,
29+
meta: {
30+
path: '/encoding/brotli',
31+
description: 'Returns brotli-encoded JSON data.',
32+
examples: ['/encoding/brotli'],
33+
group: httpContentEncoding
34+
}
2835
};

src/endpoints/http/encoding/deflate.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as zlib from 'node:zlib';
22
import { serializeJson } from '../../../util.js';
33
import { HttpEndpoint, HttpHandler } from '../../http-index.js';
4+
import { httpContentEncoding } from '../../groups.js';
45

56
// We pre-decode the data. Note that this differs from HTTPBin which returns
67
// dynamic data here - for this reason, we use a subdirectory. Dynamic encoding
@@ -24,5 +25,11 @@ const handle: HttpHandler = (req, res) => {
2425

2526
export const deflate: HttpEndpoint = {
2627
matchPath,
27-
handle
28+
handle,
29+
meta: {
30+
path: '/encoding/deflate',
31+
description: 'Returns deflate-encoded JSON data.',
32+
examples: ['/encoding/deflate'],
33+
group: httpContentEncoding
34+
}
2835
};

0 commit comments

Comments
 (0)