package tiny_libs
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
From-scratch libraries for teaching: graphics, audio, compression, crypto, networking and more
Install
dune-project
Dependency
Authors
Maintainers
Sources
0.3.6.tar.gz
md5=7c636383d146d30ac6f2fa234a6253c8
sha512=c79f3823c5f8f57e5038eb640d487c61168b84aa07c61999d6622ef9fd0c890e2b03b4c6a7cdbbe9352a49e25dda00ac7bb14693cee8e3d7beeed251351a2af0
doc/src/tiny_libs.networking_unix/Http_client.ml.html
Source file Http_client.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63(* Claude Code * * Copyright (C) 2026 Yoann Padioleau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * (LGPL) as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. *) (* See Http_client.mli *) let ( let* ) = Result.bind let prepare ?post (url : Url.t) : (string * int * string, string) result = match (url.scheme, url.authority, Url.port url) with | Some ("http" | "https"), Some (a : Url.authority), Some port -> (* the Host header says the port only when it isn't the default *) let host_header = match a.port with Some p -> Printf.sprintf "%s:%d" a.host p | None -> a.host in (* "[::1]" in a URL, "::1" for the resolver *) let host = if String.starts_with ~prefix:"[" a.host then String.sub a.host 1 (String.length a.host - 2) else a.host in let target = Url.request_target url in let bytes = match post with | None -> Http.request_to_string (Http.get ~host:host_header target) | Some (content_type, body) -> Http.request_to_string ~body (Http.post ~host:host_header ~content_type ~body target) in Ok (host, port, bytes) | Some ("http" | "https"), _, _ -> Error (Printf.sprintf "%s: no host" (Url.to_string url)) | _ -> Error (Printf.sprintf "%s: not an http:// or https:// URL" (Url.to_string url)) (* one request, no redirection followed: over TCP, or inside TLS for https:// (Tls_client, our own TLS 1.3) *) let get_once ?post ?timeout (caps : < Cap.network ; .. >) (url : Url.t) : (Http.response, string) result = let* host, port, request = prepare ?post url in if url.scheme = Some "https" then let* answer = Tls_client.exchange ?timeout caps ~host ~port request in Http.parse_response answer else match Tcp.exchange ?timeout caps ~host ~port request with | answer -> Http.parse_response answer | exception Unix.Unix_error (e, _, _) -> Error (Printf.sprintf "%s: %s" (Url.to_string url) (Unix.error_message e)) | exception Failure msg -> Error msg let fetch ?post ?(max_redirects = 5) ?timeout (caps : < Cap.network ; .. >) (s : string) : (string * Http.response, string) result = let rec follow ?post (url : Url.t) (left : int) = let* (response : Http.response) = get_once ?post ?timeout caps url in match (Http.is_redirect response.status, Http.header "Location" response.headers) with | true, Some location -> if left = 0 then Error (Printf.sprintf "%s: too many redirections" s) else let* next = Url.parse location in (* a redirection is followed with a GET, as browsers do *) follow (Url.resolve url next) (left - 1) | _ -> Ok (Url.to_string url, response) in let* url = Url.parse s in follow ?post url max_redirects let get ?max_redirects ?timeout (caps : < Cap.network ; .. >) (s : string) : (Http.response, string) result = Result.map snd (fetch ?max_redirects ?timeout caps s)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>