forked from
anil.recoil.org/ocaml-requests
A batteries included HTTP/1.1 client in OCaml
1(*---------------------------------------------------------------------------
2 Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3 SPDX-License-Identifier: ISC
4 ---------------------------------------------------------------------------*)
5
6(** HTTP Proxy Configuration
7
8 Per RFC 9110 Section 3.7 and Section 7.3.2: A proxy is a message-forwarding
9 agent chosen by the client, usually configured via local rules.
10
11 {2 Usage}
12
13 Create a proxy configuration:
14 {[
15 let proxy = Proxy.http ~port:8080 "proxy.example.com"
16
17 (* With authentication *)
18 let proxy =
19 Proxy.http ~port:8080
20 ~auth:(Auth.basic ~username:"user" ~password:"pass")
21 "proxy.example.com"
22
23 (* With bypass list *)
24 let proxy =
25 Proxy.http
26 ~no_proxy:[ "localhost"; "*.internal.example.com" ]
27 "proxy.example.com"
28 ]}
29
30 Read from environment variables:
31 {[
32 match Proxy.from_env () with
33 | Some proxy -> (* use proxy *)
34 | None -> (* no proxy configured *)
35 ]} *)
36
37val src : Logs.Src.t
38(** Log source for proxy operations. *)
39
40(** {1 Proxy Types} *)
41
42(** Proxy protocol type *)
43type kind =
44 | HTTP (** HTTP proxy (CONNECT for HTTPS, absolute-URI for HTTP) *)
45 | SOCKS5 (** SOCKS5 proxy (RFC 1928) - future extension *)
46
47type config = {
48 host : string; (** Proxy server hostname *)
49 port : int; (** Proxy server port (default: 8080) *)
50 kind : kind;
51 auth : Auth.t option; (** Proxy authentication (Proxy-Authorization) *)
52 no_proxy : string list; (** Hosts/patterns to bypass proxy *)
53}
54(** Proxy configuration *)
55
56(** {1 Configuration Constructors} *)
57
58val http :
59 ?port:int -> ?auth:Auth.t -> ?no_proxy:string list -> string -> config
60(** [http ?port ?auth ?no_proxy host] creates an HTTP proxy configuration.
61
62 @param port Proxy port (default: 8080)
63 @param auth Proxy authentication credentials
64 @param no_proxy
65 List of hosts/patterns to bypass the proxy. Supports wildcards like
66 [*.example.com] to match [foo.example.com].
67 @param host Proxy server hostname. *)
68
69val socks5 :
70 ?port:int -> ?auth:Auth.t -> ?no_proxy:string list -> string -> config
71(** [socks5 ?port ?auth ?no_proxy host] creates a SOCKS5 proxy configuration.
72
73 {b Note:} SOCKS5 support is not yet implemented. This function creates the
74 configuration type for future use.
75
76 @param port Proxy port (default: 1080)
77 @param auth Proxy authentication credentials
78 @param no_proxy List of hosts/patterns to bypass the proxy
79 @param host Proxy server hostname. *)
80
81(** {1 Configuration Utilities} *)
82
83val should_bypass : config -> string -> bool
84(** [should_bypass config url] returns [true] if [url] should bypass the proxy
85 based on the [no_proxy] list.
86
87 Matching rules:
88 - Exact hostname match (case-insensitive)
89 - Wildcard prefix match: [*.example.com] matches [foo.example.com]
90 - [localhost] and [127.0.0.1] match by default if in no_proxy list. *)
91
92val host_port : config -> string * int
93(** [host_port config] returns the proxy host and port as a tuple. *)
94
95val validate_supported : config -> unit
96(** [validate_supported config] checks that the proxy type is currently
97 supported.
98 @raise Error.Proxy_error if SOCKS5 is requested (not yet implemented). *)
99
100(** {1 Environment Variable Support} *)
101
102val from_env : unit -> config option
103(** [from_env ()] reads proxy configuration from environment variables.
104
105 Checks the following variables (in order of preference):
106 - [HTTP_PROXY] / [http_proxy]
107 - [HTTPS_PROXY] / [https_proxy]
108 - [ALL_PROXY] / [all_proxy]
109 - [NO_PROXY] / [no_proxy] (comma-separated list of bypass patterns)
110
111 Returns [None] if no proxy is configured.
112
113 URL format: [http://[user:pass@]host[:port]]
114
115 Example environment:
116 {[
117 HTTP_PROXY=http://user:pass@proxy.example.com:8080
118 NO_PROXY=localhost,*.internal.example.com,.example.org
119 ]}. *)
120
121val from_env_for_url : string -> config option
122(** [from_env_for_url url] reads proxy configuration appropriate for [url].
123
124 - Uses [HTTPS_PROXY] for HTTPS URLs
125 - Uses [HTTP_PROXY] for HTTP URLs
126 - Falls back to [ALL_PROXY]
127 - Returns [None] if the URL matches [NO_PROXY] patterns. *)
128
129(** {1 Pretty Printing} *)
130
131val pp_kind : Format.formatter -> kind -> unit
132(** Pretty printer for proxy type. *)
133
134val pp_config : Format.formatter -> config -> unit
135(** Pretty printer for proxy configuration. Note: Authentication credentials are
136 redacted. *)