1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_dom_XMLHttpRequestWorker_h
8 #define mozilla_dom_XMLHttpRequestWorker_h
9 
10 #include "WorkerHolder.h"
11 #include "XMLHttpRequest.h"
12 #include "XMLHttpRequestString.h"
13 #include "mozilla/dom/TypedArray.h"
14 
15 namespace mozilla {
16 namespace dom {
17 
18 class Proxy;
19 class SendRunnable;
20 class DOMString;
21 
22 namespace workers {
23 class WorkerPrivate;
24 }
25 
26 class XMLHttpRequestWorker final : public XMLHttpRequest,
27                                    public workers::WorkerHolder
28 {
29 public:
30   struct StateData
31   {
32     XMLHttpRequestStringSnapshot mResponseText;
33     nsString mResponseURL;
34     uint32_t mStatus;
35     nsCString mStatusText;
36     uint16_t mReadyState;
37     JS::Heap<JS::Value> mResponse;
38     nsresult mResponseTextResult;
39     nsresult mStatusResult;
40     nsresult mResponseResult;
41 
StateDataStateData42     StateData()
43     : mStatus(0), mReadyState(0), mResponse(JS::UndefinedValue()),
44       mResponseTextResult(NS_OK), mStatusResult(NS_OK),
45       mResponseResult(NS_OK)
46     { }
47 
48     void trace(JSTracer* trc);
49   };
50 
51 private:
52   RefPtr<XMLHttpRequestUpload> mUpload;
53   workers::WorkerPrivate* mWorkerPrivate;
54   RefPtr<Proxy> mProxy;
55   XMLHttpRequestResponseType mResponseType;
56   StateData mStateData;
57 
58   uint32_t mTimeout;
59 
60   bool mRooted;
61   bool mBackgroundRequest;
62   bool mWithCredentials;
63   bool mCanceled;
64 
65   bool mMozAnon;
66   bool mMozSystem;
67 
68 public:
69   NS_DECL_ISUPPORTS_INHERITED
70   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(XMLHttpRequestWorker,
71                                                          XMLHttpRequest)
72 
73 
74   static already_AddRefed<XMLHttpRequest>
75   Construct(const GlobalObject& aGlobal,
76             const MozXMLHttpRequestParameters& aParams,
77             ErrorResult& aRv);
78 
79   void
80   Unpin();
81 
82   bool
83   Notify(workers::Status aStatus) override;
84 
85   virtual uint16_t
ReadyState()86   ReadyState() const override
87   {
88     return mStateData.mReadyState;
89   }
90 
91   virtual void
Open(const nsACString & aMethod,const nsAString & aUrl,ErrorResult & aRv)92   Open(const nsACString& aMethod, const nsAString& aUrl,
93        ErrorResult& aRv) override
94   {
95     Open(aMethod, aUrl, true, Optional<nsAString>(),
96          Optional<nsAString>(), aRv);
97   }
98 
99   virtual void
Open(const nsACString & aMethod,const nsAString & aUrl,bool aAsync,const nsAString & aUsername,const nsAString & aPassword,ErrorResult & aRv)100   Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync,
101        const nsAString& aUsername, const nsAString& aPassword,
102        ErrorResult& aRv) override
103   {
104     Optional<nsAString> username;
105     username = &aUsername;
106     Optional<nsAString> password;
107     password = &aPassword;
108     Open(aMethod, aUrl, aAsync, username, password, aRv);
109   }
110 
111   void
112   Open(const nsACString& aMethod, const nsAString& aUrl,
113        bool aAsync, const Optional<nsAString>& aUser,
114        const Optional<nsAString>& aPassword, ErrorResult& aRv);
115 
116   virtual void
117   SetRequestHeader(const nsACString& aHeader, const nsACString& aValue,
118                    ErrorResult& aRv) override;
119 
120   virtual uint32_t
Timeout()121   Timeout() const override
122   {
123     return mTimeout;
124   }
125 
126   virtual void
127   SetTimeout(uint32_t aTimeout, ErrorResult& aRv) override;
128 
129   virtual bool
WithCredentials()130   WithCredentials() const override
131   {
132     return mWithCredentials;
133   }
134 
135   virtual void
136   SetWithCredentials(bool aWithCredentials, ErrorResult& aRv) override;
137 
138   virtual bool
MozBackgroundRequest()139   MozBackgroundRequest() const override
140   {
141     return mBackgroundRequest;
142   }
143 
144   virtual void
145   SetMozBackgroundRequest(bool aBackgroundRequest, ErrorResult& aRv) override;
146 
147   virtual nsIChannel*
GetChannel()148   GetChannel() const override
149   {
150     MOZ_CRASH("This method cannot be called on workers.");
151   }
152 
153   virtual void
GetNetworkInterfaceId(nsACString & aId)154   GetNetworkInterfaceId(nsACString& aId) const override
155   {
156     MOZ_CRASH("This method cannot be called on workers.");
157   }
158 
159   virtual void
SetNetworkInterfaceId(const nsACString & aId)160   SetNetworkInterfaceId(const nsACString& aId) override
161   {
162     MOZ_CRASH("This method cannot be called on workers.");
163   }
164 
165   virtual XMLHttpRequestUpload*
166   GetUpload(ErrorResult& aRv) override;
167 
168   virtual void
169   Send(JSContext* aCx, ErrorResult& aRv) override;
170 
171   virtual void
172   Send(JSContext* aCx, const nsAString& aBody, ErrorResult& aRv) override;
173 
174   virtual void
Send(JSContext * aCx,nsIInputStream * aStream,ErrorResult & aRv)175   Send(JSContext* aCx, nsIInputStream* aStream, ErrorResult& aRv) override
176   {
177     MOZ_CRASH("This method cannot be called on workers.");
178   }
179 
180   virtual void
181   Send(JSContext* aCx, Blob& aBody, ErrorResult& aRv) override;
182 
183   virtual void
184   Send(JSContext* aCx, FormData& aBody, ErrorResult& aRv) override;
185 
186   virtual void
187   Send(JSContext* aCx, const ArrayBuffer& aBody, ErrorResult& aRv) override;
188 
189   virtual void
190   Send(JSContext* aCx, const ArrayBufferView& aBody, ErrorResult& aRv) override;
191 
192   virtual void
193   Send(JSContext* aCx, URLSearchParams& aBody, ErrorResult& aRv) override;
194 
195   virtual void
Send(JSContext * aCx,nsIDocument & aDoc,ErrorResult & aRv)196   Send(JSContext* aCx, nsIDocument& aDoc, ErrorResult& aRv) override
197   {
198     MOZ_CRASH("This method cannot be called on workers.");
199   }
200 
201   virtual void
202   Abort(ErrorResult& aRv) override;
203 
204   virtual void
GetResponseURL(nsAString & aUrl)205   GetResponseURL(nsAString& aUrl) override
206   {
207     aUrl = mStateData.mResponseURL;
208   }
209 
210   uint32_t
GetStatus(ErrorResult & aRv)211   GetStatus(ErrorResult& aRv) override
212   {
213     aRv = mStateData.mStatusResult;
214     return mStateData.mStatus;
215   }
216 
217   virtual void
GetStatusText(nsACString & aStatusText,ErrorResult & aRv)218   GetStatusText(nsACString& aStatusText, ErrorResult& aRv) override
219   {
220     aStatusText = mStateData.mStatusText;
221   }
222 
223   virtual void
224   GetResponseHeader(const nsACString& aHeader, nsACString& aResponseHeader,
225                     ErrorResult& aRv) override;
226 
227   virtual void
228   GetAllResponseHeaders(nsACString& aResponseHeaders,
229                         ErrorResult& aRv) override;
230 
231   virtual void
232   OverrideMimeType(const nsAString& aMimeType, ErrorResult& aRv) override;
233 
234   virtual XMLHttpRequestResponseType
ResponseType()235   ResponseType() const override
236   {
237     return mResponseType;
238   }
239 
240   virtual void
241   SetResponseType(XMLHttpRequestResponseType aResponseType,
242                   ErrorResult& aRv) override;
243 
244   virtual void
245   GetResponse(JSContext* /* unused */, JS::MutableHandle<JS::Value> aResponse,
246               ErrorResult& aRv) override;
247 
248   virtual void
249   GetResponseText(DOMString& aResponseText, ErrorResult& aRv) override;
250 
251   virtual nsIDocument*
GetResponseXML(ErrorResult & aRv)252   GetResponseXML(ErrorResult& aRv) override
253   {
254     MOZ_CRASH("This method should not be called.");
255   }
256 
257   virtual void
GetInterface(JSContext * aCx,nsIJSID * aIID,JS::MutableHandle<JS::Value> aRetval,ErrorResult & aRv)258   GetInterface(JSContext* aCx, nsIJSID* aIID,
259                JS::MutableHandle<JS::Value> aRetval,
260                ErrorResult& aRv) override
261   {
262     aRv.Throw(NS_ERROR_FAILURE);
263   }
264 
265   virtual void
SetOriginAttributes(const mozilla::dom::OriginAttributesDictionary & aAttrs)266   SetOriginAttributes(const mozilla::dom::OriginAttributesDictionary& aAttrs) override
267   {
268     MOZ_CRASH("This method cannot be called on workers.");
269   }
270 
271   XMLHttpRequestUpload*
GetUploadObjectNoCreate()272   GetUploadObjectNoCreate() const
273   {
274     return mUpload;
275   }
276 
277   void
278   UpdateState(const StateData& aStateData, bool aUseCachedArrayBufferResponse);
279 
280   void
NullResponseText()281   NullResponseText()
282   {
283     mStateData.mResponseText.SetVoid();
284     mStateData.mResponse.setNull();
285   }
286 
MozAnon()287   virtual bool MozAnon() const override
288   {
289     return mMozAnon;
290   }
291 
MozSystem()292   virtual bool MozSystem() const override
293   {
294     return mMozSystem;
295   }
296 
297   bool
SendInProgress()298   SendInProgress() const
299   {
300     return mRooted;
301   }
302 
303 private:
304   explicit XMLHttpRequestWorker(workers::WorkerPrivate* aWorkerPrivate);
305   ~XMLHttpRequestWorker();
306 
307   enum ReleaseType { Default, XHRIsGoingAway, WorkerIsGoingAway };
308 
309   void
310   ReleaseProxy(ReleaseType aType = Default);
311 
312   void
313   MaybePin(ErrorResult& aRv);
314 
315   void
316   MaybeDispatchPrematureAbortEvents(ErrorResult& aRv);
317 
318   void
319   DispatchPrematureAbortEvent(EventTarget* aTarget,
320                               const nsAString& aEventType, bool aUploadTarget,
321                               ErrorResult& aRv);
322 
323   void
324   Send(JSContext* aCx, JS::Handle<JSObject*> aBody, ErrorResult& aRv);
325 
326   void
327   SendInternal(SendRunnable* aRunnable,
328                ErrorResult& aRv);
329 };
330 
331 } // dom namespace
332 } // mozilla namespace
333 
334 #endif // mozilla_dom_workers_xmlhttprequest_h__
335