2 * Copyright (C) 1996-2025 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 09 File Transfer Protocol (FTP) */
11 #ifndef SQUID_SRC_CLIENTS_FTPCLIENT_H
12 #define SQUID_SRC_CLIENTS_FTPCLIENT_H
14 #include "clients/Client.h"
15 #include "error/Detail.h"
21 extern const char *const crlf
;
23 /// Holds FTP server reply error code
24 /// Squid needs to interpret internally FTP reply codes and respond with
25 /// custom error (eg in the case of Ftp::Gateway), however still we need
26 /// to log the exact FTP server error reply code as the reason of error.
27 class ErrorDetail
: public ::ErrorDetail
{
28 MEMPROXY_CLASS(Ftp::ErrorDetail
);
31 explicit ErrorDetail(const int code
): completionCode(code
) {}
34 SBuf
brief() const override
;
35 SBuf
verbose(const HttpRequestPointer
&) const override
;
38 int completionCode
; ///< FTP reply completion code
41 /// Common code for FTP server control and data channels.
42 /// Does not own the channel descriptor, which is managed by Ftp::Client.
46 /// called after the socket is opened, sets up close handler
47 void opened(const Comm::ConnectionPointer
&conn
, const AsyncCall::Pointer
&aCloser
);
49 /** Handles all operations needed to properly close the active channel FD.
50 * clearing the close handler, clearing the listen socket properly, and calling comm_close
54 void forget(); /// remove the close handler, leave connection open
56 void clear(); ///< just drops conn and close handler. does not close active connections.
58 Comm::ConnectionPointer conn
; ///< channel descriptor
60 /** A temporary handle to the connection being listened on.
61 * Closing this will also close the waiting Data channel acceptor.
62 * If a data connection has already been accepted but is still waiting in the event queue
63 * the callback will still happen and needs to be handled (usually dropped).
65 Comm::ConnectionPointer listenConn
;
68 AsyncCall::Pointer closer
; ///< Comm close handler callback
71 /// FTP channel for control commands.
72 /// This channel is opened once per transaction.
73 class CtrlChannel
: public Ftp::Channel
88 CtrlChannel(const CtrlChannel
&); // not implemented
89 CtrlChannel
&operator =(const CtrlChannel
&); // not implemented
92 /// FTP channel for data exchanges.
93 /// This channel may be opened/closed a few times.
94 class DataChannel
: public Ftp::Channel
100 void addr(const Ip::Address
&addr
); ///< import host and port
109 /// FTP client functionality shared among FTP Gateway and Relay clients.
110 class Client
: public ::Client
112 CBDATA_INTERMEDIATE();
115 explicit Client(FwdState
*fwdState
);
118 /// handle a fatal transaction error, closing the control connection
119 virtual void failed(err_type error
= ERR_NONE
, int xerrno
= 0,
120 ErrorState
*ftperr
= nullptr);
122 /// read timeout handler
123 virtual void timeout(const CommTimeoutCbParams
&io
);
126 void maybeReadVirginBody() override
;
128 void writeCommand(const char *buf
);
130 /// extracts remoteAddr from PASV response, validates it,
131 /// sets data address details, and returns true on success
132 bool handlePasvReply(Ip::Address
&remoteAddr
);
133 bool handleEpsvReply(Ip::Address
&remoteAddr
);
138 void connectDataChannel();
139 bool openListenSocket();
140 void switchTimeoutToDataChannel();
142 CtrlChannel ctrl
; ///< FTP control channel state
143 DataChannel data
; ///< FTP data channel state
171 SENT_DATA_REQUEST
, // LIST, NLST or RETR requests..
172 SENT_COMMAND
, // General command
182 void start() override
;
185 void closeServer() override
;
186 bool doneWithServer() const override
;
187 const Comm::ConnectionPointer
& dataConnection() const override
;
188 void abortAll(const char *reason
) override
;
189 void noteDelayAwareReadChance() override
;
191 virtual Http::StatusCode
failedHttpStatus(err_type
&error
);
192 void ctrlClosed(const CommCloseCbParams
&io
);
193 void scheduleReadControlReply(int buffered_ok
);
194 void readControlReply(const CommIoCbParams
&io
);
195 virtual void handleControlReply();
196 void writeCommandCallback(const CommIoCbParams
&io
);
197 virtual void dataChannelConnected(const CommConnectCbParams
&io
) = 0;
198 void dataRead(const CommIoCbParams
&io
);
200 AsyncCall::Pointer
dataCloser();
201 virtual void dataClosed(const CommCloseCbParams
&io
);
204 // sending of the request body to the server
205 void sentRequestBody(const CommIoCbParams
&io
) override
;
206 void doneSendingRequestBody() override
;
208 /// Waits for an FTP data connection to the server to be established/opened.
209 /// This wait only happens in FTP passive mode (via PASV or EPSV).
210 JobWait
<Comm::ConnOpener
> dataConnWait
;
213 bool parseControlReply(size_t &bytesUsed
);
215 /// XXX: An old hack for FTP servers like ftp.netscape.com that may not
216 /// respond to PASV. Use faster connect timeout instead of read timeout.
217 bool shortenReadTimeout
;
222 #endif /* SQUID_SRC_CLIENTS_FTPCLIENT_H */