2 * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 33 Client-side Routines */
11 #ifndef SQUID_SERVERS_FTP_SERVER_H
12 #define SQUID_SERVERS_FTP_SERVER_H
14 #include "base/JobWait.h"
15 #include "base/Lock.h"
16 #include "client_side.h"
17 #include "comm/forward.h"
29 fssHandleUploadRequest
,
38 // TODO: This should become a part of MasterXaction when we start sending
39 // master transactions to the clients/ code.
40 /// Transaction information shared among our FTP client and server jobs.
41 class MasterState
: public RefCountable
44 typedef RefCount
<MasterState
> Pointer
;
46 MasterState(): serverState(fssBegin
), clientReadGreeting(false), userDataDone(0) {}
48 Ip::Address clientDataAddr
; ///< address of our FTP client data connection
49 SBuf workingDir
; ///< estimated current working directory for URI formation
50 ServerState serverState
; ///< what our FTP server is doing
51 bool clientReadGreeting
; ///< whether our FTP client read their FTP server greeting
52 /// Squid will send or has sent this final status code to the FTP client
56 /// Manages a control connection from an FTP client.
57 class Server
: public ConnStateData
62 explicit Server(const MasterXaction::Pointer
&xact
);
63 virtual ~Server() override
;
66 virtual void callException(const std::exception
&e
) override
;
68 /// Called by Ftp::Client class when it is start receiving or
70 void startWaitingForOrigin();
72 /// Called by Ftp::Client class when it is done receiving or
73 /// sending data. Waits for both agents to be done before
74 /// responding to the FTP client and closing the data connection.
75 void stopWaitingForOrigin(int status
);
77 // This is a pointer in hope to minimize future changes when MasterState
78 // becomes a part of MasterXaction. Guaranteed not to be nil.
79 MasterState::Pointer master
; ///< info shared among our FTP client and server jobs
82 friend void StartListening();
84 // errors detected before it is possible to create an HTTP request wrapper
85 enum class EarlyErrorKind
{
95 /* ConnStateData API */
96 virtual Http::Stream
*parseOneRequest() override
;
97 virtual void processParsedRequest(Http::StreamPointer
&context
) override
;
98 virtual void notePeerConnection(Comm::ConnectionPointer conn
) override
;
99 virtual void clientPinnedConnectionClosed(const CommCloseCbParams
&io
) override
;
100 virtual void handleReply(HttpReply
*header
, StoreIOBuffer receivedData
) override
;
101 virtual int pipelinePrefetchMax() const override
;
102 virtual bool writeControlMsgAndCall(HttpReply
*rep
, AsyncCall::Pointer
&call
) override
;
103 virtual time_t idleTimeout() const override
;
106 virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer
) override
;
107 virtual void noteBodyConsumerAborted(BodyPipe::Pointer ptr
) override
;
110 virtual void start() override
;
113 static void AcceptCtrlConnection(const CommAcceptCbParams
¶ms
);
114 void acceptDataConnection(const CommAcceptCbParams
¶ms
);
115 void readUploadData(const CommIoCbParams
&io
);
116 void wroteEarlyReply(const CommIoCbParams
&io
);
117 void wroteReply(const CommIoCbParams
&io
);
118 void wroteReplyData(const CommIoCbParams
&io
);
119 void connectedForData(const CommConnectCbParams
¶ms
);
121 unsigned int listenForDataConnection();
122 bool createDataConnection(Ip::Address cltAddr
);
123 void closeDataConnection();
125 /// Called after data transfer on client-to-squid data connection is
127 void userDataCompletionCheckpoint(int finalStatusCode
);
129 /// Writes the data-transfer status reply to the FTP client and
130 /// closes the data connection.
131 void completeDataDownload();
133 void calcUri(const SBuf
*file
);
134 void changeState(const Ftp::ServerState newState
, const char *reason
);
135 Http::Stream
*handleUserRequest(const SBuf
&cmd
, SBuf
¶ms
);
136 bool checkDataConnPost() const;
137 void replyDataWritingCheckpoint();
138 void maybeReadUploadData();
140 void setReply(const int code
, const char *msg
);
141 void writeCustomReply(const int code
, const char *msg
, const HttpReply
*reply
= nullptr);
142 void writeEarlyReply(const int code
, const char *msg
);
143 void writeErrorReply(const HttpReply
*reply
, const int status
);
144 void writeForwardedForeign(const HttpReply
*reply
);
145 void writeForwardedReply(const HttpReply
*reply
);
146 void writeForwardedReplyAndCall(const HttpReply
*reply
, AsyncCall::Pointer
&call
);
147 void writeReply(MemBuf
&mb
);
149 Http::Stream
*earlyError(const EarlyErrorKind eek
);
150 bool handleRequest(HttpRequest
*);
151 void setDataCommand();
152 bool checkDataConnPre();
154 /// a method handling an FTP command; selected by handleRequest()
155 typedef bool (Ftp::Server::*RequestHandler
)(String
&cmd
, String
¶ms
);
156 bool handleFeatRequest(String
&cmd
, String
¶ms
);
157 bool handlePasvRequest(String
&cmd
, String
¶ms
);
158 bool handlePortRequest(String
&cmd
, String
¶ms
);
159 bool handleDataRequest(String
&cmd
, String
¶ms
);
160 bool handleUploadRequest(String
&cmd
, String
¶ms
);
161 bool handleEprtRequest(String
&cmd
, String
¶ms
);
162 bool handleEpsvRequest(String
&cmd
, String
¶ms
);
163 bool handleCwdRequest(String
&cmd
, String
¶ms
);
164 bool handlePassRequest(String
&cmd
, String
¶ms
);
165 bool handleCdupRequest(String
&cmd
, String
¶ms
);
167 /// a method handling an FTP response; selected by handleReply()
168 typedef void (Ftp::Server::*ReplyHandler
)(const HttpReply
*reply
, StoreIOBuffer data
);
169 void handleFeatReply(const HttpReply
*header
, StoreIOBuffer receivedData
);
170 void handlePasvReply(const HttpReply
*header
, StoreIOBuffer receivedData
);
171 void handlePortReply(const HttpReply
*header
, StoreIOBuffer receivedData
);
172 void handleErrorReply(const HttpReply
*header
, StoreIOBuffer receivedData
);
173 void handleDataReply(const HttpReply
*header
, StoreIOBuffer receivedData
);
174 void handleUploadReply(const HttpReply
*header
, StoreIOBuffer receivedData
);
175 void handleEprtReply(const HttpReply
*header
, StoreIOBuffer receivedData
);
176 void handleEpsvReply(const HttpReply
*header
, StoreIOBuffer receivedData
);
179 void doProcessRequest();
180 void shovelUploadData();
181 void resetLogin(const char *reason
);
183 SBuf uri
; ///< a URI reconstructed from various FTP message details
184 SBuf host
; ///< intended dest. of a transparently intercepted FTP conn
185 bool gotEpsvAll
; ///< restrict data conn setup commands to just EPSV
186 AsyncCall::Pointer onDataAcceptCall
; ///< who to call upon data conn acceptance
187 Comm::ConnectionPointer dataListenConn
; ///< data connection listening socket
188 Comm::ConnectionPointer dataConn
; ///< data connection
189 char uploadBuf
[CLIENT_REQ_BUF_SZ
]; ///< data connection input buffer
190 size_t uploadAvailSize
; ///< number of yet unused uploadBuf bytes
192 AsyncCall::Pointer listener
; ///< set when we are passively listening
194 /// Waits for an FTP data connection to the client to be established/opened.
195 /// This wait only happens in FTP active mode (via PORT or EPRT).
196 JobWait
<Comm::ConnOpener
> dataConnWait
;
198 AsyncCall::Pointer reader
; ///< set when we are reading FTP data
200 /// whether we wait for the origin data transfer to end
201 bool waitingForOrigin
;
202 /// whether the origin data transfer aborted
203 bool originDataDownloadAbortedOnError
;
205 /// a response which writing was postponed until stopWaitingForOrigin()
206 HttpReply::Pointer delayedReply
;
211 #endif /* SQUID_SERVERS_FTP_SERVER_H */