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