1 /* run some tests on the file:// protocol handler */
5 const PR_RDONLY
= 0x1; // see prio.h
7 const special_type
= "application/x-our-special-type";
16 ].forEach(f
=> add_test(f
));
18 function new_file_input_stream(file
, buffered
) {
19 var stream
= Cc
["@mozilla.org/network/file-input-stream;1"].createInstance(
22 stream
.init(file
, PR_RDONLY
, 0, 0);
28 "@mozilla.org/network/buffered-input-stream;1"
29 ].createInstance(Ci
.nsIBufferedInputStream
);
30 buffer
.init(stream
, 4096);
34 function new_file_channel(file
) {
35 let uri
= Services
.io
.newFileURI(file
);
36 return NetUtil
.newChannel({
38 loadingPrincipal
: Services
.scriptSecurityManager
.createContentPrincipal(
42 securityFlags
: Ci
.nsILoadInfo
.SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT
,
43 contentPolicyType
: Ci
.nsIContentPolicy
.TYPE_DOCUMENT
,
49 * this listener has some additional file-specific tests, so we can't just use
50 * ChannelListener here.
52 function FileStreamListener(closure
) {
53 this._closure
= closure
;
55 FileStreamListener
.prototype = {
58 _got_onstartrequest
: false,
59 _got_onstoprequest
: false,
63 request
.QueryInterface(Ci
.nsIFileChannel
);
64 return request
.file
.isDirectory();
67 QueryInterface
: ChromeUtils
.generateQI([
72 onStartRequest(request
) {
73 if (this._got_onstartrequest
) {
74 do_throw("Got second onStartRequest event!");
76 this._got_onstartrequest
= true;
78 if (!this._isDir(request
)) {
79 request
.QueryInterface(Ci
.nsIChannel
);
80 this._contentLen
= request
.contentLength
;
81 if (this._contentLen
== -1) {
82 do_throw("Content length is unknown in onStartRequest!");
87 onDataAvailable(request
, stream
, offset
, count
) {
88 if (!this._got_onstartrequest
) {
89 do_throw("onDataAvailable without onStartRequest event!");
91 if (this._got_onstoprequest
) {
92 do_throw("onDataAvailable after onStopRequest event!");
94 if (!request
.isPending()) {
95 do_throw("request reports itself as not pending from onStartRequest!");
98 this._buffer
= this._buffer
.concat(read_stream(stream
, count
));
101 onStopRequest(request
, status
) {
102 if (!this._got_onstartrequest
) {
103 do_throw("onStopRequest without onStartRequest event!");
105 if (this._got_onstoprequest
) {
106 do_throw("Got second onStopRequest event!");
108 this._got_onstoprequest
= true;
109 if (!Components
.isSuccessCode(status
)) {
110 do_throw("Failed to load file: " + status
.toString(16));
112 if (status
!= request
.status
) {
113 do_throw("request.status does not match status arg to onStopRequest!");
115 if (request
.isPending()) {
116 do_throw("request reports itself as pending from onStopRequest!");
118 if (this._contentLen
!= -1 && this._buffer
.length
!= this._contentLen
) {
119 do_throw("did not read nsIChannel.contentLength number of bytes!");
122 this._closure(this._buffer
);
126 function test_read_file() {
127 dump("*** test_read_file\n");
129 var file
= do_get_file("../unit/data/test_readline6.txt");
130 var chan
= new_file_channel(file
);
132 function on_read_complete(data
) {
133 dump("*** test_read_file.on_read_complete\n");
136 if (chan
.contentType
!= special_type
) {
138 "Type mismatch! Is <" +
146 /* read completed successfully. now read data directly from file,
147 and compare the result. */
148 var stream
= new_file_input_stream(file
, false);
149 var result
= read_stream(stream
, stream
.available());
150 if (result
!= data
) {
151 do_throw("Stream contents do not match with direct read!");
156 chan
.contentType
= special_type
;
157 chan
.asyncOpen(new FileStreamListener(on_read_complete
));
160 function do_test_read_dir(set_type
, expected_type
) {
161 dump("*** test_read_dir(" + set_type
+ ", " + expected_type
+ ")\n");
163 var file
= do_get_tempdir();
164 var chan
= new_file_channel(file
);
166 function on_read_complete() {
168 "*** test_read_dir.on_read_complete(" +
176 if (chan
.contentType
!= expected_type
) {
178 "Type mismatch! Is <" +
190 chan
.contentType
= expected_type
;
192 chan
.asyncOpen(new FileStreamListener(on_read_complete
));
195 function test_read_dir_1() {
196 return do_test_read_dir(false, "application/http-index-format");
199 function test_read_dir_2() {
200 return do_test_read_dir(true, special_type
);
203 function test_upload_file() {
204 dump("*** test_upload_file\n");
206 var file
= do_get_file("../unit/data/test_readline6.txt"); // file to upload
207 var dest
= do_get_tempdir(); // file upload destination
208 dest
.append("junk.dat");
209 dest
.createUnique(dest
.NORMAL_FILE_TYPE
, 0o600);
211 var uploadstream
= new_file_input_stream(file
, true);
213 var chan
= new_file_channel(dest
);
214 chan
.QueryInterface(Ci
.nsIUploadChannel
);
215 chan
.setUploadStream(uploadstream
, "", file
.fileSize
);
217 function on_upload_complete(data
) {
218 dump("*** test_upload_file.on_upload_complete\n");
221 if (chan
.contentType
!= special_type
) {
223 "Type mismatch! Is <" +
231 /* upload of file completed successfully. */
233 do_throw("Upload resulted in data!");
236 var oldstream
= new_file_input_stream(file
, false);
237 var newstream
= new_file_input_stream(dest
, false);
238 var olddata
= read_stream(oldstream
, oldstream
.available());
239 var newdata
= read_stream(newstream
, newstream
.available());
240 if (olddata
!= newdata
) {
241 do_throw("Stream contents do not match after file copy!");
246 /* cleanup... also ensures that the destination file is not in
247 use when OnStopRequest is called. */
252 do_throw("Unable to remove uploaded file!\n");
258 chan
.contentType
= special_type
;
259 chan
.asyncOpen(new FileStreamListener(on_upload_complete
));
262 function test_load_shelllink() {
263 // lnk files should not resolve to their targets
264 dump("*** test_load_shelllink\n");
265 let file
= do_get_file("data/system_root.lnk", false);
266 var chan
= new_file_channel(file
);
268 // The original URI path should be the same as the URI path
269 Assert
.equal(chan
.URI
.pathQueryRef
, chan
.originalURI
.pathQueryRef
);
271 // The original URI path should be the same as the lnk file path
273 chan
.originalURI
.pathQueryRef
,
274 Services
.io
.newFileURI(file
).pathQueryRef