1 /* run some tests on the file:// protocol handler */
3 const Cc = Components.classes;
4 const Ci = Components.interfaces;
5 const Cr = Components.results;
6 const PR_RDONLY = 0x1; // see prio.h
8 const special_type = "application/x-our-special-type";
19 function run_next_test() {
20 test_array[test_index++]();
23 function getFile(key) {
24 var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
25 .getService(Components.interfaces.nsIProperties);
26 return dirSvc.get(key, Components.interfaces.nsILocalFile);
29 function new_file_input_stream(file, buffered) {
31 Cc["@mozilla.org/network/file-input-stream;1"].
32 createInstance(Ci.nsIFileInputStream);
33 stream.init(file, PR_RDONLY, 0, 0);
38 Cc["@mozilla.org/network/buffered-input-stream;1"].
39 createInstance(Ci.nsIBufferedInputStream);
40 buffer.init(stream, 4096);
44 function new_file_channel(file) {
46 Cc["@mozilla.org/network/io-service;1"].
47 getService(Ci.nsIIOService);
48 return ios.newChannelFromURI(ios.newFileURI(file));
53 * this listener has some additional file-specific tests, so we can't just use
54 * ChannelListener here.
56 function FileStreamListener(closure) {
57 this._closure = closure;
59 FileStreamListener.prototype = {
62 _got_onstartrequest: false,
63 _got_onstoprequest: false,
66 _isDir: function(request) {
67 request.QueryInterface(Ci.nsIFileChannel);
68 return request.file.isDirectory();
71 QueryInterface: function(iid) {
72 if (iid.equals(Ci.nsIStreamListener) ||
73 iid.equals(Ci.nsIRequestObserver) ||
74 iid.equals(Ci.nsISupports))
76 throw Cr.NS_ERROR_NO_INTERFACE;
79 onStartRequest: function(request, context) {
80 if (this._got_onstartrequest)
81 do_throw("Got second onStartRequest event!");
82 this._got_onstartrequest = true;
84 if (!this._isDir(request)) {
85 request.QueryInterface(Ci.nsIChannel);
86 this._contentLen = request.contentLength;
87 if (this._contentLen == -1)
88 do_throw("Content length is unknown in onStartRequest!");
92 onDataAvailable: function(request, context, stream, offset, count) {
93 if (!this._got_onstartrequest)
94 do_throw("onDataAvailable without onStartRequest event!");
95 if (this._got_onstoprequest)
96 do_throw("onDataAvailable after onStopRequest event!");
97 if (!request.isPending())
98 do_throw("request reports itself as not pending from onStartRequest!");
100 this._buffer = this._buffer.concat(read_stream(stream, count));
103 onStopRequest: function(request, context, status) {
104 if (!this._got_onstartrequest)
105 do_throw("onStopRequest without onStartRequest event!");
106 if (this._got_onstoprequest)
107 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));
111 if (status != request.status)
112 do_throw("request.status does not match status arg to onStopRequest!");
113 if (request.isPending())
114 do_throw("request reports itself as pending from onStopRequest!");
115 if (this._contentLen != -1 && this._buffer.length != this._contentLen)
116 do_throw("did not read nsIChannel.contentLength number of bytes!");
118 this._closure(this._buffer);
122 function test_read_file() {
123 dump("*** test_read_file\n");
125 var file = getFile("XpcomLib");
126 var chan = new_file_channel(file);
128 function on_read_complete(data) {
129 dump("*** test_read_file.on_read_complete\n");
132 if (chan.contentType != special_type)
133 do_throw("Type mismatch! Is <" + chan.contentType + ">, should be <" +
136 /* read completed successfully. now read data directly from file,
137 and compare the result. */
138 var stream = new_file_input_stream(file, false);
139 var result = read_stream(stream, stream.available());
141 do_throw("Stream contents do not match with direct read!");
145 chan.contentType = special_type;
146 chan.asyncOpen(new FileStreamListener(on_read_complete), null);
149 function do_test_read_dir(set_type, expected_type) {
150 dump("*** test_read_dir(" + set_type + ", " + expected_type + ")\n");
152 var file = getFile("TmpD");
153 var chan = new_file_channel(file);
155 function on_read_complete(data) {
156 dump("*** test_read_dir.on_read_complete(" + set_type + ", " + expected_type + ")\n");
159 if (chan.contentType != expected_type)
160 do_throw("Type mismatch! Is <" + chan.contentType + ">, should be <" +
167 chan.contentType = expected_type;
168 chan.asyncOpen(new FileStreamListener(on_read_complete), null);
171 function test_read_dir_1() {
172 return do_test_read_dir(false, "application/http-index-format");
175 function test_read_dir_2() {
176 return do_test_read_dir(true, special_type);
179 function test_upload_file() {
180 dump("*** test_upload_file\n");
182 var file = getFile("XpcomLib"); // file to upload
183 var dest = getFile("TmpD"); // file upload destination
184 dest.append("junk.dat");
185 dest.createUnique(dest.NORMAL_FILE_TYPE, 0600);
187 var uploadstream = new_file_input_stream(file, true);
189 var chan = new_file_channel(dest);
190 chan.QueryInterface(Ci.nsIUploadChannel);
191 chan.setUploadStream(uploadstream, "", file.fileSize);
193 function on_upload_complete(data) {
194 dump("*** test_upload_file.on_upload_complete\n");
197 if (chan.contentType != special_type)
198 do_throw("Type mismatch! Is <" + chan.contentType + ">, should be <" +
201 /* upload of file completed successfully. */
202 if (data.length != 0)
203 do_throw("Upload resulted in data!");
205 var oldstream = new_file_input_stream(file, false);
206 var newstream = new_file_input_stream(dest, false);
207 var olddata = read_stream(oldstream, oldstream.available());
208 var newdata = read_stream(newstream, newstream.available());
209 if (olddata != newdata)
210 do_throw("Stream contents do not match after file copy!");
214 /* cleanup... also ensures that the destination file is not in
215 use when OnStopRequest is called. */
220 do_throw("Unable to remove uploaded file!\n");
226 chan.contentType = special_type;
227 chan.asyncOpen(new FileStreamListener(on_upload_complete), null);
230 function run_test() {