Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsPluginStreamListenerPeer_h_
7 #define nsPluginStreamListenerPeer_h_
9 #include "nscore.h"
10 #include "nsIFile.h"
11 #include "nsIStreamListener.h"
12 #include "nsIProgressEventSink.h"
13 #include "nsIHttpHeaderVisitor.h"
14 #include "nsWeakReference.h"
15 #include "nsNPAPIPluginStreamListener.h"
16 #include "nsDataHashtable.h"
17 #include "nsHashKeys.h"
18 #include "nsNPAPIPluginInstance.h"
19 #include "nsIInterfaceRequestor.h"
20 #include "nsIChannelEventSink.h"
22 class nsIChannel;
24 /**
25 * When a plugin requests opens multiple requests to the same URL and
26 * the request must be satified by saving a file to disk, each stream
27 * listener holds a reference to the backing file: the file is only removed
28 * when all the listeners are done.
29 */
30 class CachedFileHolder
31 {
32 public:
33 CachedFileHolder(nsIFile* cacheFile);
34 ~CachedFileHolder();
36 void AddRef();
37 void Release();
39 nsIFile* file() const { return mFile; }
41 private:
42 nsAutoRefCnt mRefCnt;
43 nsCOMPtr<nsIFile> mFile;
44 };
46 class nsPluginStreamListenerPeer : public nsIStreamListener,
47 public nsIProgressEventSink,
48 public nsIHttpHeaderVisitor,
49 public nsSupportsWeakReference,
50 public nsIInterfaceRequestor,
51 public nsIChannelEventSink
52 {
53 public:
54 nsPluginStreamListenerPeer();
55 virtual ~nsPluginStreamListenerPeer();
57 NS_DECL_ISUPPORTS
58 NS_DECL_NSIPROGRESSEVENTSINK
59 NS_DECL_NSIREQUESTOBSERVER
60 NS_DECL_NSISTREAMLISTENER
61 NS_DECL_NSIHTTPHEADERVISITOR
62 NS_DECL_NSIINTERFACEREQUESTOR
63 NS_DECL_NSICHANNELEVENTSINK
65 // Called by RequestRead
66 void
67 MakeByteRangeString(NPByteRange* aRangeList, nsACString &string, int32_t *numRequests);
69 bool UseExistingPluginCacheFile(nsPluginStreamListenerPeer* psi);
71 // Called by GetURL and PostURL (via NewStream) or by the host in the case of
72 // the initial plugin stream.
73 nsresult Initialize(nsIURI *aURL,
74 nsNPAPIPluginInstance *aInstance,
75 nsNPAPIPluginStreamListener *aListener);
77 nsresult OnFileAvailable(nsIFile* aFile);
79 nsresult ServeStreamAsFile(nsIRequest *request, nsISupports *ctxt);
81 nsNPAPIPluginInstance *GetPluginInstance() { return mPluginInstance; }
83 nsresult RequestRead(NPByteRange* rangeList);
84 nsresult GetLength(uint32_t* result);
85 nsresult GetURL(const char** result);
86 nsresult GetLastModified(uint32_t* result);
87 nsresult IsSeekable(bool* result);
88 nsresult GetContentType(char** result);
89 nsresult GetStreamOffset(int32_t* result);
90 nsresult SetStreamOffset(int32_t value);
92 void TrackRequest(nsIRequest* request)
93 {
94 mRequests.AppendObject(request);
95 }
97 void ReplaceRequest(nsIRequest* oldRequest, nsIRequest* newRequest)
98 {
99 int32_t i = mRequests.IndexOfObject(oldRequest);
100 if (i == -1) {
101 NS_ASSERTION(mRequests.Count() == 0,
102 "Only our initial stream should be unknown!");
103 mRequests.AppendObject(oldRequest);
104 }
105 else {
106 mRequests.ReplaceObjectAt(newRequest, i);
107 }
108 }
110 void CancelRequests(nsresult status)
111 {
112 // Copy the array to avoid modification during the loop.
113 nsCOMArray<nsIRequest> requestsCopy(mRequests);
114 for (int32_t i = 0; i < requestsCopy.Count(); ++i)
115 requestsCopy[i]->Cancel(status);
116 }
118 void SuspendRequests() {
119 nsCOMArray<nsIRequest> requestsCopy(mRequests);
120 for (int32_t i = 0; i < requestsCopy.Count(); ++i)
121 requestsCopy[i]->Suspend();
122 }
124 void ResumeRequests() {
125 nsCOMArray<nsIRequest> requestsCopy(mRequests);
126 for (int32_t i = 0; i < requestsCopy.Count(); ++i)
127 requestsCopy[i]->Resume();
128 }
130 private:
131 nsresult SetUpStreamListener(nsIRequest* request, nsIURI* aURL);
132 nsresult SetupPluginCacheFile(nsIChannel* channel);
133 nsresult GetInterfaceGlobal(const nsIID& aIID, void** result);
135 nsCOMPtr<nsIURI> mURL;
136 nsCString mURLSpec; // Have to keep this member because GetURL hands out char*
137 nsRefPtr<nsNPAPIPluginStreamListener> mPStreamListener;
139 // Set to true if we request failed (like with a HTTP response of 404)
140 bool mRequestFailed;
142 /*
143 * Set to true after nsNPAPIPluginStreamListener::OnStartBinding() has
144 * been called. Checked in ::OnStopRequest so we can call the
145 * plugin's OnStartBinding if, for some reason, it has not already
146 * been called.
147 */
148 bool mStartBinding;
149 bool mHaveFiredOnStartRequest;
150 // these get passed to the plugin stream listener
151 uint32_t mLength;
152 int32_t mStreamType;
154 // local cached file, we save the content into local cache if browser cache is not available,
155 // or plugin asks stream as file and it expects file extension until bug 90558 got fixed
156 nsRefPtr<CachedFileHolder> mLocalCachedFileHolder;
157 nsCOMPtr<nsIOutputStream> mFileCacheOutputStream;
158 nsDataHashtable<nsUint32HashKey, uint32_t>* mDataForwardToRequest;
160 nsCString mContentType;
161 bool mSeekable;
162 uint32_t mModified;
163 nsRefPtr<nsNPAPIPluginInstance> mPluginInstance;
164 int32_t mStreamOffset;
165 bool mStreamComplete;
167 public:
168 bool mAbort;
169 int32_t mPendingRequests;
170 nsWeakPtr mWeakPtrChannelCallbacks;
171 nsWeakPtr mWeakPtrChannelLoadGroup;
172 nsCOMArray<nsIRequest> mRequests;
173 };
175 #endif // nsPluginStreamListenerPeer_h_