|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
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 __nsFtpState__h_ |
|
7 #define __nsFtpState__h_ |
|
8 |
|
9 #include "nsBaseContentStream.h" |
|
10 |
|
11 #include "nsICacheListener.h" |
|
12 #include "nsString.h" |
|
13 #include "nsCOMPtr.h" |
|
14 #include "nsIAsyncInputStream.h" |
|
15 #include "nsAutoPtr.h" |
|
16 #include "nsITransport.h" |
|
17 #include "mozilla/net/DNS.h" |
|
18 #include "nsFtpControlConnection.h" |
|
19 #include "nsIProtocolProxyCallback.h" |
|
20 |
|
21 #ifdef MOZ_WIDGET_GONK |
|
22 #include "nsINetworkManager.h" |
|
23 #include "nsProxyRelease.h" |
|
24 #endif |
|
25 |
|
26 // ftp server types |
|
27 #define FTP_GENERIC_TYPE 0 |
|
28 #define FTP_UNIX_TYPE 1 |
|
29 #define FTP_VMS_TYPE 8 |
|
30 #define FTP_NT_TYPE 9 |
|
31 #define FTP_OS2_TYPE 11 |
|
32 |
|
33 // ftp states |
|
34 typedef enum _FTP_STATE { |
|
35 /////////////////////// |
|
36 //// Internal states |
|
37 FTP_INIT, |
|
38 FTP_WAIT_CACHE, |
|
39 FTP_READ_CACHE, |
|
40 FTP_COMMAND_CONNECT, |
|
41 FTP_READ_BUF, |
|
42 FTP_ERROR, |
|
43 FTP_COMPLETE, |
|
44 |
|
45 /////////////////////// |
|
46 //// Command channel connection setup states |
|
47 FTP_S_USER, FTP_R_USER, |
|
48 FTP_S_PASS, FTP_R_PASS, |
|
49 FTP_S_SYST, FTP_R_SYST, |
|
50 FTP_S_ACCT, FTP_R_ACCT, |
|
51 FTP_S_TYPE, FTP_R_TYPE, |
|
52 FTP_S_CWD, FTP_R_CWD, |
|
53 FTP_S_SIZE, FTP_R_SIZE, |
|
54 FTP_S_MDTM, FTP_R_MDTM, |
|
55 FTP_S_REST, FTP_R_REST, |
|
56 FTP_S_RETR, FTP_R_RETR, |
|
57 FTP_S_STOR, FTP_R_STOR, |
|
58 FTP_S_LIST, FTP_R_LIST, |
|
59 FTP_S_PASV, FTP_R_PASV, |
|
60 FTP_S_PWD, FTP_R_PWD, |
|
61 FTP_S_FEAT, FTP_R_FEAT, |
|
62 FTP_S_OPTS, FTP_R_OPTS |
|
63 } FTP_STATE; |
|
64 |
|
65 // higher level ftp actions |
|
66 typedef enum _FTP_ACTION {GET, PUT} FTP_ACTION; |
|
67 |
|
68 class nsFtpChannel; |
|
69 class nsICancelable; |
|
70 class nsICacheEntryDescriptor; |
|
71 class nsIProxyInfo; |
|
72 class nsIStreamListener; |
|
73 |
|
74 // The nsFtpState object is the content stream for the channel. It implements |
|
75 // nsIInputStreamCallback, so it can read data from the control connection. It |
|
76 // implements nsITransportEventSink so it can mix status events from both the |
|
77 // control connection and the data connection. |
|
78 |
|
79 class nsFtpState : public nsBaseContentStream, |
|
80 public nsIInputStreamCallback, |
|
81 public nsITransportEventSink, |
|
82 public nsICacheListener, |
|
83 public nsIRequestObserver, |
|
84 public nsFtpControlConnectionListener, |
|
85 public nsIProtocolProxyCallback |
|
86 { |
|
87 public: |
|
88 NS_DECL_ISUPPORTS_INHERITED |
|
89 NS_DECL_NSIINPUTSTREAMCALLBACK |
|
90 NS_DECL_NSITRANSPORTEVENTSINK |
|
91 NS_DECL_NSICACHELISTENER |
|
92 NS_DECL_NSIREQUESTOBSERVER |
|
93 NS_DECL_NSIPROTOCOLPROXYCALLBACK |
|
94 |
|
95 // Override input stream methods: |
|
96 NS_IMETHOD CloseWithStatus(nsresult status); |
|
97 NS_IMETHOD Available(uint64_t *result); |
|
98 NS_IMETHOD ReadSegments(nsWriteSegmentFun fun, void *closure, |
|
99 uint32_t count, uint32_t *result); |
|
100 |
|
101 // nsFtpControlConnectionListener methods: |
|
102 virtual void OnControlDataAvailable(const char *data, uint32_t dataLen); |
|
103 virtual void OnControlError(nsresult status); |
|
104 |
|
105 nsFtpState(); |
|
106 nsresult Init(nsFtpChannel *channel); |
|
107 |
|
108 protected: |
|
109 // Notification from nsBaseContentStream::AsyncWait |
|
110 virtual void OnCallbackPending(); |
|
111 |
|
112 private: |
|
113 virtual ~nsFtpState(); |
|
114 |
|
115 /////////////////////////////////// |
|
116 // BEGIN: STATE METHODS |
|
117 nsresult S_user(); FTP_STATE R_user(); |
|
118 nsresult S_pass(); FTP_STATE R_pass(); |
|
119 nsresult S_syst(); FTP_STATE R_syst(); |
|
120 nsresult S_acct(); FTP_STATE R_acct(); |
|
121 |
|
122 nsresult S_type(); FTP_STATE R_type(); |
|
123 nsresult S_cwd(); FTP_STATE R_cwd(); |
|
124 |
|
125 nsresult S_size(); FTP_STATE R_size(); |
|
126 nsresult S_mdtm(); FTP_STATE R_mdtm(); |
|
127 nsresult S_list(); FTP_STATE R_list(); |
|
128 |
|
129 nsresult S_rest(); FTP_STATE R_rest(); |
|
130 nsresult S_retr(); FTP_STATE R_retr(); |
|
131 nsresult S_stor(); FTP_STATE R_stor(); |
|
132 nsresult S_pasv(); FTP_STATE R_pasv(); |
|
133 nsresult S_pwd(); FTP_STATE R_pwd(); |
|
134 nsresult S_feat(); FTP_STATE R_feat(); |
|
135 nsresult S_opts(); FTP_STATE R_opts(); |
|
136 // END: STATE METHODS |
|
137 /////////////////////////////////// |
|
138 |
|
139 // internal methods |
|
140 void MoveToNextState(FTP_STATE nextState); |
|
141 nsresult Process(); |
|
142 |
|
143 void KillControlConnection(); |
|
144 nsresult StopProcessing(); |
|
145 nsresult EstablishControlConnection(); |
|
146 nsresult SendFTPCommand(const nsCSubstring& command); |
|
147 void ConvertFilespecToVMS(nsCString& fileSpec); |
|
148 void ConvertDirspecToVMS(nsCString& fileSpec); |
|
149 void ConvertDirspecFromVMS(nsCString& fileSpec); |
|
150 nsresult BuildStreamConverter(nsIStreamListener** convertStreamListener); |
|
151 nsresult SetContentType(); |
|
152 |
|
153 /** |
|
154 * This method is called to kick-off the FTP state machine. mState is |
|
155 * reset to FTP_COMMAND_CONNECT, and the FTP state machine progresses from |
|
156 * there. This method is initially called (indirectly) from the channel's |
|
157 * AsyncOpen implementation. |
|
158 */ |
|
159 void Connect(); |
|
160 |
|
161 /** |
|
162 * This method opens a cache entry for reading or writing depending on the |
|
163 * state of the channel and of the system (e.g., opened for reading if we |
|
164 * are offline). This method is responsible for setting mCacheEntry if |
|
165 * there is a cache entry that can be used. It returns true if it ends up |
|
166 * waiting (asynchronously) for access to the cache entry. In that case, |
|
167 * the nsFtpState's OnCacheEntryAvailable method will be called once the |
|
168 * cache entry is available or if an error occurs. |
|
169 */ |
|
170 bool CheckCache(); |
|
171 |
|
172 /** |
|
173 * This method returns true if the data for this URL can be read from the |
|
174 * cache. This method assumes that mCacheEntry is non-null. |
|
175 */ |
|
176 bool CanReadCacheEntry(); |
|
177 |
|
178 /** |
|
179 * This method causes the cache entry to be read. Data from the cache |
|
180 * entry will be fed to the channel's listener. This method returns true |
|
181 * if successfully reading from the cache. This method assumes that |
|
182 * mCacheEntry is non-null and opened with read access. |
|
183 */ |
|
184 bool ReadCacheEntry(); |
|
185 |
|
186 /** |
|
187 * This method configures mDataStream with an asynchronous input stream to |
|
188 * the cache entry. The cache entry is read on a background thread. This |
|
189 * method assumes that mCacheEntry is non-null and opened with read access. |
|
190 */ |
|
191 nsresult OpenCacheDataStream(); |
|
192 |
|
193 /** |
|
194 * This method inserts the cache entry's output stream into the stream |
|
195 * listener chain for the FTP channel. As a result, the cache entry |
|
196 * receives data as data is pushed to the channel's listener. This method |
|
197 * assumes that mCacheEntry is non-null and opened with write access. |
|
198 */ |
|
199 nsresult InstallCacheListener(); |
|
200 |
|
201 /////////////////////////////////// |
|
202 // Private members |
|
203 |
|
204 // ****** state machine vars |
|
205 FTP_STATE mState; // the current state |
|
206 FTP_STATE mNextState; // the next state |
|
207 bool mKeepRunning; // thread event loop boolean |
|
208 int32_t mResponseCode; // the last command response code |
|
209 nsCString mResponseMsg; // the last command response text |
|
210 |
|
211 // ****** channel/transport/stream vars |
|
212 nsRefPtr<nsFtpControlConnection> mControlConnection; // cacheable control connection (owns mCPipe) |
|
213 bool mReceivedControlData; |
|
214 bool mTryingCachedControl; // retrying the password |
|
215 bool mRETRFailed; // Did we already try a RETR and it failed? |
|
216 uint64_t mFileSize; |
|
217 nsCString mModTime; |
|
218 |
|
219 // ****** consumer vars |
|
220 nsRefPtr<nsFtpChannel> mChannel; // our owning FTP channel we pass through our events |
|
221 nsCOMPtr<nsIProxyInfo> mProxyInfo; |
|
222 |
|
223 // ****** connection cache vars |
|
224 int32_t mServerType; // What kind of server are we talking to |
|
225 |
|
226 // ****** protocol interpretation related state vars |
|
227 nsString mUsername; // username |
|
228 nsString mPassword; // password |
|
229 FTP_ACTION mAction; // the higher level action (GET/PUT) |
|
230 bool mAnonymous; // try connecting anonymous (default) |
|
231 bool mRetryPass; // retrying the password |
|
232 bool mStorReplyReceived; // FALSE if waiting for STOR |
|
233 // completion status from server |
|
234 nsresult mInternalError; // represents internal state errors |
|
235 bool mReconnectAndLoginAgain; |
|
236 bool mCacheConnection; |
|
237 |
|
238 // ****** URI vars |
|
239 int32_t mPort; // the port to connect to |
|
240 nsString mFilename; // url filename (if any) |
|
241 nsCString mPath; // the url's path |
|
242 nsCString mPwd; // login Path |
|
243 |
|
244 // ****** other vars |
|
245 nsCOMPtr<nsITransport> mDataTransport; |
|
246 nsCOMPtr<nsIAsyncInputStream> mDataStream; |
|
247 nsCOMPtr<nsIRequest> mUploadRequest; |
|
248 bool mAddressChecked; |
|
249 bool mServerIsIPv6; |
|
250 bool mUseUTF8; |
|
251 |
|
252 static uint32_t mSessionStartTime; |
|
253 |
|
254 mozilla::net::NetAddr mServerAddress; |
|
255 |
|
256 // ***** control read gvars |
|
257 nsresult mControlStatus; |
|
258 nsCString mControlReadCarryOverBuf; |
|
259 |
|
260 nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry; |
|
261 bool mDoomCache; |
|
262 |
|
263 nsCString mSuppliedEntityID; |
|
264 |
|
265 nsCOMPtr<nsICancelable> mProxyRequest; |
|
266 bool mDeferredCallbackPending; |
|
267 |
|
268 // These members are used for network per-app metering (bug 855948) |
|
269 // Currently, they are only available on gonk. |
|
270 uint64_t mCountRecv; |
|
271 #ifdef MOZ_WIDGET_GONK |
|
272 nsMainThreadPtrHandle<nsINetworkInterface> mActiveNetwork; |
|
273 #endif |
|
274 nsresult SaveNetworkStats(bool); |
|
275 void CountRecvBytes(uint64_t recvBytes) |
|
276 { |
|
277 mCountRecv += recvBytes; |
|
278 SaveNetworkStats(false); |
|
279 } |
|
280 }; |
|
281 |
|
282 #endif //__nsFtpState__h_ |