<!DOCTYPE html SYSTEM "about:legacy-compat">
<html lang="en"><head><META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<!--
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
              This file is generated from xml source: DO NOT EDIT
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      -->
<title>mod_proxy_ftp - Apache HTTP Server Version 2.4</title>
<link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet">
<link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size">
<link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css"><link rel="stylesheet" type="text/css" href="../style/css/prettify.css">
<script src="../style/scripts/prettify.min.js">
</script>

<link href="../images/favicon.png" rel="shortcut icon"></head>
<body>
<div id="page-header">
<p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="https://cwiki.apache.org/confluence/display/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a> | <a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug</a></p>
<p class="apache">Apache HTTP Server Version 2.4</p>
<img alt="" src="../images/feather.png"></div>
<div class="up"><a href="./"><img title="<-" alt="<-" src="../images/left.gif"></a></div>
<div id="path">
<a href="https://www.apache.org/">Apache</a> &gt; <a href="https://httpd.apache.org/">HTTP Server</a> &gt; <a href="https://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Modules</a></div>
<div id="page-content">
<div id="preamble"><h1>Apache Module mod_proxy_ftp</h1>
<button aria-label="Toggle language list" class="lang-toggle"><svg xmlns="http://www.w3.org/2000/svg" stroke-width="2" stroke="currentColor" fill="none" viewBox="0 0 24 24" height="16" width="16"><circle r="10" cy="12" cx="12"/><line y2="12" x2="22" y1="12" x1="2"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg></button>
<div class="toplang">
<p><span>Available Languages: </span><a href="../en/mod/mod_proxy_ftp.html" title="English">&nbsp;en&nbsp;</a> |
<a href="../fr/mod/mod_proxy_ftp.html" hreflang="fr" rel="alternate" title="Fran&ccedil;ais">&nbsp;fr&nbsp;</a></p>
</div>
<table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td>FTP support module for
<code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code></td></tr>
<tr><th><a href="module-dict.html#Status">Status:</a></th><td>Extension</td></tr>
<tr><th><a href="module-dict.html#ModuleIdentifier">Module&nbsp;Identifier:</a></th><td>proxy_ftp_module</td></tr>
<tr><th><a href="module-dict.html#SourceFile">Source&nbsp;File:</a></th><td>mod_proxy_ftp.c</td></tr></table>
<h3>Summary</h3>

    <p>This module <em>requires</em> the service of <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>. It provides support for the proxying
    FTP sites.  Note that FTP support is currently limited to
    the GET method.</p>

    <p>Thus, in order to get the ability of handling FTP proxy requests,
    <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code> and <code class="module"><a href="../mod/mod_proxy_ftp.html">mod_proxy_ftp</a></code>
    have to be present in the server.</p>

    <div class="warning"><h3>Warning</h3>
      <p>Do not enable proxying until you have <a href="mod_proxy.html#access">secured your server</a>. Open proxy
      servers are dangerous both to your network and to the Internet at
      large.</p>
    </div>
</div>
<div id="quickview"><h3>Topics</h3>
<ul id="topics">
<li><img alt="" src="../images/down.gif"> <a href="#mimetypes">Why doesn't file type <var>xxx</var>
    download via FTP?</a></li>
<li><img alt="" src="../images/down.gif"> <a href="#type">How can I force an FTP ASCII download of
    file <var>xxx</var>?</a></li>
<li><img alt="" src="../images/down.gif"> <a href="#ftpnonget">How can I do FTP upload?</a></li>
<li><img alt="" src="../images/down.gif"> <a href="#percent2fhck">How can I access FTP files outside
    of my home directory?</a></li>
<li><img alt="" src="../images/down.gif"> <a href="#ftppass">How can I hide the FTP cleartext password
    in my browser's URL line?</a></li>
<li><img alt="" src="../images/down.gif"> <a href="#wildcard">Why do I get a file listing when I expected
        a file to be downloaded?</a></li>
</ul><h3 class="directives">Directives</h3>
<ul id="toc">
<li><img alt="" src="../images/down.gif"> <a href="#proxyftpdircharset">ProxyFtpDirCharset</a></li>
<li><img alt="" src="../images/down.gif"> <a href="#proxyftpescapewildcards">ProxyFtpEscapeWildcards</a></li>
<li><img alt="" src="../images/down.gif"> <a href="#proxyftplistonwildcard">ProxyFtpListOnWildcard</a></li>
</ul>
<h3>Bugfix checklist</h3><ul class="seealso"><li><a href="https://www.apache.org/dist/httpd/CHANGES_2.4">httpd changelog</a></li><li><a href="https://bz.apache.org/bugzilla/buglist.cgi?bug_status=__open__&amp;list_id=144532&amp;product=Apache%20httpd-2&amp;query_format=specific&amp;order=changeddate%20DESC%2Cpriority%2Cbug_severity&amp;component=mod_proxy_ftp">Known issues</a></li><li><a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2&amp;component=mod_proxy_ftp">Report a bug</a></li></ul><h3>See also</h3>
<ul class="seealso">
<li><code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code></li>
</ul></div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif"></a></div>
<div class="section">
<h2 id="mimetypes">Why doesn't file type <var>xxx</var>
    download via FTP? <a title="Permanent link" href="#mimetypes" class="permalink">&para;</a></h2>
      <p>You probably don't have that particular file type defined as
      <code>application/octet-stream</code> in your proxy's mime.types
      configuration file. A useful line can be:</p>

      <div class="example"><pre>application/octet-stream   bin dms lha lzh exe class tgz taz</pre></div>
      <p>Alternatively you may prefer to use the <code class="directive"><a href="../mod/core.html#forcetype">ForceType</a></code>
      directive to default everything to binary:</p>
      <div class="example"><pre class="prettyprint lang-config">ForceType application/octet-stream</pre>
</div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif"></a></div>
<div class="section">
<h2 id="type">How can I force an FTP ASCII download of
    file <var>xxx</var>? <a title="Permanent link" href="#type" class="permalink">&para;</a></h2>
      <p>In the rare situation where you must download a specific file using the
      FTP <code>ASCII</code> transfer method (while the default transfer is in
      <code>binary</code> mode), you can override <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>'s
      default by suffixing the request with <code>;type=a</code> to force an
      ASCII transfer. (FTP Directory listings are always executed in ASCII mode,
      however.)</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif"></a></div>
<div class="section">
<h2 id="ftpnonget">How can I do FTP upload? <a title="Permanent link" href="#ftpnonget" class="permalink">&para;</a></h2>
    <p>Currently, only GET is supported for FTP in <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>.  You can
    of course use HTTP upload (POST or PUT) through an Apache proxy.</p>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif"></a></div>
<div class="section">
<h2 id="percent2fhck">How can I access FTP files outside
    of my home directory? <a title="Permanent link" href="#percent2fhck" class="permalink">&para;</a></h2>
      <p>An FTP URI is interpreted relative to the home directory of the user
      who is logging in. Alas, to reach higher directory levels you cannot
      use /../, as the dots are interpreted by the browser and not actually
      sent to the FTP server. To address this problem, the so called <dfn>Squid
      %2f hack</dfn> was implemented in the Apache FTP proxy; it is a
      solution which is also used by other popular proxy servers like the <a href="http://www.squid-cache.org/">Squid Proxy Cache</a>. By
      prepending <code>/%2f</code> to the path of your request, you can make
      such a proxy change the FTP starting directory to <code>/</code> (instead
      of the home directory). For example, to retrieve the file
      <code>/etc/motd</code>, you would use the URL:</p>

      <div class="example"><p><code>
        ftp://<var>user</var>@<var>host</var>/%2f/etc/motd
      </code></p></div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif"></a></div>
<div class="section">
<h2 id="ftppass">How can I hide the FTP cleartext password
    in my browser's URL line? <a title="Permanent link" href="#ftppass" class="permalink">&para;</a></h2>
      <p>To log in to an FTP server by username and password, Apache uses
      different strategies. In absence of a user name and password in the URL
      altogether, Apache sends an anonymous login to the FTP server,
      <em>i.e.</em>,</p>

      <div class="example"><p><code>
        user: anonymous<br>
        password: apache-proxy@
      </code></p></div>

      <p>This works for all popular FTP servers which are configured for
      anonymous access.</p>

      <p>For a personal login with a specific username, you can embed the user
      name into the URL, like in:</p>

      <div class="example"><p><code>
        ftp://<var>username</var>@<var>host</var>/myfile
      </code></p></div>

      <div class="note"><h3>HttpProtocolOptions</h3>
        <p>By default, <code class="directive"><a href="../mod/core.html#httpprotocoloptions">HttpProtocolOptions</a></code> is set to <code>Strict</code>,
        which rejects URLs containing userinfo (username or password)
        per RFC 7230.  To use credentials in FTP URLs, you must set
        <code>HttpProtocolOptions Unsafe</code>.</p>
      </div>

      <p>If the FTP server asks for a password when given this username (which
      it should), then Apache will reply with a <code>401</code> (Authorization
      required) response, which causes the Browser to pop up the
      username/password dialog. Upon entering the password, the connection
      attempt is retried, and if successful, the requested resource is
      presented. The advantage of this procedure is that your browser does not
      display the password in cleartext (which it would if you had used</p>

      <div class="example"><p><code>
        ftp://<var>username</var>:<var>password</var>@<var>host</var>/myfile
      </code></p></div>

      <p>in the first place).</p>

      <div class="note"><h3>Note</h3>
        <p>The password which is transmitted in such a way is not encrypted on
        its way. It travels between your browser and the Apache proxy server in
        a base64-encoded cleartext string, and between the Apache proxy and the
        FTP server as plaintext. You should therefore think twice before
        accessing your FTP server via HTTP (or before accessing your personal
        files via FTP at all!) When using insecure channels, an eavesdropper
        might intercept your password on its way.</p>
      </div>
    </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif"></a></div>
<div class="section">
<h2 id="wildcard">Why do I get a file listing when I expected
        a file to be downloaded? <a title="Permanent link" href="#wildcard" class="permalink">&para;</a></h2>
      <p>In order to allow both browsing the directories on an FTP server and
        downloading files, Apache looks at the request URL.  If it looks like
        a directory, or contains wildcard characters ("*?[{~"), then it
        guesses that a listing is wanted instead of a download.</p>
      <p>You can disable the special handling of names with wildcard characters.
        See the <code class="directive"><a href="#proxyftplistonwildcard">ProxyFtpListOnWildcard</a></code> directive.
      </p>
    </div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif"></a></div>
<div class="directive-section"><h2 id="proxyftpdircharset"><span id="ProxyFtpDirCharset">ProxyFtpDirCharset</span> Directive <a title="Permanent link" href="#proxyftpdircharset" class="permalink">&para;</a></h2>
<table class="directive">
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Define the character set for proxied FTP listings</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>ProxyFtpDirCharset <var>character_set</var></code></td></tr>
<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>ProxyFtpDirCharset ISO-8859-1</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory</td></tr>
<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_proxy_ftp</td></tr>
<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>Available in Apache 2.2.7 and later. Moved from <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code> in Apache 2.3.5.</td></tr>
</table>
    <p>The <code class="directive">ProxyFtpDirCharset</code> directive defines the
    character set to be set for FTP directory listings in HTML generated by
    <code class="module"><a href="../mod/mod_proxy_ftp.html">mod_proxy_ftp</a></code>.</p>

</div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif"></a></div>
<div class="directive-section"><h2 id="proxyftpescapewildcards"><span id="ProxyFtpEscapeWildcards">ProxyFtpEscapeWildcards</span> Directive <a title="Permanent link" href="#proxyftpescapewildcards" class="permalink">&para;</a></h2>
<table class="directive">
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Whether wildcards in requested filenames are escaped when sent to the FTP server</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>ProxyFtpEscapeWildcards on|off</code></td></tr>
<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>ProxyFtpEscapeWildcards on</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory</td></tr>
<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_proxy_ftp</td></tr>
<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>Available in Apache 2.3.3 and later</td></tr>
</table>
  <p>The <code class="directive">ProxyFtpEscapeWildcards</code> directive
    controls whether wildcard characters ("*?[{~") in requested
    filenames are escaped with backslash before sending them to the
    FTP server.  That is the default behavior, but many FTP servers
    don't know about the escaping and try to serve the literal filenames
    they were sent, including the backslashes in the names.</p>
    <p>Set to "off" to allow downloading files with wildcards
    in their names from FTP servers that don't understand wildcard
    escaping.</p>

</div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif"></a></div>
<div class="directive-section"><h2 id="proxyftplistonwildcard"><span id="ProxyFtpListOnWildcard">ProxyFtpListOnWildcard</span> Directive <a title="Permanent link" href="#proxyftplistonwildcard" class="permalink">&para;</a></h2>
<table class="directive">
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Whether wildcards in requested filenames trigger a file listing</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>ProxyFtpListOnWildcard on|off</code></td></tr>
<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>ProxyFtpListOnWildcard on</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory</td></tr>
<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_proxy_ftp</td></tr>
<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>Available in Apache 2.3.3 and later</td></tr>
</table>
  <p>The <code class="directive">ProxyFtpListOnWildcard</code> directive
    controls whether wildcard characters ("*?[{~") in requested
    filenames cause <code class="module"><a href="../mod/mod_proxy_ftp.html">mod_proxy_ftp</a></code> to return a listing
    of files instead of downloading a file.  By default (value on),
    they do.</p>
    <p>Set to "off" to allow downloading files even if they
    have wildcard characters in their names.</p>

</div>
</div>
<div class="bottomlang">
<p><span>Available Languages: </span><a href="../en/mod/mod_proxy_ftp.html" title="English">&nbsp;en&nbsp;</a> |
<a href="../fr/mod/mod_proxy_ftp.html" hreflang="fr" rel="alternate" title="Fran&ccedil;ais">&nbsp;fr&nbsp;</a></p>
</div><div id="footer">
<p class="apache">Copyright 2026 The Apache Software Foundation.<br>Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
<p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="https://cwiki.apache.org/confluence/display/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a> | <a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug</a></p></div><script><!--//--><![CDATA[//><!--
if (typeof(prettyPrint) !== 'undefined') {
    prettyPrint();
}
var langToggle = document.querySelector('.lang-toggle');
var topLang = document.querySelector('.toplang');
if (langToggle && topLang) {
    langToggle.addEventListener('click', function() { topLang.classList.toggle('open'); });
}
var qv = document.getElementById('quickview');
if (qv) {
    document.body.appendChild(qv);
    var qvBtn = document.createElement('button');
    qvBtn.className = 'qv-toggle';
    qvBtn.setAttribute('aria-label', 'Toggle page navigation');
    qvBtn.innerHTML = '&#9776;';
    document.body.appendChild(qvBtn);
    qvBtn.addEventListener('click', function() {
        var isOpen = qv.classList.toggle('open');
        if (isOpen) {
            qv.style.top = window.scrollY + 10 + 'px';
        }
    });
    window.addEventListener('scroll', function() { qv.classList.remove('open'); });
}
//--><!]]></script>
</body></html>