source: project/wiki/eggref/4/http-client @ 22133

Last change on this file since 22133 was 22133, checked in by sjamaan, 10 years ago

Document new cookie behaviour (which is still horrible)

File size: 12.4 KB
Line 
1[[tags: egg]]
2
3== http-client
4
5[[toc:]]
6
7=== Description
8
9Http-client is a highlevel HTTP client library.
10
11=== Author
12
13[[/users/peter-bex|Peter Bex]]
14
15=== Requirements
16
17Requires the [[intarweb]] and [[openssl]] extensions.
18
19=== Documentation
20
21This egg is still under development; the API might change a bit in
22future versions.
23
24==== Main request procedures
25
26<procedure>(call-with-response request writer reader)</procedure>
27
28This is the core http-client procedure.  It is only necessary to use
29this when you want the most control over the request/response cycle.
30{{request}} is the request object that contains information about the
31request to perform.  {{reader}} is a procedure that receives the
32response object and should read the request body, {{writer}} is a
33procedure that receives the request object and should write the
34request body.
35
36The {{writer}} should be prepared to be called several times; if the
37response is a redirect or some other status that indicates the server
38wants the client to perform a new request, the writer should be ready
39to write a request body for this new request. In case digest
40authentication with message integrity checking is used, {{writer}} is
41always invoked at least twice, once to determine the message digest of
42the response and once to actually write the response.
43
44Returns three values: The result of the call to {{reader}}, the
45request-uri of the last request and the response object. The
46request-uri is useful because this is to be used as the base uri of
47the document. This can differ from the initial request in the presence
48of redirects.
49
50<procedure>(call-with-input-request uri-or-request writer reader)</procedure>
51
52This procedure is a convenience wrapper around {{call-with-response}}.
53
54It is much less strict - {{uri-or-request}} can be an [[intarweb]]
55request object, but also an uri-common object or even a string with the
56URI in it, in which case a request object will be automatically
57constructed around the URI, using the {{GET}} method.
58
59{{writer}} can be either {{#f}} (in which case nothing is written), a
60string containing the raw data to send, an alist (in which case the
61data is written out as using www-form-urlencoding, useful for POST
62requests), or a procedure that accepts a port and writes the response
63data to it.  If you supply a procedure, do not forget to set the
64{{content-length}} header!  In the other cases, the length is
65calculated and the header automatically set for you.  If you supplied
66an alist, the {{content-type}} header is automatically set to
67{{application/x-www-form-urlencoded}}.
68
69{{reader}} is a procedure which accepts a port and reads out the data.
70
71Returns three values: The result of the call to {{reader}}, the
72request-uri of the last request and the response object.  If the
73response code is not in the 200 class, it will throw an exception of
74type {{(exn http client-error)}}, {{(exn http server-error)}} or
75{{(exn http unexpected-server-response)}}, depending on the response
76code.  This includes {{404 not found}} (which is a {{client-error}}).
77
78<procedure>(with-input-from-request uri-or-request write-thunk read-thunk)</procedure>
79
80Same as {{call-with-input-request}}, except this accepts thunks
81(lambdas of no arguments) which will be executed with the current
82input (or output) port to the request or response port, respectively.
83
84<enscript highlight="scheme">
85(use http-client)
86
87(with-input-from-request "http://wiki.call-cc.org/" #f read-string)
88 => ;; [the chicken wiki page HTML contents]
89
90
91(use http-client uri-common intarweb)
92
93;; Perform a POST of the key "test" with value "value" to an echo service
94(with-input-from-request
95  (make-request method: 'POST
96                uri: (uri-reference "http://localhost/echo-service"))
97  '((test . "value")) read-string)
98 => "You posted: test=value"
99</enscript>
100
101
102==== Request handling parameters
103
104<parameter>(max-retry-attempts [number])</parameter>
105
106When a request fails because of an I/O or network problem (or simply
107because the remote end closed a persistent connection while we were
108doing something else), the library will try to establish a new
109connection and perform the request again.  This parameter controls how
110many times this is allowed to be done.  If {{#f}}, it will never give up.
111
112Defaults to 1.
113
114<parameter>(retry-request? [predicate])</parameter>
115
116This procedure is invoked when a retry should take place, to determine
117if it should take place at all.  It should be a procedure accepting a
118request object and returning {{#f}} or a true value.  If the value is
119true, the new request will be sent.  Otherwise, the error that caused
120the retry attempt will be re-raised.
121
122Defaults to {{idempotent?}}, from [[intarweb]].  This is because
123non-idempotent requests cannot be safely retried when it is unknown
124whether the previous request reached the server or not.
125
126<parameter>(max-redirect-depth [number])</parameter>
127
128The maximum number of allowed redirects, or {{#f}} if there is no
129limit.  Currently there's no automatic redirect loop detection
130algorithm implemented.
131
132Defaults to 5.
133
134<parameter>(client-software [software-spec])</parameter>
135
136This is the names, versions and comments of the software packages that
137the client is using, for use in the {{user-agent}} header which is
138automatically added to each request.
139
140Defaults to {{(("Chicken Scheme HTTP-client" VERSION #f))}}, where
141{{VERSION}} is the version of this egg.
142
143
144==== Connection management
145
146<procedure>(close-connection! uri)</procedure>
147
148Close the connection to the server associated with the URI.
149
150<procedure>(close-all-connections!)</procedure>
151
152Close all connections to all servers.
153
154
155==== Cookie management
156
157http-client's cookie management is supposed to be as automatic and
158DWIMmy as possible.  This means it will write any cookie as instructed
159by a server and all stored cookies are automatically sent back to the
160server upon a new request.
161
162However, in some cases you may want to take control of how cookies are
163stored.
164
165The API described here should be considered unstable and it may change
166dramatically when someone comes up with a better way to handle cookies.
167
168<procedure>(get-cookies-for-uri uri)</procedure>
169
170Fetch a list of all cookies which ought to be sent to the given URI.
171Cookies are vectors of two elements: a name/value pair and an alist of
172attributes.  In other words, these are the exact same values you can
173put in a {{cookie}} header.
174
175<procedure>(store-cookie! cookie-info set-cookie)</procedure>
176
177Store a cookie in the cookiejar corresponding to the Set-Cookie header
178given by {{set-cookie}}.  This overwrites any cookie that is equal to
179this cookie, as defined by RFC 2965, section 3.3.3.  Practically, this
180means that when the cookie's name, domain and path are equal to an
181existant one, it will be overwritten by the new one.  These attributes
182are taken from the {{cookie-info}} alist and expected to be there.
183
184Generally, attributes should be taken from {{set-cookie}}, but if
185missing they ought to be taken from the request URI that responded
186with the {{set-cookie}}.
187
188<procedure>(delete-cookie! cookie-name cookie-info)</procedure>
189
190Removes any cookie from the cookiejar that is equal to the given
191cookie (again, in the sense of RFC 2965, section 3.3.3).
192The {{cookie-name}} must match and the {{path}} and {{domain}} values for
193the {{cookie-info}} alist must match.
194
195==== Authentication support
196
197When a 401 Unauthorized response is received, in most interactive
198clients, the user is normally asked to authenticate.  To support this
199type of interaction, http-client offers the following parameter:
200
201<parameter>(determine-username/password [HANDLER])</parameter>
202
203The procedure in this parameter is called whenever the remote
204host requests authentication via a 401 Unauthorized response.
205
206The {{HANDLER}} is a procedure of two arguments; the URI for the
207resource currently being requested and the realm (a string) which
208wants credentials.  The procedure should return two string values:
209the username and the password to use for authentication.
210
211The default value is a procedure which extracts the username and
212password components from the URI.
213
214For proxy authentication support, see {{determine-proxy-username/password}}
215in the next section.
216
217==== Proxy support
218
219http-client has support for sending requests through proxy servers.
220
221<parameter>(determine-proxy [HANDLER])</parameter>
222
223Whenever a request is sent, the library invokes the procedure stored
224in this parameter to determine through what proxy to send the request,
225if any.
226
227The {{HANDLER}} procedure receives one argument, the URI about to be
228requested, and returns either an URI-common absolute URI object
229representing the proxy or {{#f}} if no proxy should be used.
230
231The URI's path and query, if present, are ignored; only the scheme
232and authority (host, port, username, password) are used.
233
234The default value of this parameter is {{determine-proxy-from-environment}}.
235
236If you just want to disable proxy support, you can do:
237
238<enscript highlight="scheme">
239(determine-proxy (constantly #f))   ; From unit data-structures
240</enscript>
241
242<procedure>(determine-proxy-from-environment URI)</procedure>
243
244This procedure implements the common behaviour of HTTP software under
245UNIX:
246
247* First it checks if the requested URI's host (or an asterisk) is listed in the {{NO_PROXY}} environment variable (if suffixed with a port number, the port is also compared).  If a match is found, no proxy is used.
248* Then it will check if the {{$(protocol)_proxy}} or the {{$(PROTOCOL)_PROXY}} variable (in that order) are set.  If so, that's used.  {{protocol}} here actually means "scheme", so the URI's scheme is used, suffixed with {{_proxy}}. This means {{http_proxy}} is used for HTTP requests and {{https_proxy}} is used for HTTPS requests.
249* If there's still no match, it looks for {{all_proxy}} or {{ALL_PROXY}}, in that order. If one of these environment variables are set, that value is used as a fallback proxy.
250* Finally, if none of these checks resulted in a proxy URI, no proxy will be used.
251
252Some UNIX software expects plain hostnames or hostname port
253combinations separated by colons, but (currently) this library expects
254full URIs, like most modern UNIX programs.
255
256<parameter>(determine-proxy-username/password [HANDLER])</parameter>
257
258The procedure in this parameter is called whenever the proxy requests
259authentication via a 407 Proxy Authentication Required response. This
260basically works the same as authentication against an origin server.
261
262The {{HANDLER}} is a procedure of two arguments; the URI for the
263''proxy'' currently being used and the realm (a string) which wants
264credentials.  The procedure should return two string values: the
265username and the password to use for authentication.
266
267The default value is a procedure which extracts the username and
268password components from the proxy's URI.
269
270
271=== Changelog
272
273* 0.3 Fixed handling of missing Path parameters in set-cookie headers. Reported by Hugo Arregui. Improve set-cookie handling by only passing Path and Domain when matching Set-Cookie header included those parameters.
274* 0.2 Added proxy support and many many bugfixes
275* 0.1 Initial version
276
277=== License
278
279  Copyright (c) 2008-2010, Peter Bex
280  Parts copyright (c) 2000-2004, Felix L. Winkelmann
281  All rights reserved.
282 
283  Redistribution and use in source and binary forms, with or without
284  modification, are permitted provided that the following conditions are
285  met:
286 
287  Redistributions of source code must retain the above copyright
288  notice, this list of conditions and the following disclaimer.
289 
290  Redistributions in binary form must reproduce the above copyright
291  notice, this list of conditions and the following disclaimer in the
292  documentation and/or other materials provided with the distribution.
293 
294  Neither the name of the author nor the names of its contributors may
295  be used to endorse or promote products derived from this software
296  without specific prior written permission.
297 
298  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
299  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
300  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
301  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
302  COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
303  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
304  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
305  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
306  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
307  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
308  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
309  OF THE POSSIBILITY OF SUCH DAMAGE.
Note: See TracBrowser for help on using the repository browser.