1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * Bradley Baetz <bbaetz@student.usyd.edu.au>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #ifndef __nsFtpState__h_
40 #define __nsFtpState__h_
43 #include "nsFTPChannel.h"
44 #include "nsBaseContentStream.h"
47 #include "nsIThread.h"
48 #include "nsIRunnable.h"
49 #include "nsISocketTransportService.h"
50 #include "nsISocketTransport.h"
51 #include "nsIServiceManager.h"
52 #include "nsIStreamListener.h"
53 #include "nsICacheListener.h"
57 #include "nsIFTPChannel.h"
58 #include "nsIProtocolHandler.h"
60 #include "nsIAsyncInputStream.h"
61 #include "nsIOutputStream.h"
62 #include "nsAutoLock.h"
63 #include "nsAutoPtr.h"
64 #include "nsIPrompt.h"
65 #include "nsITransport.h"
66 #include "nsIProxyInfo.h"
68 #include "nsFtpControlConnection.h"
70 #include "nsICacheEntryDescriptor.h"
71 #include "nsICacheListener.h"
74 #define FTP_GENERIC_TYPE 0
75 #define FTP_UNIX_TYPE 1
76 #define FTP_VMS_TYPE 8
78 #define FTP_OS2_TYPE 11
81 typedef enum _FTP_STATE
{
82 ///////////////////////
92 ///////////////////////
93 //// Command channel connection setup states
94 FTP_S_USER
, FTP_R_USER
,
95 FTP_S_PASS
, FTP_R_PASS
,
96 FTP_S_SYST
, FTP_R_SYST
,
97 FTP_S_ACCT
, FTP_R_ACCT
,
98 FTP_S_TYPE
, FTP_R_TYPE
,
100 FTP_S_SIZE
, FTP_R_SIZE
,
101 FTP_S_MDTM
, FTP_R_MDTM
,
102 FTP_S_REST
, FTP_R_REST
,
103 FTP_S_RETR
, FTP_R_RETR
,
104 FTP_S_STOR
, FTP_R_STOR
,
105 FTP_S_LIST
, FTP_R_LIST
,
106 FTP_S_PASV
, FTP_R_PASV
,
110 // higher level ftp actions
111 typedef enum _FTP_ACTION
{GET
, PUT
} FTP_ACTION
;
115 // The nsFtpState object is the content stream for the channel. It implements
116 // nsIInputStreamCallback, so it can read data from the control connection. It
117 // implements nsITransportEventSink so it can mix status events from both the
118 // control connection and the data connection.
120 class nsFtpState
: public nsBaseContentStream
,
121 public nsIInputStreamCallback
,
122 public nsITransportEventSink
,
123 public nsICacheListener
,
124 public nsIRequestObserver
,
125 public nsFtpControlConnectionListener
{
127 NS_DECL_ISUPPORTS_INHERITED
128 NS_DECL_NSIINPUTSTREAMCALLBACK
129 NS_DECL_NSITRANSPORTEVENTSINK
130 NS_DECL_NSICACHELISTENER
131 NS_DECL_NSIREQUESTOBSERVER
133 // Override input stream methods:
134 NS_IMETHOD
CloseWithStatus(nsresult status
);
135 NS_IMETHOD
Available(PRUint32
*result
);
136 NS_IMETHOD
ReadSegments(nsWriteSegmentFun fun
, void *closure
,
137 PRUint32 count
, PRUint32
*result
);
139 // nsFtpControlConnectionListener methods:
140 virtual void OnControlDataAvailable(const char *data
, PRUint32 dataLen
);
141 virtual void OnControlError(nsresult status
);
144 nsresult
Init(nsFtpChannel
*channel
);
147 // Notification from nsBaseContentStream::AsyncWait
148 virtual void OnCallbackPending();
151 virtual ~nsFtpState();
153 ///////////////////////////////////
154 // BEGIN: STATE METHODS
155 nsresult
S_user(); FTP_STATE
R_user();
156 nsresult
S_pass(); FTP_STATE
R_pass();
157 nsresult
S_syst(); FTP_STATE
R_syst();
158 nsresult
S_acct(); FTP_STATE
R_acct();
160 nsresult
S_type(); FTP_STATE
R_type();
161 nsresult
S_cwd(); FTP_STATE
R_cwd();
163 nsresult
S_size(); FTP_STATE
R_size();
164 nsresult
S_mdtm(); FTP_STATE
R_mdtm();
165 nsresult
S_list(); FTP_STATE
R_list();
167 nsresult
S_rest(); FTP_STATE
R_rest();
168 nsresult
S_retr(); FTP_STATE
R_retr();
169 nsresult
S_stor(); FTP_STATE
R_stor();
170 nsresult
S_pasv(); FTP_STATE
R_pasv();
171 nsresult
S_pwd(); FTP_STATE
R_pwd();
172 // END: STATE METHODS
173 ///////////////////////////////////
176 void MoveToNextState(FTP_STATE nextState
);
179 void KillControlConnection();
180 nsresult
StopProcessing();
181 nsresult
EstablishControlConnection();
182 nsresult
SendFTPCommand(const nsCSubstring
& command
);
183 void ConvertFilespecToVMS(nsCString
& fileSpec
);
184 void ConvertDirspecToVMS(nsCString
& fileSpec
);
185 void ConvertDirspecFromVMS(nsCString
& fileSpec
);
186 nsresult
BuildStreamConverter(nsIStreamListener
** convertStreamListener
);
187 nsresult
SetContentType();
188 nsresult
ConvertUTF8PathToCharset(const nsACString
&aCharset
);
191 * This method is called to kick-off the FTP state machine. mState is
192 * reset to FTP_COMMAND_CONNECT, and the FTP state machine progresses from
193 * there. This method is initially called (indirectly) from the channel's
194 * AsyncOpen implementation.
199 * This method opens a cache entry for reading or writing depending on the
200 * state of the channel and of the system (e.g., opened for reading if we
201 * are offline). This method is responsible for setting mCacheEntry if
202 * there is a cache entry that can be used. It returns true if it ends up
203 * waiting (asynchronously) for access to the cache entry. In that case,
204 * the nsFtpState's OnCacheEntryAvailable method will be called once the
205 * cache entry is available or if an error occurs.
210 * This method returns true if the data for this URL can be read from the
211 * cache. This method assumes that mCacheEntry is non-null.
213 PRBool
CanReadCacheEntry();
216 * This method causes the cache entry to be read. Data from the cache
217 * entry will be fed to the channel's listener. This method returns true
218 * if successfully reading from the cache. This method assumes that
219 * mCacheEntry is non-null and opened with read access.
221 PRBool
ReadCacheEntry();
224 * This method configures mDataStream with an asynchronous input stream to
225 * the cache entry. The cache entry is read on a background thread. This
226 * method assumes that mCacheEntry is non-null and opened with read access.
228 nsresult
OpenCacheDataStream();
231 * This method inserts the cache entry's output stream into the stream
232 * listener chain for the FTP channel. As a result, the cache entry
233 * receives data as data is pushed to the channel's listener. This method
234 * assumes that mCacheEntry is non-null and opened with write access.
236 nsresult
InstallCacheListener();
238 ///////////////////////////////////
241 // ****** state machine vars
242 FTP_STATE mState
; // the current state
243 FTP_STATE mNextState
; // the next state
244 PRPackedBool mKeepRunning
; // thread event loop boolean
245 PRInt32 mResponseCode
; // the last command response code
246 nsCString mResponseMsg
; // the last command response text
248 // ****** channel/transport/stream vars
249 nsRefPtr
<nsFtpControlConnection
> mControlConnection
; // cacheable control connection (owns mCPipe)
250 PRPackedBool mReceivedControlData
;
251 PRPackedBool mTryingCachedControl
; // retrying the password
252 PRPackedBool mRETRFailed
; // Did we already try a RETR and it failed?
256 // ****** consumer vars
257 nsRefPtr
<nsFtpChannel
> mChannel
; // our owning FTP channel we pass through our events
258 nsCOMPtr
<nsIProxyInfo
> mProxyInfo
;
260 // ****** connection cache vars
261 PRInt32 mServerType
; // What kind of server are we talking to
263 // ****** protocol interpretation related state vars
264 nsString mUsername
; // username
265 nsString mPassword
; // password
266 FTP_ACTION mAction
; // the higher level action (GET/PUT)
267 PRPackedBool mAnonymous
; // try connecting anonymous (default)
268 PRPackedBool mRetryPass
; // retrying the password
269 PRPackedBool mStorReplyReceived
; // FALSE if waiting for STOR
270 // completion status from server
271 nsresult mInternalError
; // represents internal state errors
274 PRInt32 mPort
; // the port to connect to
275 nsString mFilename
; // url filename (if any)
276 nsCString mPath
; // the url's path
277 nsCString mPwd
; // login Path
280 nsCOMPtr
<nsITransport
> mDataTransport
;
281 nsCOMPtr
<nsIAsyncInputStream
> mDataStream
;
282 nsCOMPtr
<nsIRequest
> mUploadRequest
;
283 PRPackedBool mAddressChecked
;
284 PRPackedBool mServerIsIPv6
;
286 static PRUint32 mSessionStartTime
;
288 char mServerAddress
[64];
290 // ***** control read gvars
291 nsresult mControlStatus
;
292 nsCString mControlReadCarryOverBuf
;
294 nsCOMPtr
<nsICacheEntryDescriptor
> mCacheEntry
;
295 PRPackedBool mDoomCache
;
297 nsCString mSuppliedEntityID
;
300 #endif //__nsFtpState__h_