Line data Source code
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/. */
5 :
6 : #ifndef nsPluginStreamListenerPeer_h_
7 : #define nsPluginStreamListenerPeer_h_
8 :
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"
21 :
22 : class nsIChannel;
23 :
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 : explicit CachedFileHolder(nsIFile* cacheFile);
34 : ~CachedFileHolder();
35 :
36 : void AddRef();
37 : void Release();
38 :
39 0 : nsIFile* file() const { return mFile; }
40 :
41 : private:
42 : nsAutoRefCnt mRefCnt;
43 : nsCOMPtr<nsIFile> mFile;
44 : };
45 :
46 : class nsPluginStreamListenerPeer : public nsIStreamListener,
47 : public nsIProgressEventSink,
48 : public nsIHttpHeaderVisitor,
49 : public nsSupportsWeakReference,
50 : public nsIInterfaceRequestor,
51 : public nsIChannelEventSink
52 : {
53 : virtual ~nsPluginStreamListenerPeer();
54 :
55 : public:
56 : nsPluginStreamListenerPeer();
57 :
58 : NS_DECL_ISUPPORTS
59 : NS_DECL_NSIPROGRESSEVENTSINK
60 : NS_DECL_NSIREQUESTOBSERVER
61 : NS_DECL_NSISTREAMLISTENER
62 : NS_DECL_NSIHTTPHEADERVISITOR
63 : NS_DECL_NSIINTERFACEREQUESTOR
64 : NS_DECL_NSICHANNELEVENTSINK
65 :
66 : // Called by RequestRead
67 : void
68 : MakeByteRangeString(NPByteRange* aRangeList, nsACString &string, int32_t *numRequests);
69 :
70 : bool UseExistingPluginCacheFile(nsPluginStreamListenerPeer* psi);
71 :
72 : // Called by GetURL and PostURL (via NewStream) or by the host in the case of
73 : // the initial plugin stream.
74 : nsresult Initialize(nsIURI *aURL,
75 : nsNPAPIPluginInstance *aInstance,
76 : nsNPAPIPluginStreamListener *aListener);
77 :
78 : nsresult OnFileAvailable(nsIFile* aFile);
79 :
80 : nsresult ServeStreamAsFile(nsIRequest *request, nsISupports *ctxt);
81 :
82 0 : nsNPAPIPluginInstance *GetPluginInstance() { return mPluginInstance; }
83 :
84 : nsresult RequestRead(NPByteRange* rangeList);
85 : nsresult GetLength(uint32_t* result);
86 : nsresult GetURL(const char** result);
87 : nsresult GetLastModified(uint32_t* result);
88 : nsresult IsSeekable(bool* result);
89 : nsresult GetContentType(char** result);
90 : nsresult GetStreamOffset(int32_t* result);
91 : nsresult SetStreamOffset(int32_t value);
92 :
93 0 : void TrackRequest(nsIRequest* request)
94 : {
95 0 : mRequests.AppendObject(request);
96 0 : }
97 :
98 0 : void ReplaceRequest(nsIRequest* oldRequest, nsIRequest* newRequest)
99 : {
100 0 : int32_t i = mRequests.IndexOfObject(oldRequest);
101 0 : if (i == -1) {
102 0 : NS_ASSERTION(mRequests.Count() == 0,
103 : "Only our initial stream should be unknown!");
104 0 : mRequests.AppendObject(oldRequest);
105 : }
106 : else {
107 0 : mRequests.ReplaceObjectAt(newRequest, i);
108 : }
109 0 : }
110 :
111 0 : void CancelRequests(nsresult status)
112 : {
113 : // Copy the array to avoid modification during the loop.
114 0 : nsCOMArray<nsIRequest> requestsCopy(mRequests);
115 0 : for (int32_t i = 0; i < requestsCopy.Count(); ++i)
116 0 : requestsCopy[i]->Cancel(status);
117 0 : }
118 :
119 0 : void SuspendRequests() {
120 0 : nsCOMArray<nsIRequest> requestsCopy(mRequests);
121 0 : for (int32_t i = 0; i < requestsCopy.Count(); ++i)
122 0 : requestsCopy[i]->Suspend();
123 0 : }
124 :
125 0 : void ResumeRequests() {
126 0 : nsCOMArray<nsIRequest> requestsCopy(mRequests);
127 0 : for (int32_t i = 0; i < requestsCopy.Count(); ++i)
128 0 : requestsCopy[i]->Resume();
129 0 : }
130 :
131 : // Called by nsNPAPIPluginStreamListener
132 : void OnStreamTypeSet(const int32_t aStreamType);
133 :
134 : enum {
135 : STREAM_TYPE_UNKNOWN = UINT16_MAX
136 : };
137 :
138 : private:
139 : nsresult SetUpStreamListener(nsIRequest* request, nsIURI* aURL);
140 : nsresult SetupPluginCacheFile(nsIChannel* channel);
141 : nsresult GetInterfaceGlobal(const nsIID& aIID, void** result);
142 :
143 : nsCOMPtr<nsIURI> mURL;
144 : nsCString mURLSpec; // Have to keep this member because GetURL hands out char*
145 : RefPtr<nsNPAPIPluginStreamListener> mPStreamListener;
146 :
147 : // Set to true if we request failed (like with a HTTP response of 404)
148 : bool mRequestFailed;
149 :
150 : /*
151 : * Set to true after nsNPAPIPluginStreamListener::OnStartBinding() has
152 : * been called. Checked in ::OnStopRequest so we can call the
153 : * plugin's OnStartBinding if, for some reason, it has not already
154 : * been called.
155 : */
156 : bool mStartBinding;
157 : bool mHaveFiredOnStartRequest;
158 : // these get passed to the plugin stream listener
159 : uint32_t mLength;
160 : int32_t mStreamType;
161 :
162 : // local cached file, we save the content into local cache if browser cache is not available,
163 : // or plugin asks stream as file and it expects file extension until bug 90558 got fixed
164 : RefPtr<CachedFileHolder> mLocalCachedFileHolder;
165 : nsCOMPtr<nsIOutputStream> mFileCacheOutputStream;
166 : nsDataHashtable<nsUint32HashKey, uint32_t>* mDataForwardToRequest;
167 :
168 : nsCString mContentType;
169 : bool mUseLocalCache;
170 : nsCOMPtr<nsIRequest> mRequest;
171 : bool mSeekable;
172 : uint32_t mModified;
173 : RefPtr<nsNPAPIPluginInstance> mPluginInstance;
174 : int32_t mStreamOffset;
175 : bool mStreamComplete;
176 :
177 : public:
178 : bool mAbort;
179 : int32_t mPendingRequests;
180 : nsWeakPtr mWeakPtrChannelCallbacks;
181 : nsWeakPtr mWeakPtrChannelLoadGroup;
182 : nsCOMArray<nsIRequest> mRequests;
183 : };
184 :
185 : #endif // nsPluginStreamListenerPeer_h_
|