My agentic slop goes here. Not intended for anyone else!
1(** HTTP status codes following RFC 7231 and extensions *)
2
3let src = Logs.Src.create "requests.status" ~doc:"HTTP Status Codes"
4module Log = (val Logs.src_log src : Logs.LOG)
5
6type informational = [
7 | `Continue
8 | `Switching_protocols
9 | `Processing
10 | `Early_hints
11]
12
13type success = [
14 | `OK
15 | `Created
16 | `Accepted
17 | `Non_authoritative_information
18 | `No_content
19 | `Reset_content
20 | `Partial_content
21 | `Multi_status
22 | `Already_reported
23 | `Im_used
24]
25
26type redirection = [
27 | `Multiple_choices
28 | `Moved_permanently
29 | `Found
30 | `See_other
31 | `Not_modified
32 | `Use_proxy
33 | `Temporary_redirect
34 | `Permanent_redirect
35]
36
37type client_error = [
38 | `Bad_request
39 | `Unauthorized
40 | `Payment_required
41 | `Forbidden
42 | `Not_found
43 | `Method_not_allowed
44 | `Not_acceptable
45 | `Proxy_authentication_required
46 | `Request_timeout
47 | `Conflict
48 | `Gone
49 | `Length_required
50 | `Precondition_failed
51 | `Payload_too_large
52 | `Uri_too_long
53 | `Unsupported_media_type
54 | `Range_not_satisfiable
55 | `Expectation_failed
56 | `I_m_a_teapot
57 | `Misdirected_request
58 | `Unprocessable_entity
59 | `Locked
60 | `Failed_dependency
61 | `Too_early
62 | `Upgrade_required
63 | `Precondition_required
64 | `Too_many_requests
65 | `Request_header_fields_too_large
66 | `Unavailable_for_legal_reasons
67]
68
69type server_error = [
70 | `Internal_server_error
71 | `Not_implemented
72 | `Bad_gateway
73 | `Service_unavailable
74 | `Gateway_timeout
75 | `Http_version_not_supported
76 | `Variant_also_negotiates
77 | `Insufficient_storage
78 | `Loop_detected
79 | `Not_extended
80 | `Network_authentication_required
81]
82
83type standard = [
84 | informational
85 | success
86 | redirection
87 | client_error
88 | server_error
89]
90
91type t = [
92 | `Code of int
93 | standard
94]
95
96let to_int = function
97 (* Informational *)
98 | `Continue -> 100
99 | `Switching_protocols -> 101
100 | `Processing -> 102
101 | `Early_hints -> 103
102 (* Success *)
103 | `OK -> 200
104 | `Created -> 201
105 | `Accepted -> 202
106 | `Non_authoritative_information -> 203
107 | `No_content -> 204
108 | `Reset_content -> 205
109 | `Partial_content -> 206
110 | `Multi_status -> 207
111 | `Already_reported -> 208
112 | `Im_used -> 226
113 (* Redirection *)
114 | `Multiple_choices -> 300
115 | `Moved_permanently -> 301
116 | `Found -> 302
117 | `See_other -> 303
118 | `Not_modified -> 304
119 | `Use_proxy -> 305
120 | `Temporary_redirect -> 307
121 | `Permanent_redirect -> 308
122 (* Client Error *)
123 | `Bad_request -> 400
124 | `Unauthorized -> 401
125 | `Payment_required -> 402
126 | `Forbidden -> 403
127 | `Not_found -> 404
128 | `Method_not_allowed -> 405
129 | `Not_acceptable -> 406
130 | `Proxy_authentication_required -> 407
131 | `Request_timeout -> 408
132 | `Conflict -> 409
133 | `Gone -> 410
134 | `Length_required -> 411
135 | `Precondition_failed -> 412
136 | `Payload_too_large -> 413
137 | `Uri_too_long -> 414
138 | `Unsupported_media_type -> 415
139 | `Range_not_satisfiable -> 416
140 | `Expectation_failed -> 417
141 | `I_m_a_teapot -> 418
142 | `Misdirected_request -> 421
143 | `Unprocessable_entity -> 422
144 | `Locked -> 423
145 | `Failed_dependency -> 424
146 | `Too_early -> 425
147 | `Upgrade_required -> 426
148 | `Precondition_required -> 428
149 | `Too_many_requests -> 429
150 | `Request_header_fields_too_large -> 431
151 | `Unavailable_for_legal_reasons -> 451
152 (* Server Error *)
153 | `Internal_server_error -> 500
154 | `Not_implemented -> 501
155 | `Bad_gateway -> 502
156 | `Service_unavailable -> 503
157 | `Gateway_timeout -> 504
158 | `Http_version_not_supported -> 505
159 | `Variant_also_negotiates -> 506
160 | `Insufficient_storage -> 507
161 | `Loop_detected -> 508
162 | `Not_extended -> 510
163 | `Network_authentication_required -> 511
164 (* Custom code *)
165 | `Code c -> c
166
167let of_int = function
168 (* Informational *)
169 | 100 -> `Continue
170 | 101 -> `Switching_protocols
171 | 102 -> `Processing
172 | 103 -> `Early_hints
173 (* Success *)
174 | 200 -> `OK
175 | 201 -> `Created
176 | 202 -> `Accepted
177 | 203 -> `Non_authoritative_information
178 | 204 -> `No_content
179 | 205 -> `Reset_content
180 | 206 -> `Partial_content
181 | 207 -> `Multi_status
182 | 208 -> `Already_reported
183 | 226 -> `Im_used
184 (* Redirection *)
185 | 300 -> `Multiple_choices
186 | 301 -> `Moved_permanently
187 | 302 -> `Found
188 | 303 -> `See_other
189 | 304 -> `Not_modified
190 | 305 -> `Use_proxy
191 | 307 -> `Temporary_redirect
192 | 308 -> `Permanent_redirect
193 (* Client Error *)
194 | 400 -> `Bad_request
195 | 401 -> `Unauthorized
196 | 402 -> `Payment_required
197 | 403 -> `Forbidden
198 | 404 -> `Not_found
199 | 405 -> `Method_not_allowed
200 | 406 -> `Not_acceptable
201 | 407 -> `Proxy_authentication_required
202 | 408 -> `Request_timeout
203 | 409 -> `Conflict
204 | 410 -> `Gone
205 | 411 -> `Length_required
206 | 412 -> `Precondition_failed
207 | 413 -> `Payload_too_large
208 | 414 -> `Uri_too_long
209 | 415 -> `Unsupported_media_type
210 | 416 -> `Range_not_satisfiable
211 | 417 -> `Expectation_failed
212 | 418 -> `I_m_a_teapot
213 | 421 -> `Misdirected_request
214 | 422 -> `Unprocessable_entity
215 | 423 -> `Locked
216 | 424 -> `Failed_dependency
217 | 425 -> `Too_early
218 | 426 -> `Upgrade_required
219 | 428 -> `Precondition_required
220 | 429 -> `Too_many_requests
221 | 431 -> `Request_header_fields_too_large
222 | 451 -> `Unavailable_for_legal_reasons
223 (* Server Error *)
224 | 500 -> `Internal_server_error
225 | 501 -> `Not_implemented
226 | 502 -> `Bad_gateway
227 | 503 -> `Service_unavailable
228 | 504 -> `Gateway_timeout
229 | 505 -> `Http_version_not_supported
230 | 506 -> `Variant_also_negotiates
231 | 507 -> `Insufficient_storage
232 | 508 -> `Loop_detected
233 | 510 -> `Not_extended
234 | 511 -> `Network_authentication_required
235 (* Unknown code *)
236 | c -> `Code c
237
238let to_string t = string_of_int (to_int t)
239
240let reason_phrase t =
241 match t with
242 (* Informational *)
243 | `Continue -> "Continue"
244 | `Switching_protocols -> "Switching Protocols"
245 | `Processing -> "Processing"
246 | `Early_hints -> "Early Hints"
247 (* Success *)
248 | `OK -> "OK"
249 | `Created -> "Created"
250 | `Accepted -> "Accepted"
251 | `Non_authoritative_information -> "Non-Authoritative Information"
252 | `No_content -> "No Content"
253 | `Reset_content -> "Reset Content"
254 | `Partial_content -> "Partial Content"
255 | `Multi_status -> "Multi-Status"
256 | `Already_reported -> "Already Reported"
257 | `Im_used -> "IM Used"
258 (* Redirection *)
259 | `Multiple_choices -> "Multiple Choices"
260 | `Moved_permanently -> "Moved Permanently"
261 | `Found -> "Found"
262 | `See_other -> "See Other"
263 | `Not_modified -> "Not Modified"
264 | `Use_proxy -> "Use Proxy"
265 | `Temporary_redirect -> "Temporary Redirect"
266 | `Permanent_redirect -> "Permanent Redirect"
267 (* Client Error *)
268 | `Bad_request -> "Bad Request"
269 | `Unauthorized -> "Unauthorized"
270 | `Payment_required -> "Payment Required"
271 | `Forbidden -> "Forbidden"
272 | `Not_found -> "Not Found"
273 | `Method_not_allowed -> "Method Not Allowed"
274 | `Not_acceptable -> "Not Acceptable"
275 | `Proxy_authentication_required -> "Proxy Authentication Required"
276 | `Request_timeout -> "Request Timeout"
277 | `Conflict -> "Conflict"
278 | `Gone -> "Gone"
279 | `Length_required -> "Length Required"
280 | `Precondition_failed -> "Precondition Failed"
281 | `Payload_too_large -> "Payload Too Large"
282 | `Uri_too_long -> "URI Too Long"
283 | `Unsupported_media_type -> "Unsupported Media Type"
284 | `Range_not_satisfiable -> "Range Not Satisfiable"
285 | `Expectation_failed -> "Expectation Failed"
286 | `I_m_a_teapot -> "I'm a teapot"
287 | `Misdirected_request -> "Misdirected Request"
288 | `Unprocessable_entity -> "Unprocessable Entity"
289 | `Locked -> "Locked"
290 | `Failed_dependency -> "Failed Dependency"
291 | `Too_early -> "Too Early"
292 | `Upgrade_required -> "Upgrade Required"
293 | `Precondition_required -> "Precondition Required"
294 | `Too_many_requests -> "Too Many Requests"
295 | `Request_header_fields_too_large -> "Request Header Fields Too Large"
296 | `Unavailable_for_legal_reasons -> "Unavailable For Legal Reasons"
297 (* Server Error *)
298 | `Internal_server_error -> "Internal Server Error"
299 | `Not_implemented -> "Not Implemented"
300 | `Bad_gateway -> "Bad Gateway"
301 | `Service_unavailable -> "Service Unavailable"
302 | `Gateway_timeout -> "Gateway Timeout"
303 | `Http_version_not_supported -> "HTTP Version Not Supported"
304 | `Variant_also_negotiates -> "Variant Also Negotiates"
305 | `Insufficient_storage -> "Insufficient Storage"
306 | `Loop_detected -> "Loop Detected"
307 | `Not_extended -> "Not Extended"
308 | `Network_authentication_required -> "Network Authentication Required"
309 (* Custom code - provide generic reason based on category *)
310 | `Code c ->
311 if c >= 100 && c < 200 then "Informational"
312 else if c >= 200 && c < 300 then "Success"
313 else if c >= 300 && c < 400 then "Redirection"
314 else if c >= 400 && c < 500 then "Client Error"
315 else if c >= 500 && c < 600 then "Server Error"
316 else "Unknown"
317
318(* Classification functions *)
319let is_informational t =
320 let code = to_int t in
321 code >= 100 && code < 200
322
323let is_success t =
324 let code = to_int t in
325 code >= 200 && code < 300
326
327let is_redirection t =
328 let code = to_int t in
329 code >= 300 && code < 400
330
331let is_client_error t =
332 let code = to_int t in
333 code >= 400 && code < 500
334
335let is_server_error t =
336 let code = to_int t in
337 code >= 500 && code < 600
338
339let is_error t =
340 let code = to_int t in
341 code >= 400 && code < 600
342
343(* Retry policy functions *)
344let is_retryable t =
345 match t with
346 | `Request_timeout
347 | `Too_many_requests
348 | `Bad_gateway
349 | `Service_unavailable
350 | `Gateway_timeout -> true
351 | _ -> is_server_error t (* All 5xx errors are generally retryable *)
352
353let should_retry_on_different_host t =
354 match t with
355 | `Bad_gateway
356 | `Service_unavailable
357 | `Gateway_timeout -> true
358 | _ -> false
359
360(* Pretty printing *)
361let pp ppf t =
362 Format.fprintf ppf "%d" (to_int t)
363
364let pp_hum ppf t =
365 Format.fprintf ppf "%d %s" (to_int t) (reason_phrase t)