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