|
1 Cu.import("resource://testing-common/httpd.js"); |
|
2 |
|
3 XPCOMUtils.defineLazyGetter(this, "URL", function() { |
|
4 return "http://localhost:" + httpserver.identity.primaryPort; |
|
5 }); |
|
6 |
|
7 var httpserver = new HttpServer(); |
|
8 var testpath = "/simple"; |
|
9 var httpbody = "0123456789"; |
|
10 |
|
11 var last = 0, max = 0; |
|
12 |
|
13 const STATUS_RECEIVING_FROM = 0x804b0006; |
|
14 const LOOPS = 50000; |
|
15 |
|
16 const TYPE_ONSTATUS = 1; |
|
17 const TYPE_ONPROGRESS = 2; |
|
18 const TYPE_ONSTARTREQUEST = 3; |
|
19 const TYPE_ONDATAAVAILABLE = 4; |
|
20 const TYPE_ONSTOPREQUEST = 5; |
|
21 |
|
22 var progressCallback = { |
|
23 _listener: null, |
|
24 _got_onstartrequest: false, |
|
25 _got_onstatus_after_onstartrequest: false, |
|
26 _last_callback_handled: null, |
|
27 |
|
28 QueryInterface: function (iid) { |
|
29 if (iid.equals(Ci.nsISupports) || |
|
30 iid.equals(Ci.nsIProgressEventSink) || |
|
31 iid.equals(Ci.nsIStreamListener) || |
|
32 iid.equals(Ci.nsIRequestObserver)) |
|
33 return this; |
|
34 throw Cr.NS_ERROR_NO_INTERFACE; |
|
35 }, |
|
36 |
|
37 getInterface: function (iid) { |
|
38 if (iid.equals(Ci.nsIProgressEventSink) || |
|
39 iid.equals(Ci.nsIStreamListener) || |
|
40 iid.equals(Ci.nsIRequestObserver)) |
|
41 return this; |
|
42 throw Cr.NS_ERROR_NO_INTERFACE; |
|
43 }, |
|
44 |
|
45 onStartRequest: function(request, context) { |
|
46 do_check_eq(this._last_callback_handled, TYPE_ONSTATUS); |
|
47 this._got_onstartrequest = true; |
|
48 this._last_callback_handled = TYPE_ONSTARTREQUEST; |
|
49 |
|
50 this._listener = new ChannelListener(checkRequest, request); |
|
51 this._listener.onStartRequest(request, context); |
|
52 }, |
|
53 |
|
54 onDataAvailable: function(request, context, data, offset, count) { |
|
55 do_check_eq(this._last_callback_handled, TYPE_ONPROGRESS); |
|
56 this._last_callback_handled = TYPE_ONDATAAVAILABLE; |
|
57 |
|
58 this._listener.onDataAvailable(request, context, data, offset, count); |
|
59 }, |
|
60 |
|
61 onStopRequest: function(request, context, status) { |
|
62 do_check_eq(this._last_callback_handled, TYPE_ONDATAAVAILABLE); |
|
63 do_check_true(this._got_onstatus_after_onstartrequest); |
|
64 this._last_callback_handled = TYPE_ONSTOPREQUEST; |
|
65 |
|
66 this._listener.onStopRequest(request, context, status); |
|
67 delete this._listener; |
|
68 }, |
|
69 |
|
70 onProgress: function (request, context, progress, progressMax) { |
|
71 do_check_eq(this._last_callback_handled, TYPE_ONSTATUS); |
|
72 this._last_callback_handled = TYPE_ONPROGRESS; |
|
73 |
|
74 do_check_eq(mStatus, STATUS_RECEIVING_FROM); |
|
75 last = progress; |
|
76 max = progressMax; |
|
77 }, |
|
78 |
|
79 onStatus: function (request, context, status, statusArg) { |
|
80 if (!this._got_onstartrequest) { |
|
81 // Ensure that all messages before onStartRequest are onStatus |
|
82 if (this._last_callback_handled) |
|
83 do_check_eq(this._last_callback_handled, TYPE_ONSTATUS); |
|
84 } else if (this._last_callback_handled == TYPE_ONSTARTREQUEST) { |
|
85 this._got_onstatus_after_onstartrequest = true; |
|
86 } else { |
|
87 do_check_eq(this._last_callback_handled, TYPE_ONDATAAVAILABLE); |
|
88 } |
|
89 this._last_callback_handled = TYPE_ONSTATUS; |
|
90 |
|
91 do_check_eq(statusArg, "localhost"); |
|
92 mStatus = status; |
|
93 }, |
|
94 |
|
95 mStatus: 0, |
|
96 }; |
|
97 |
|
98 function run_test() { |
|
99 httpserver.registerPathHandler(testpath, serverHandler); |
|
100 httpserver.start(-1); |
|
101 var channel = setupChannel(testpath); |
|
102 channel.asyncOpen(progressCallback, null); |
|
103 do_test_pending(); |
|
104 } |
|
105 |
|
106 function setupChannel(path) { |
|
107 var ios = Cc["@mozilla.org/network/io-service;1"]. |
|
108 getService(Ci.nsIIOService); |
|
109 var chan = ios.newChannel(URL + path, "", null); |
|
110 chan.QueryInterface(Ci.nsIHttpChannel); |
|
111 chan.requestMethod = "GET"; |
|
112 chan.notificationCallbacks = progressCallback; |
|
113 return chan; |
|
114 } |
|
115 |
|
116 function serverHandler(metadata, response) { |
|
117 response.setHeader("Content-Type", "text/plain", false); |
|
118 for (let i = 0; i < LOOPS; i++) |
|
119 response.bodyOutputStream.write(httpbody, httpbody.length); |
|
120 } |
|
121 |
|
122 function checkRequest(request, data, context) { |
|
123 do_check_eq(last, httpbody.length*LOOPS); |
|
124 do_check_eq(max, httpbody.length*LOOPS); |
|
125 httpserver.stop(do_test_finished); |
|
126 } |