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 "XMLHttpRequest.h"
11 #include "XMLHttpRequestString.h"
12 #include "mozilla/dom/TypedArray.h"
13 #include "mozilla/dom/WorkerHolder.h"
14 
15 namespace mozilla {
16 namespace dom {
17 
18 class Proxy;
19 class SendRunnable;
20 class DOMString;
21 class WorkerPrivate;
22 
23 class XMLHttpRequestWorker final : public XMLHttpRequest, public WorkerHolder {
24  public:
25   struct StateData {
26     XMLHttpRequestStringSnapshot mResponseText;
27     nsString mResponseURL;
28     uint32_t mStatus;
29     nsCString mStatusText;
30     uint16_t mReadyState;
31     bool mFlagSend;
32     JS::Heap<JS::Value> mResponse;
33     nsresult mResponseTextResult;
34     nsresult mStatusResult;
35     nsresult mResponseResult;
36 
StateDataStateData37     StateData()
38         : mStatus(0),
39           mReadyState(0),
40           mFlagSend(false),
41           mResponse(JS::UndefinedValue()),
42           mResponseTextResult(NS_OK),
43           mStatusResult(NS_OK),
44           mResponseResult(NS_OK) {}
45 
46     void trace(JSTracer* trc);
47   };
48 
49  private:
50   RefPtr<XMLHttpRequestUpload> mUpload;
51   WorkerPrivate* mWorkerPrivate;
52   RefPtr<Proxy> mProxy;
53   XMLHttpRequestResponseType mResponseType;
54   StateData mStateData;
55 
56   uint32_t mTimeout;
57 
58   bool mRooted;
59   bool mBackgroundRequest;
60   bool mWithCredentials;
61   bool mCanceled;
62 
63   bool mMozAnon;
64   bool mMozSystem;
65 
66  public:
67   NS_DECL_ISUPPORTS_INHERITED
68   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(XMLHttpRequestWorker,
69                                                          XMLHttpRequest)
70 
71   static already_AddRefed<XMLHttpRequest> Construct(
72       const GlobalObject& aGlobal, const MozXMLHttpRequestParameters& aParams,
73       ErrorResult& aRv);
74 
75   void Unpin();
76 
77   bool Notify(WorkerStatus aStatus) override;
78 
ReadyState()79   virtual uint16_t ReadyState() const override {
80     return mStateData.mReadyState;
81   }
82 
Open(const nsACString & aMethod,const nsAString & aUrl,ErrorResult & aRv)83   virtual void Open(const nsACString& aMethod, const nsAString& aUrl,
84                     ErrorResult& aRv) override {
85     Open(aMethod, aUrl, true, Optional<nsAString>(), Optional<nsAString>(),
86          aRv);
87   }
88 
Open(const nsACString & aMethod,const nsAString & aUrl,bool aAsync,const nsAString & aUsername,const nsAString & aPassword,ErrorResult & aRv)89   virtual void Open(const nsACString& aMethod, const nsAString& aUrl,
90                     bool aAsync, const nsAString& aUsername,
91                     const nsAString& aPassword, ErrorResult& aRv) override {
92     Optional<nsAString> username;
93     username = &aUsername;
94     Optional<nsAString> password;
95     password = &aPassword;
96     Open(aMethod, aUrl, aAsync, username, password, aRv);
97   }
98 
99   void Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync,
100             const Optional<nsAString>& aUser,
101             const Optional<nsAString>& aPassword, ErrorResult& aRv);
102 
103   virtual void SetRequestHeader(const nsACString& aHeader,
104                                 const nsACString& aValue,
105                                 ErrorResult& aRv) override;
106 
Timeout()107   virtual uint32_t Timeout() const override { return mTimeout; }
108 
109   virtual void SetTimeout(uint32_t aTimeout, ErrorResult& aRv) override;
110 
WithCredentials()111   virtual bool WithCredentials() const override { return mWithCredentials; }
112 
113   virtual void SetWithCredentials(bool aWithCredentials,
114                                   ErrorResult& aRv) override;
115 
MozBackgroundRequest()116   virtual bool MozBackgroundRequest() const override {
117     return mBackgroundRequest;
118   }
119 
120   virtual void SetMozBackgroundRequest(bool aBackgroundRequest,
121                                        ErrorResult& aRv) override;
122 
GetChannel()123   virtual nsIChannel* GetChannel() const override {
124     MOZ_CRASH("This method cannot be called on workers.");
125   }
126 
GetNetworkInterfaceId(nsACString & aId)127   virtual void GetNetworkInterfaceId(nsACString& aId) const override {
128     MOZ_CRASH("This method cannot be called on workers.");
129   }
130 
SetNetworkInterfaceId(const nsACString & aId)131   virtual void SetNetworkInterfaceId(const nsACString& aId) override {
132     MOZ_CRASH("This method cannot be called on workers.");
133   }
134 
135   virtual XMLHttpRequestUpload* GetUpload(ErrorResult& aRv) override;
136 
137   virtual void Send(
138       JSContext* aCx,
139       const Nullable<
140           DocumentOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString>&
141           aData,
142       ErrorResult& aRv) override;
143 
SendInputStream(nsIInputStream * aInputStream,ErrorResult & aRv)144   virtual void SendInputStream(nsIInputStream* aInputStream,
145                                ErrorResult& aRv) override {
146     MOZ_CRASH("nsIInputStream is not a valid argument for XHR in workers.");
147   }
148 
149   virtual void Abort(ErrorResult& aRv) override;
150 
GetResponseURL(nsAString & aUrl)151   virtual void GetResponseURL(nsAString& aUrl) override {
152     aUrl = mStateData.mResponseURL;
153   }
154 
GetStatus(ErrorResult & aRv)155   uint32_t GetStatus(ErrorResult& aRv) override {
156     aRv = mStateData.mStatusResult;
157     return mStateData.mStatus;
158   }
159 
GetStatusText(nsACString & aStatusText,ErrorResult & aRv)160   virtual void GetStatusText(nsACString& aStatusText,
161                              ErrorResult& aRv) override {
162     aStatusText = mStateData.mStatusText;
163   }
164 
165   virtual void GetResponseHeader(const nsACString& aHeader,
166                                  nsACString& aResponseHeader,
167                                  ErrorResult& aRv) override;
168 
169   virtual void GetAllResponseHeaders(nsACString& aResponseHeaders,
170                                      ErrorResult& aRv) override;
171 
172   virtual void OverrideMimeType(const nsAString& aMimeType,
173                                 ErrorResult& aRv) override;
174 
ResponseType()175   virtual XMLHttpRequestResponseType ResponseType() const override {
176     return mResponseType;
177   }
178 
179   virtual void SetResponseType(XMLHttpRequestResponseType aResponseType,
180                                ErrorResult& aRv) override;
181 
182   virtual void GetResponse(JSContext* /* unused */,
183                            JS::MutableHandle<JS::Value> aResponse,
184                            ErrorResult& aRv) override;
185 
186   virtual void GetResponseText(DOMString& aResponseText,
187                                ErrorResult& aRv) override;
188 
GetResponseXML(ErrorResult & aRv)189   virtual nsIDocument* GetResponseXML(ErrorResult& aRv) override {
190     MOZ_CRASH("This method should not be called.");
191   }
192 
GetInterface(JSContext * aCx,nsIJSID * aIID,JS::MutableHandle<JS::Value> aRetval,ErrorResult & aRv)193   virtual void GetInterface(JSContext* aCx, nsIJSID* aIID,
194                             JS::MutableHandle<JS::Value> aRetval,
195                             ErrorResult& aRv) override {
196     aRv.Throw(NS_ERROR_FAILURE);
197   }
198 
SetOriginAttributes(const mozilla::dom::OriginAttributesDictionary & aAttrs)199   virtual void SetOriginAttributes(
200       const mozilla::dom::OriginAttributesDictionary& aAttrs) override {
201     MOZ_CRASH("This method cannot be called on workers.");
202   }
203 
GetUploadObjectNoCreate()204   XMLHttpRequestUpload* GetUploadObjectNoCreate() const { return mUpload; }
205 
206   void UpdateState(const StateData& aStateData,
207                    bool aUseCachedArrayBufferResponse);
208 
NullResponseText()209   void NullResponseText() {
210     mStateData.mResponseText.SetVoid();
211     mStateData.mResponse.setNull();
212   }
213 
ErrorCode()214   virtual uint16_t ErrorCode() const override {
215     return 0;  // eOK
216   }
217 
MozAnon()218   virtual bool MozAnon() const override { return mMozAnon; }
219 
MozSystem()220   virtual bool MozSystem() const override { return mMozSystem; }
221 
SendInProgress()222   bool SendInProgress() const { return mRooted; }
223 
224  private:
225   explicit XMLHttpRequestWorker(WorkerPrivate* aWorkerPrivate);
226   ~XMLHttpRequestWorker();
227 
228   enum ReleaseType { Default, XHRIsGoingAway, WorkerIsGoingAway };
229 
230   void ReleaseProxy(ReleaseType aType = Default);
231 
232   void MaybePin(ErrorResult& aRv);
233 
234   void MaybeDispatchPrematureAbortEvents(ErrorResult& aRv);
235 
236   void DispatchPrematureAbortEvent(EventTarget* aTarget,
237                                    const nsAString& aEventType,
238                                    bool aUploadTarget, ErrorResult& aRv);
239 
240   void Send(JSContext* aCx, JS::Handle<JSObject*> aBody, ErrorResult& aRv);
241 
242   void SendInternal(SendRunnable* aRunnable, ErrorResult& aRv);
243 };
244 
245 }  // namespace dom
246 }  // namespace mozilla
247 
248 #endif  // mozilla_dom_workers_xmlhttprequest_h__
249