1
(* $Id: http_fs.mli 1661 2011-08-28 22:45:55Z gerd $ *)
5
(** This module makes an HTTP file server accessible via a {!Netfs.stream_fs}
9
- identifying and reading directories (if the server generates
10
index pages for directories, see below for more information)
11
- writing files (if the server implements PUT)
12
- removing files (if the server implements DELETE)
14
One has to specify a base URL [b], and the access of a file with path [p]
15
is translated to the URL [b ^ p]. Note that [p] cannot include web
16
parameters ("?" strings), and hash marks are also not supported.
18
A directory is recognized by appending a slash to the URL, and
19
checking whether the URL exists.
21
The contents of a directory are determined by loading the directory
22
URL, analyzing the HTML page, and checking for the presence of
23
hyperlinks that do not contain slashes (or at most a trailing slash).
24
Only hyperlinks of "A" elements are accepted.
26
Almost every web server can be configured to generate directory
27
listings that conform to this format. For example, Apache provides
28
this through the module [mod_autoindex].
30
There is an extension to this class for WebDAV:
31
- {{:http://oss.wink.com/webdav/} Webdav} provides an extension of
32
{!Http_fs} for the full WebDAV set of filesystem operations
39
(** Read an HTTP directory:
42
let fs = new http_fs ~streaming:true "http://localhost/~gerd"
43
let files = fs # readdir [] "/"
46
Download a file into a string:
49
let ch = fs # read [] "/file"
50
let s = Netchannels.string_of_in_obj_channels ch
53
Copy a file hierarchy to the local disk:
56
let lfs = Netfs.local_fs()
57
Netfs.copy_into (fs :> Netfs.stream_fs) "/tree" lfs "/tmp"
63
let fsys = Netglob.of_stream_fs (fs :> Netfs.stream_fs)
64
let files = Netglob.glob ~fsys (`String "/*.gif")
68
(** {2 Extended [stream_fs] type} *)
70
(** There is the new flag [`Header] for [read] and [write], and the
71
new method [last_response_header] for getting the response
72
header of the most recently executed operation.
76
[ Netfs.read_flag | `Header of (string*string)list ]
79
[ Netfs.read_file_flag | `Header of (string*string)list ]
82
[ Netfs.write_flag | `Header of (string*string)list ]
84
type write_file_flag =
85
[ Netfs.write_file_flag | `Header of (string*string)list ]
88
class type http_stream_fs =
90
method read : read_flag list -> string -> Netchannels.in_obj_channel
92
- [`Header h]: Set these headers in the submitted GET request
95
method read_file : read_file_flag list -> string -> Netfs.local_file
97
- [`Header h]: Set these headers in the submitted GET request
100
method write : write_flag list -> string -> Netchannels.out_obj_channel
102
- [`Header h]: Set these headers in the submitted PUT request
105
method write_file : write_file_flag list -> string -> Netfs.local_file -> unit
107
- [`Header h]: Set these headers in the submitted PUT request
110
method last_response_header : Nethttp.http_header
111
(** Returns the header of the HTTP response of the last operation.
113
header is set when the last operation returns normally (no
114
exception was raised). In case of [write], the header is first set when
115
the stream is closed.
117
Raises [Not_found] if the last operation did not receive a header
121
method pipeline : Http_client.pipeline
122
(** The HTTP pipeline backing this file system *)
124
(** The following methods are the same as in {!Netfs.stream_fs}.
125
(For formal reasons we cannot inherit from this class type.)
128
method translate : string -> string
129
(** Translates a path into a URL *)
131
method path_encoding : Netconversion.encoding option
132
method path_exclusions : (int * int) list
133
method nominal_dot_dot : bool
134
method size : Netfs.size_flag list -> string -> int64
135
method test : Netfs.test_flag list -> string -> Netfs.test_type -> bool
136
method test_list : Netfs.test_flag list -> string -> Netfs.test_type list -> bool list
137
method remove : Netfs.remove_flag list -> string -> unit
138
method rename : Netfs.rename_flag list -> string -> string -> unit
139
method symlink : Netfs.symlink_flag list -> string -> string -> unit
140
method readdir : Netfs.readdir_flag list -> string -> string list
141
method readlink : Netfs.readlink_flag list -> string -> string
142
method mkdir : Netfs.mkdir_flag list -> string -> unit
143
method rmdir : Netfs.rmdir_flag list -> string -> unit
144
method copy : Netfs.copy_flag list -> string -> string -> unit
145
method cancel : unit -> unit
151
class http_fs : ?config_pipeline:(Http_client.pipeline -> unit) ->
153
?tmp_directory:string ->
154
?tmp_prefix:string ->
155
?path_encoding:Netconversion.encoding ->
156
?enable_read_for_directories:bool ->
158
string -> http_stream_fs
159
(** [http_fs base_url]: Accesses the HTTP file system rooted at
162
The following access methods are supported (compare with
164
- [path_encoding]: Returns the passed [path_encoding]. Paths
166
- [path_exclusions]: is just [0,0; 47,47]
167
- [nominal_dot_dot] is true
168
- [read]: is supported. All files are considered as binary.
169
The [`Skip] flag works, and is translated to a [Range] header.
170
- [write]: is supported and translated to [PUT]. It is assumed
171
that [PUT] truncates existing files, and creates new files.
172
Note that errors are often first reported when the returned
174
- [size]: this works only if the server includes the [Content-length]
175
header in responses to [HEAD] requests.
176
- [test] and [test_list]: The tests [`N], [`E], [`D], [`F], and [`S]
177
should work. Files are never symlinks. [`R] is handled like [`E],
178
and [`X] is handled like [`X] (i.e. it is assumed that all
179
files are readable, and all directories can be entered). The
180
[`W] test is never successful.
181
- [remove]: is translated to a [DELETE] request.
182
- [readdir]: works if index pages are generated (see above)
184
There is no support for [rename], [symlink], [mkdir], [rmdir], and
188
- [config_pipeline]: one can enable further features on the pipeline
189
object (e.g. authentication, proxies)
190
- [streaming]: if true, the [read] method only reads as much data
191
from the HTTP connection as requested by the user. This assumes
192
that the user does not pause stream accesses for longer periods
193
as this would risk a server timeout. Also, there is no way for
194
the client to automatically reconnect to the HTTP server after crashes.
195
If false (the default),
196
files are first downloaded to a temporary file before they are
197
made accessible as [in_obj_channel]. Streaming can also be
198
enabled for each [read] or [write] by including [`Streaming]
199
in the list of flags.
200
- [tmp_directory]: directory for temporary files
201
- [tmp_prefix]: file prefix for temporary files (w/o directory)
202
- [path_encoding]: The encoding that is used for the file names.
203
This must match the encoding the server assumes for translating
204
file names to hyperlinks. Unfortunately, there is no way to
205
query the server for this. The default, [`Enc_utf8], seems to be the
206
de-facto standard on the web (e.g. browsers use UTF-8 when
207
non-ASCII characters are entered in the address line).
208
- [enable_ftp]: This enables anonymous FTP via web proxies. In
209
this case the [base_url] is of the form [ftp://host:port/path].
210
This works only if the pipeline is configured to contact a
211
web proxy understanding FTP URLs.
215
- [is_error_response]: This function is invoked with the current
216
call object as soon as the response header arrives. It
217
looks at the response code, and checks whether the response
218
is successful or not. In the latter case the function returns
219
the exception to raise. This function can be called several
220
times during the execution of an operation. If it is called
221
at a moment where only the response header is available but
222
not the response body it is ensured that it will be called
223
again with the full response later.
224
Defaults to {!Http_fs.is_error_response}.
227
val http_fs : ?config_pipeline:(Http_client.pipeline -> unit) ->
229
?tmp_directory:string ->
230
?tmp_prefix:string ->
231
?path_encoding:Netconversion.encoding ->
232
?enable_read_for_directories:bool ->
234
string -> http_stream_fs
235
(** Same as normal function *)
238
val is_error_response : string -> Http_client.http_call -> exn option
239
(** Default implementation: The [status] [`Successful] (code in the range
240
200 to 299) is considered as successful, and:
241
- code 404 is mapped to [ENOENT]
242
- codes 401 and 403 are mapped to [EACCES]
243
- other codes from 300 to 599 are mapped to [EPERM]
249
val find_flag : ('a -> 'b option) -> 'a list -> 'b