]> git.ipfire.org Git - thirdparty/squid.git/blame_incremental - src/servers/FtpServer.h
Simplify appending SBuf to String (#2108)
[thirdparty/squid.git] / src / servers / FtpServer.h
... / ...
CommitLineData
1/*
2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9/* DEBUG: section 33 Client-side Routines */
10
11#ifndef SQUID_SRC_SERVERS_FTPSERVER_H
12#define SQUID_SRC_SERVERS_FTPSERVER_H
13
14#include "base/JobWait.h"
15#include "base/Lock.h"
16#include "client_side.h"
17#include "comm/forward.h"
18#include "http/forward.h"
19
20namespace Ftp
21{
22
23typedef enum {
24 fssBegin,
25 fssConnected,
26 fssHandleFeat,
27 fssHandlePasv,
28 fssHandlePort,
29 fssHandleDataRequest,
30 fssHandleUploadRequest,
31 fssHandleEprt,
32 fssHandleEpsv,
33 fssHandleCwd,
34 fssHandlePass,
35 fssHandleCdup,
36 fssError
37} ServerState;
38
39// TODO: This should become a part of MasterXaction when we start sending
40// master transactions to the clients/ code.
41/// Transaction information shared among our FTP client and server jobs.
42class MasterState: public RefCountable
43{
44public:
45 typedef RefCount<MasterState> Pointer;
46
47 MasterState(): serverState(fssBegin), clientReadGreeting(false), userDataDone(0) {}
48
49 Ip::Address clientDataAddr; ///< address of our FTP client data connection
50 SBuf workingDir; ///< estimated current working directory for URI formation
51 ServerState serverState; ///< what our FTP server is doing
52 bool clientReadGreeting; ///< whether our FTP client read their FTP server greeting
53 /// Squid will send or has sent this final status code to the FTP client
54 int userDataDone;
55};
56
57/// Manages a control connection from an FTP client.
58class Server: public ConnStateData
59{
60 CBDATA_CHILD(Server);
61
62public:
63 explicit Server(const MasterXaction::Pointer &xact);
64 ~Server() override;
65
66 /* AsyncJob API */
67 void callException(const std::exception &e) override;
68
69 /// Called by Ftp::Client class when it is start receiving or
70 /// sending data.
71 void startWaitingForOrigin();
72
73 /// Called by Ftp::Client class when it is done receiving or
74 /// sending data. Waits for both agents to be done before
75 /// responding to the FTP client and closing the data connection.
76 void stopWaitingForOrigin(int status);
77
78 // This is a pointer in hope to minimize future changes when MasterState
79 // becomes a part of MasterXaction. Guaranteed not to be nil.
80 MasterState::Pointer master; ///< info shared among our FTP client and server jobs
81
82protected:
83 friend void StartListening();
84
85 // errors detected before it is possible to create an HTTP request wrapper
86 enum class EarlyErrorKind {
87 HugeRequest,
88 MissingLogin,
89 MissingUsername,
90 MissingHost,
91 UnsupportedCommand,
92 InvalidUri,
93 MalformedCommand
94 };
95
96 /* ConnStateData API */
97 Http::Stream *parseOneRequest() override;
98 void processParsedRequest(Http::StreamPointer &context) override;
99 void notePeerConnection(Comm::ConnectionPointer conn) override;
100 void clientPinnedConnectionClosed(const CommCloseCbParams &io) override;
101 void handleReply(HttpReply *header, StoreIOBuffer receivedData) override;
102 int pipelinePrefetchMax() const override;
103 bool writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call) override;
104 time_t idleTimeout() const override;
105
106 /* BodyPipe API */
107 void noteMoreBodySpaceAvailable(BodyPipe::Pointer) override;
108 void noteBodyConsumerAborted(BodyPipe::Pointer ptr) override;
109
110 /* AsyncJob API */
111 void start() override;
112
113 /* Comm callbacks */
114 static void AcceptCtrlConnection(const CommAcceptCbParams &params);
115 void acceptDataConnection(const CommAcceptCbParams &params);
116 void readUploadData(const CommIoCbParams &io);
117 void wroteEarlyReply(const CommIoCbParams &io);
118 void wroteReply(const CommIoCbParams &io);
119 void wroteReplyData(const CommIoCbParams &io);
120 void connectedForData(const CommConnectCbParams &params);
121
122 unsigned int listenForDataConnection();
123 bool createDataConnection(Ip::Address cltAddr);
124 void closeDataConnection();
125
126 /// Called after data transfer on client-to-squid data connection is
127 /// finished.
128 void userDataCompletionCheckpoint(int finalStatusCode);
129
130 /// Writes the data-transfer status reply to the FTP client and
131 /// closes the data connection.
132 void completeDataDownload();
133
134 void calcUri(const SBuf *file);
135 void changeState(const Ftp::ServerState newState, const char *reason);
136 Http::Stream *handleUserRequest(const SBuf &cmd, SBuf &params);
137 bool checkDataConnPost() const;
138 void replyDataWritingCheckpoint();
139 void maybeReadUploadData();
140
141 void setReply(const int code, const char *msg);
142 void writeCustomReply(const int code, const char *msg, const HttpReply *reply = nullptr);
143 void writeEarlyReply(const int code, const char *msg);
144 void writeErrorReply(const HttpReply *reply, const int status);
145 void writeForwardedForeign(const HttpReply *reply);
146 void writeForwardedReply(const HttpReply *reply);
147 void writeForwardedReplyAndCall(const HttpReply *reply, AsyncCall::Pointer &call);
148 void writeReply(MemBuf &mb);
149
150 Http::Stream *earlyError(const EarlyErrorKind eek);
151 bool handleRequest(HttpRequest *);
152 void setDataCommand();
153 bool checkDataConnPre();
154
155 /// a method handling an FTP command; selected by handleRequest()
156 typedef bool (Ftp::Server::*RequestHandler)(String &cmd, String &params);
157 bool handleFeatRequest(String &cmd, String &params);
158 bool handlePasvRequest(String &cmd, String &params);
159 bool handlePortRequest(String &cmd, String &params);
160 bool handleDataRequest(String &cmd, String &params);
161 bool handleUploadRequest(String &cmd, String &params);
162 bool handleEprtRequest(String &cmd, String &params);
163 bool handleEpsvRequest(String &cmd, String &params);
164 bool handleCwdRequest(String &cmd, String &params);
165 bool handlePassRequest(String &cmd, String &params);
166 bool handleCdupRequest(String &cmd, String &params);
167
168 /// a method handling an FTP response; selected by handleReply()
169 typedef void (Ftp::Server::*ReplyHandler)(const HttpReply *reply, StoreIOBuffer data);
170 void handleFeatReply(const HttpReply *header, StoreIOBuffer receivedData);
171 void handlePasvReply(const HttpReply *header, StoreIOBuffer receivedData);
172 void handlePortReply(const HttpReply *header, StoreIOBuffer receivedData);
173 void handleErrorReply(const HttpReply *header, StoreIOBuffer receivedData);
174 void handleDataReply(const HttpReply *header, StoreIOBuffer receivedData);
175 void handleUploadReply(const HttpReply *header, StoreIOBuffer receivedData);
176 void handleEprtReply(const HttpReply *header, StoreIOBuffer receivedData);
177 void handleEpsvReply(const HttpReply *header, StoreIOBuffer receivedData);
178
179private:
180 void doProcessRequest();
181 void shovelUploadData();
182 void resetLogin(const char *reason);
183
184 SBuf uri; ///< a URI reconstructed from various FTP message details
185 SBuf host; ///< intended dest. of a transparently intercepted FTP conn
186 bool gotEpsvAll; ///< restrict data conn setup commands to just EPSV
187 AsyncCall::Pointer onDataAcceptCall; ///< who to call upon data conn acceptance
188 Comm::ConnectionPointer dataListenConn; ///< data connection listening socket
189 Comm::ConnectionPointer dataConn; ///< data connection
190 char uploadBuf[CLIENT_REQ_BUF_SZ]; ///< data connection input buffer
191 size_t uploadAvailSize; ///< number of yet unused uploadBuf bytes
192
193 AsyncCall::Pointer listener; ///< set when we are passively listening
194
195 /// Waits for an FTP data connection to the client to be established/opened.
196 /// This wait only happens in FTP active mode (via PORT or EPRT).
197 JobWait<Comm::ConnOpener> dataConnWait;
198
199 AsyncCall::Pointer reader; ///< set when we are reading FTP data
200
201 /// whether we wait for the origin data transfer to end
202 bool waitingForOrigin;
203 /// whether the origin data transfer aborted
204 bool originDataDownloadAbortedOnError;
205
206 /// a response which writing was postponed until stopWaitingForOrigin()
207 HttpReply::Pointer delayedReply;
208};
209
210} // namespace Ftp
211
212#endif /* SQUID_SRC_SERVERS_FTPSERVER_H */
213