pinned_connection->stopPinnedConnectionMonitoring();
flags.connected_okay = true;
++n_tries;
- request->hier.note(serverConn, request->GetHost());
request->flags.pinned = true;
request->hier.note(serverConn, pinned_connection->pinning.host);
if (pinned_connection->pinnedAuth())
HttpHeaderPos pos = HttpHeaderInitPos;
const HttpHeaderEntry *e;
assert(p);
- debugs(55, 7, "packing hdr: (" << this << ")");
+ debugs(55, 7, this << " into " << p <<
+ (mask_sensitive_info ? " while masking" : ""));
/* pack all entries one by one */
while ((e = getEntry(&pos))) {
if (!mask_sensitive_info) {
e->packInto(p);
continue;
}
- // TODO: When native FTP commands may end up in error pages and other
- // sensitive places, hide HDR_FTP_ARGUMENTS for the FTP PASS command.
+
+ bool maskThisEntry = false;
switch (e->id) {
case HDR_AUTHORIZATION:
case HDR_PROXY_AUTHORIZATION:
- packerAppend(p, e->name.rawBuf(), e->name.size());
- packerAppend(p, ": ** NOT DISPLAYED **\r\n", 23);
+ maskThisEntry = true;
break;
+
+ case HDR_FTP_ARGUMENTS:
+ if (const HttpHeaderEntry *cmd = findEntry(HDR_FTP_COMMAND))
+ maskThisEntry = (cmd->value == "PASS");
+ break;
+
default:
- e->packInto(p);
break;
}
+ if (maskThisEntry) {
+ packerAppend(p, e->name.rawBuf(), e->name.size());
+ packerAppend(p, ": ** NOT DISPLAYED **\r\n", 23);
+ } else {
+ e->packInto(p);
+ }
+
}
/* Pack in the "special" entries */
{
assert(raw);
+ // TODO: Optimize by appending a sequence of characters instead of a char.
+ // This optimization may be easier with Tokenizer after raw becomes SBuf.
+
// RFC 7230 says a "sender SHOULD NOT generate a quoted-pair in a
// quoted-string except where necessary" (i.e., DQUOTE and backslash)
bool needInnerQuote = false;
/// parses the protocol= option of the *_port directive, returning parsed value
/// unsupported option values result in a fatal error message
+/// upper case values required; caller may convert for backward compatibility
static AnyP::ProtocolVersion
-parsePortProtocol(const char *value)
+parsePortProtocol(const SBuf &value)
{
// HTTP/1.0 not supported because we are version 1.1 which contains a superset of 1.0
// and RFC 2616 requires us to upgrade 1.0 to 1.1
- if (strcasecmp("http", value) == 0 || strcmp("HTTP/1.1", value) == 0)
+ if (value.cmp("HTTP") == 0 || value.cmp("HTTP/1.1") == 0)
return AnyP::ProtocolVersion(AnyP::PROTO_HTTP, 1,1);
- if (strcasecmp("https", value) == 0 || strcmp("HTTPS/1.1", value) == 0)
+ if (value.cmp("HTTPS") == 0 || value.cmp("HTTPS/1.1") == 0)
return AnyP::ProtocolVersion(AnyP::PROTO_HTTPS, 1,1);
- if (strcasecmp("ftp", value) == 0)
+ if (value.cmp("FTP") == 0)
return AnyP::ProtocolVersion(AnyP::PROTO_FTP,
- Ftp::ProtocolVersion().major, Ftp::ProtocolVersion().minor);
+ Ftp::ProtocolVersion().major, Ftp::ProtocolVersion().minor);
- fatalf("%s directive does not support protocol=%s\n", cfg_directive, value);
+ fatalf("%s directive does not support protocol=" SQUIDSBUFPH "\n", cfg_directive, SQUIDSBUFPRINT(value));
return AnyP::ProtocolVersion(); // not reached
}
if (strcmp(token, "accel") == 0) {
if (s->flags.isIntercepted()) {
- debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: Accelerator mode requires its own port. It cannot be shared with other modes.");
+ debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": Accelerator mode requires its own port. It cannot be shared with other modes.");
self_destruct();
}
s->flags.accelSurrogate = true;
s->vhost = true;
} else if (strcmp(token, "transparent") == 0 || strcmp(token, "intercept") == 0) {
if (s->flags.accelSurrogate || s->flags.tproxyIntercept) {
- debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: Intercept mode requires its own interception port. It cannot be shared with other modes.");
+ debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": Intercept mode requires its own interception port. It cannot be shared with other modes.");
self_destruct();
}
s->flags.natIntercept = true;
debugs(3, DBG_IMPORTANT, "Disabling Authentication on port " << s->s << " (interception enabled)");
} else if (strcmp(token, "tproxy") == 0) {
if (s->flags.natIntercept || s->flags.accelSurrogate) {
- debugs(3,DBG_CRITICAL, "FATAL: http(s)_port: TPROXY option requires its own interception port. It cannot be shared with other modes.");
+ debugs(3,DBG_CRITICAL, "FATAL: " << cfg_directive << ": TPROXY option requires its own interception port. It cannot be shared with other modes.");
self_destruct();
}
s->flags.tproxyIntercept = true;
debugs(3, DBG_IMPORTANT, "Disabling Authentication on port " << s->s << " (TPROXY enabled)");
if (!Ip::Interceptor.ProbeForTproxy(s->s)) {
- debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: TPROXY support in the system does not work.");
+ debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": TPROXY support in the system does not work.");
self_destruct();
}
} else if (strncmp(token, "defaultsite=", 12) == 0) {
if (!s->flags.accelSurrogate) {
- debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: defaultsite option requires Acceleration mode flag.");
+ debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": defaultsite option requires Acceleration mode flag.");
self_destruct();
}
safe_free(s->defaultsite);
s->defaultsite = xstrdup(token + 12);
} else if (strcmp(token, "vhost") == 0) {
if (!s->flags.accelSurrogate) {
- debugs(3, DBG_CRITICAL, "WARNING: http(s)_port: vhost option is deprecated. Use 'accel' mode flag instead.");
+ debugs(3, DBG_CRITICAL, "WARNING: " << cfg_directive << ": vhost option is deprecated. Use 'accel' mode flag instead.");
}
s->flags.accelSurrogate = true;
s->vhost = true;
} else if (strcmp(token, "no-vhost") == 0) {
if (!s->flags.accelSurrogate) {
- debugs(3, DBG_IMPORTANT, "ERROR: http(s)_port: no-vhost option requires Acceleration mode flag.");
+ debugs(3, DBG_IMPORTANT, "ERROR: " << cfg_directive << ": no-vhost option requires Acceleration mode flag.");
}
s->vhost = false;
} else if (strcmp(token, "vport") == 0) {
if (!s->flags.accelSurrogate) {
- debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: vport option requires Acceleration mode flag.");
+ debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": vport option requires Acceleration mode flag.");
self_destruct();
}
s->vport = -1;
} else if (strncmp(token, "vport=", 6) == 0) {
if (!s->flags.accelSurrogate) {
- debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: vport option requires Acceleration mode flag.");
+ debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": vport option requires Acceleration mode flag.");
self_destruct();
}
s->vport = xatos(token + 6);
} else if (strncmp(token, "protocol=", 9) == 0) {
if (!s->flags.accelSurrogate) {
- debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: protocol option requires Acceleration mode flag.");
+ debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": protocol option requires Acceleration mode flag.");
self_destruct();
}
- s->transport = parsePortProtocol(token + 9);
+ s->transport = parsePortProtocol(ToUpper(SBuf(token + 9)));
} else if (strcmp(token, "allow-direct") == 0) {
if (!s->flags.accelSurrogate) {
- debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: allow-direct option requires Acceleration mode flag.");
+ debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": allow-direct option requires Acceleration mode flag.");
self_destruct();
}
s->allow_direct = true;
} else if (strcmp(token, "act-as-origin") == 0) {
if (!s->flags.accelSurrogate) {
- debugs(3, DBG_IMPORTANT, "ERROR: http(s)_port: act-as-origin option requires Acceleration mode flag.");
+ debugs(3, DBG_IMPORTANT, "ERROR: " << cfg_directive << ": act-as-origin option requires Acceleration mode flag.");
} else
s->actAsOrigin = true;
} else if (strcmp(token, "ignore-cc") == 0) {
#if !USE_HTTP_VIOLATIONS
if (!s->flags.accelSurrogate) {
- debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: ignore-cc option requires Acceleration mode flag.");
+ debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": ignore-cc option requires Acceleration mode flag.");
self_destruct();
}
#endif
self_destruct();
} else if (strcmp(token, "ipv4") == 0) {
if ( !s->s.setIPv4() ) {
- debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: IPv6 addresses cannot be used as IPv4-Only. " << s->s );
+ debugs(3, DBG_CRITICAL, "FATAL: " << cfg_directive << ": IPv6 addresses cannot be used as IPv4-Only. " << s->s );
self_destruct();
}
} else if (strcmp(token, "tcpkeepalive") == 0) {
#if USE_OPENSSL
} else if (strcmp(token, "sslBump") == 0) {
debugs(3, DBG_CRITICAL, "WARNING: '" << token << "' is deprecated " <<
- "in http_port. Use 'ssl-bump' instead.");
+ "in " << cfg_directive << ". Use 'ssl-bump' instead.");
s->flags.tunnelSslBumping = true;
} else if (strcmp(token, "ssl-bump") == 0) {
s->flags.tunnelSslBumping = true;
} else if (strncmp(token, "dynamic_cert_mem_cache_size=", 28) == 0) {
parseBytesOptionValue(&s->dynamicCertMemCacheSize, B_BYTES_STR, token + 28);
#endif
- } else if (strcmp(token, "ftp-track-dirs=on") == 0) {
+ } else if (strcmp(token, "ftp-track-dirs") == 0) {
s->ftp_track_dirs = true;
- } else if (strcmp(token, "ftp-track-dirs=off") == 0) {
- s->ftp_track_dirs = false;
} else {
- debugs(3, DBG_CRITICAL, "FATAL: Unknown http(s)_port option '" << token << "'.");
+ debugs(3, DBG_CRITICAL, "FATAL: Unknown " << cfg_directive << " option '" << token << "'.");
self_destruct();
}
}
add_http_port(char *portspec)
{
AnyP::PortCfgPointer s = new AnyP::PortCfg();
- s->transport = parsePortProtocol("HTTP");
+ s->transport = parsePortProtocol(SBuf("HTTP"));
parsePortSpecification(s, portspec);
// we may need to merge better if the above returns a list with clones
assert(s->next == NULL);
static void
parsePortCfg(AnyP::PortCfgPointer *head, const char *optionName)
{
- const char *protocol = NULL;
+ SBuf protoName;
if (strcmp(optionName, "http_port") == 0 ||
strcmp(optionName, "ascii_port") == 0)
- protocol = "http";
+ protoName = "HTTP";
else if (strcmp(optionName, "https_port") == 0)
- protocol = "https";
+ protoName = "HTTPS";
else if (strcmp(optionName, "ftp_port") == 0)
- protocol = "ftp";
- if (!protocol) {
+ protoName = "FTP";
+ if (protoName.isEmpty()) {
self_destruct();
return;
}
}
AnyP::PortCfgPointer s = new AnyP::PortCfg();
- s->transport = parsePortProtocol(protocol); // default; protocol=... overwrites
+ s->transport = parsePortProtocol(protoName); // default; protocol=... overwrites
parsePortSpecification(s, token);
/* parse options ... */
debugs(3, DBG_CRITICAL, "FATAL: tproxy/intercept on https_port requires ssl-bump which is missing.");
self_destruct();
}
- } else if (strcmp(protocol, "ftp") == 0) {
+ } else if (protoName.cmp("FTP") == 0) {
/* ftp_port does not support ssl-bump */
if (s->flags.tunnelSslBumping) {
debugs(3, DBG_CRITICAL, "FATAL: ssl-bump is not supported for ftp_port.");
acl aclname localport 3128 ... # TCP port the client connected to [fast]
# NP: for interception mode this is usually '80'
- acl aclname myportname 3128 ... # http(s)_port name [fast]
+ acl aclname myportname 3128 ... # *_port name [fast]
acl aclname proto HTTP FTP ... # request protocol [fast]
Modes:
- intercept Same as http_port intercept. The FTP origin address is
+ intercept Same as http_port intercept. The FTP origin address is
determined based on the intended destination of the
intercepted connection.
+ tproxy Support Linux TPROXY for spoofing outgoing
+ connections using the client IP address.
+ NP: disables authentication and maybe IPv6 on the port.
+
By default (i.e., without an explicit mode option), Squid extracts the
FTP origin address from the login@origin parameter of the FTP USER
command. Many popular FTP clients support such native FTP proxying.
Options:
- ftp-track-dirs=on|off
+ name=token Specifies an internal name for the port. Defaults to
+ the port address. Usable with myportname ACL.
+
+ ftp-track-dirs=on|off
Enables tracking of FTP directories by injecting extra
PWD commands and adjusting Request-URI (in wrapping
HTTP requests) to reflect the current FTP server
directory. Disabled by default.
+ protocol=FTP Protocol to reconstruct accelerated and intercepted
+ requests with. Defaults to FTP. No other accepted
+ values have been tested with. An unsupported value
+ results in a FATAL error. Accepted values are FTP,
+ HTTP (or HTTP/1.1), and HTTPS (or HTTPS/1.1).
+
Other http_port modes and options that are not specific to HTTP and
HTTPS may also work.
DOC_END
#ifndef SQUID_CLIENTSTREAM_FORWARD_H
#define SQUID_CLIENTSTREAM_FORWARD_H
-#include "enums.h"
+#include "enums.h" /* for clientStream_status_t */
class Lock;
template <class C> class RefCount;
-/// \ingroup ClientStreamAPI
typedef RefCount<Lock> ClientStreamData;
/* Callbacks for ClientStreams API */
class HttpReply;
class StoreIOBuffer;
-/* client stream read callback */
-/// \ingroup ClientStreamAPI
+/// client stream read callback
typedef void CSCB(clientStreamNode *, ClientHttpRequest *, HttpReply *, StoreIOBuffer);
-/* client stream read */
-/// \ingroup ClientStreamAPI
+/// client stream read
typedef void CSR(clientStreamNode *, ClientHttpRequest *);
-/* client stream detach */
-/// \ingroup ClientStreamAPI
+/// client stream detach
typedef void CSD(clientStreamNode *, ClientHttpRequest *);
-/// \ingroup ClientStreamAPI
typedef clientStream_status_t CSS(clientStreamNode *, ClientHttpRequest *);
#endif /* SQUID_CLIENTSTREAM_FORWARD_H */
AnyP::UriScheme(conn->port->transport.protocol).c_str(), conn->port->defaultsite, vportStr, url);
debugs(33, 5, "ACCEL DEFAULTSITE REWRITE: '" << http->uri <<"'");
} else if (vport > 0 /* && (!vhost || no Host:) */) {
- debugs(33, 5, "ACCEL VPORT REWRITE: http_port IP + vport=" << vport);
+ debugs(33, 5, "ACCEL VPORT REWRITE: *_port IP + vport=" << vport);
/* Put the local socket IP address as the hostname, with whatever vport we found */
int url_sz = strlen(url) + 32 + Config.appendDomainLen;
http->uri = (char *)xcalloc(url_sz, 1);
/* RFC 2616 section 10.5.6 : handle unsupported HTTP major versions cleanly. */
/* We currently only support 0.9, 1.0, 1.1 properly */
+ /* TODO: move HTTP-specific processing into servers/HttpServer and such */
if ( (http_ver.major == 0 && http_ver.minor != 9) ||
(http_ver.major > 1) ) {
bool switchedToHttps() const { return false; }
#endif
- void finishDechunkingRequest(bool withSuccess);
-
/* clt_conn_tag=tag annotation access */
const SBuf &connectionTag() const { return connectionTag_; }
void connectionTag(const char *aTag) { connectionTag_ = aTag; }
protected:
void startDechunkingRequest();
+ void finishDechunkingRequest(bool withSuccess);
void abortChunkedRequestBody(const err_type error);
err_type handleChunkedRequestBody(size_t &putSize);
/// timeout to use when waiting for the next request
virtual time_t idleTimeout() const = 0;
-protected:
+ BodyPipe::Pointer bodyPipe; ///< set when we are reading request body
+
+private:
int connFinishedWithConn(int size);
void clientAfterReadingRequests();
bool concurrentRequestQueueFilled() const;
const char *stoppedReceiving_;
AsyncCall::Pointer reader; ///< set when we are reading
- BodyPipe::Pointer bodyPipe; // set when we are reading request body
SBuf connectionTag_; ///< clt_conn_tag=Tag annotation for client connection
};
*/
#include "squid.h"
-
#include "acl/FilledChecklist.h"
#include "client_side.h"
#include "clients/FtpClient.h"
#include "StatCounters.h"
#include "tools.h"
#include "wordlist.h"
+
#include <set>
namespace Ftp
const char *const crlf = "\r\n";
-/// \ingroup ServerProtocolFTPInternal
static char *
escapeIAC(const char *buf)
{
namespace Ftp
{
-/**
- \defgroup ServerProtocolFTPInternal Server-Side FTP Internals
- \ingroup ServerProtocolFTPAPI
- */
-
-/// \ingroup ServerProtocolFTPInternal
struct GatewayFlags {
/* passive mode */
};
class Gateway;
-
-/// \ingroup ServerProtocolFTPInternal
typedef void (StateMethod)(Ftp::Gateway *);
-/// \ingroup ServerProtocolFTPInternal
/// FTP Gateway: An FTP client that takes an HTTP request with an ftp:// URI,
/// converts it into one or more FTP commands, and then
/// converts one or more FTP responses into the final HTTP response.
CBDATA_NAMESPACED_CLASS_INIT(Ftp, Gateway);
-/// \ingroup ServerProtocolFTPInternal
typedef struct {
char type;
int64_t size;
char *link;
} ftpListParts;
-/// \ingroup ServerProtocolFTPInternal
#define FTP_LOGIN_ESCAPED 1
-/// \ingroup ServerProtocolFTPInternal
#define FTP_LOGIN_NOT_ESCAPED 0
#define CTRL_BUFLEN 1024
-/// \ingroup ServerProtocolFTPInternal
static char cbuf[CTRL_BUFLEN];
/*
Quit -
************************************************/
-/// \ingroup ServerProtocolFTPInternal
FTPSM *FTP_SM_FUNCS[] = {
ftpReadWelcome, /* BEGIN */
ftpReadUser, /* SENT_USER */
Ftp::Client::timeout(io);
}
-/// \ingroup ServerProtocolFTPInternal
static const char *Month[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
-/// \ingroup ServerProtocolFTPInternal
static int
is_month(const char *buf)
{
return 0;
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpListPartsFree(ftpListParts ** parts)
{
safe_free(*parts);
}
-/// \ingroup ServerProtocolFTPInternal
#define MAX_TOKENS 64
-/// \ingroup ServerProtocolFTPInternal
static ftpListParts *
ftpListParseParts(const char *buf, struct Ftp::GatewayFlags flags)
{
/* ====================================================================== */
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadWelcome(Ftp::Gateway * ftpState)
{
return realm;
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendUser(Ftp::Gateway * ftpState)
{
ftpState->state = Ftp::Client::SENT_USER;
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadUser(Ftp::Gateway * ftpState)
{
}
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendPass(Ftp::Gateway * ftpState)
{
ftpState->state = Ftp::Client::SENT_PASS;
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadPass(Ftp::Gateway * ftpState)
{
}
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendType(Ftp::Gateway * ftpState)
{
ftpState->state = Ftp::Client::SENT_TYPE;
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadType(Ftp::Gateway * ftpState)
{
}
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpTraverseDirectory(Ftp::Gateway * ftpState)
{
}
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendCwd(Ftp::Gateway * ftpState)
{
ftpState->state = Ftp::Client::SENT_CWD;
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadCwd(Ftp::Gateway * ftpState)
{
}
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendMkdir(Ftp::Gateway * ftpState)
{
ftpState->state = Ftp::Client::SENT_MKDIR;
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadMkdir(Ftp::Gateway * ftpState)
{
ftpSendReply(ftpState);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpGetFile(Ftp::Gateway * ftpState)
{
ftpSendMdtm(ftpState);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpListDir(Ftp::Gateway * ftpState)
{
ftpSendPassive(ftpState);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendMdtm(Ftp::Gateway * ftpState)
{
ftpState->state = Ftp::Client::SENT_MDTM;
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadMdtm(Ftp::Gateway * ftpState)
{
ftpSendSize(ftpState);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendSize(Ftp::Gateway * ftpState)
{
ftpSendPassive(ftpState);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadSize(Ftp::Gateway * ftpState)
{
ftpSendPassive(ftpState);
}
-/**
- \ingroup ServerProtocolFTPInternal
- */
static void
ftpReadEPSV(Ftp::Gateway* ftpState)
{
}
}
-/** \ingroup ServerProtocolFTPInternal
- *
- * Send Passive connection request.
+/** Send Passive connection request.
* Default method is to use modern EPSV request.
* The failover mechanism should check for previous state and re-call with alternates on failure.
*/
processReplyBody();
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadPasv(Ftp::Gateway * ftpState)
{
ftpRestOrList(this);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpOpenListenSocket(Ftp::Gateway * ftpState, int fallback)
{
ftpState->listenForDataChannel(temp);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendPORT(Ftp::Gateway * ftpState)
{
Ip::Address::FreeAddrInfo(AI);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadPORT(Ftp::Gateway * ftpState)
{
ftpRestOrList(ftpState);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendEPRT(Ftp::Gateway * ftpState)
{
ftpRestOrList(ftpState);
}
-/**
- \ingroup ServerProtocolFTPInternal
- \par
- * "read" handler to accept FTP data connections.
+/** "read" handler to accept FTP data connections.
*
\param io comm accept(2) callback parameters
*/
// Ctrl channel operations will determine what happens to this data connection
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpRestOrList(Ftp::Gateway * ftpState)
{
ftpSendRetr(ftpState);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendStor(Ftp::Gateway * ftpState)
{
}
}
-/// \ingroup ServerProtocolFTPInternal
/// \deprecated use ftpState->readStor() instead.
static void
ftpReadStor(Ftp::Gateway * ftpState)
}
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendRest(Ftp::Gateway * ftpState)
{
return 1;
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadRest(Ftp::Gateway * ftpState)
{
}
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendList(Ftp::Gateway * ftpState)
{
ftpState->state = Ftp::Client::SENT_LIST;
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendNlst(Ftp::Gateway * ftpState)
{
ftpState->state = Ftp::Client::SENT_NLST;
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadList(Ftp::Gateway * ftpState)
{
}
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendRetr(Ftp::Gateway * ftpState)
{
ftpState->state = Ftp::Client::SENT_RETR;
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadRetr(Ftp::Gateway * ftpState)
{
entry->unlock("Ftp::Gateway");
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpReadTransferDone(Ftp::Gateway * ftpState)
{
failed(ERR_READ_ERROR, 0);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpWriteTransferDone(Ftp::Gateway * ftpState)
{
ftpSendReply(ftpState);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendQuit(Ftp::Gateway * ftpState)
{
ftpState->state = Ftp::Client::SENT_QUIT;
}
-/**
- * \ingroup ServerProtocolFTPInternal
- *
- * This completes a client FTP operation with success or other page
+/** Completes a client FTP operation with success or other page
* generated and stored in the entry field by the code issuing QUIT.
*/
static void
ftpState->serverComplete();
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpTrySlashHack(Ftp::Gateway * ftpState)
{
nextState(this);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpFail(Ftp::Gateway *ftpState)
{
return Ftp::Client::failedHttpStatus(error);
}
-/// \ingroup ServerProtocolFTPInternal
static void
ftpSendReply(Ftp::Gateway * ftpState)
{
return newrep;
}
-/**
- \ingroup ServerProtocolFTPAPI
- \todo Should be a URL class API call.
- *
- * Construct an URI with leading / in PATH portion for use by CWD command
- * possibly others. FTP encodes absolute paths as beginning with '/'
- * after the initial URI path delimiter, which happens to be / itself.
- * This makes FTP absolute URI appear as: ftp:host:port//root/path
- * To encompass older software which compacts multiple // to / in transit
- * We use standard URI-encoding on the second / making it
- * ftp:host:port/%2froot/path AKA 'the FTP %2f hack'.
- */
const char *
Ftp::UrlWith2f(HttpRequest * request)
{
*/
#include "squid.h"
-
#include "anyp/PortCfg.h"
#include "client_side.h"
#include "clients/forward.h"
/// A new FTP Relay job
AsyncJobPointer StartRelay(FwdState *const fwdState);
-/**
- * \defgroup ServerProtocolFTPAPI Server-Side FTP API
- * \ingroup ServerProtocol
+/** Construct an URI with leading / in PATH portion for use by CWD command
+ * possibly others. FTP encodes absolute paths as beginning with '/'
+ * after the initial URI path delimiter, which happens to be / itself.
+ * This makes FTP absolute URI appear as: ftp:host:port//root/path
+ * To encompass older software which compacts multiple // to / in transit
+ * We use standard URI-encoding on the second / making it
+ * ftp:host:port/%2froot/path AKA 'the FTP %2f hack'.
+ *
+ * \todo Should be a URL class API call.
*/
-
-/// \ingroup ServerProtocolFTPAPI
const char *UrlWith2f(HttpRequest *);
} // namespace Ftp
HttpReply *const reply = new HttpReply;
Http::ProtocolVersion httpVersion = Http::ProtocolVersion(
- Ftp::ProtocolVersion().major, Ftp::ProtocolVersion().minor);
+ Ftp::ProtocolVersion().major, Ftp::ProtocolVersion().minor);
reply->sline.set(httpVersion, httpStatus);
HttpHeader &header = reply->header;
* Detects IPv6 and IPv4 level of support matches the address being listened on
* and if the compiled v2/v4 is usable as far down as a bind()ing.
*
- * \param test Address set on the http(s)_port being checked.
+ * \param test Address set on the squid.conf *_port being checked.
* \retval true TPROXY is available.
* \retval false TPROXY is not available.
*/
&Ftp::Server::handleEprtReply,// fssHandleEprt
&Ftp::Server::handleEpsvReply,// fssHandleEpsv
NULL, // fssHandleCwd
- NULL, //fssHandlePass
+ NULL, // fssHandlePass
NULL, // fssHandleCdup
&Ftp::Server::handleErrorReply // fssError
};