如何使文件看起来像在服务器上的根目录中

时间:2013-01-18 20:07:23

标签: php .htaccess ftp apache2

我有单独的域指向专用框上的单独文档根

我想授予对此文档根目录下的子文件夹ftp-upload的FTP访问权限。

正确的FTP配置不是此问题的一部分

如果授权人员将文件上传到document_root / ftp-upload,则可以通过domain.com/file而不是domain.com/ftp-upload/file

访问此文件

.htaccess文件位于文档根目录

我尝试过一些东西,但它们似乎没有用。

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /
    ## check if the file exists in subfolder
    ##   ...and if found, stop and display it
    RewriteCond %{DOCUMENT_ROOT}/ftp-upload/$1 -f [OR]
    RewriteCond %{DOCUMENT_ROOT}/ftp-upload/$1 -d
    RewriteCond $1 !^$
    RewriteRule  (.*)  %{DOCUMENT_ROOT}/ftp-upload/$1 [L]

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond $1 !^(index\.php|images|robots\.txt|css|assets|ftp-upload)
    RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>

我也试过

RewriteCond  %{DOCUMENT_ROOT}/ftp-upload/${REQUEST_FILENAME} -f

RewriteCond %{DOCUMENT_ROOT}/ftp-upload%{REQUEST_URI} -f

这是一项正在进行的工作,所以这不是最终的解决方案,但是这项功能正在被要求很多。如果可能的话,我宁愿不让他们访问文档根目录。

更新: 当它想要的时候看起来像是工作的东西......

如果我输入domain.com/test.txt(仅存在于ftp-upload目录中) 请求转到domain.com/index.php/test.txt,我在主页

如果我输入domain.com/ftp-upload/,我会收到包含test.txt

的目录列表

如果我点击test.txt,我会得到文件内容(“工作正常!”)。如果我输入domain.com/test.txt,我会再次显示文件内容......

我的脑袋爆炸......有什么想法吗?

解决了另一种方式,这里的答案在我的服务器上无效。

我现在建立的CMS有另一个用户组'SEO优化'和上传部分。在该部分下,用户可以选择他们想要将文件上载到哪个指定位置。如果上传文件夹中存在所请求的文件,则网站index.php(控制器/路由器)将提供服务。没有.htaccess编辑,因为我的服务器表现得很时髦..

5 个答案:

答案 0 :(得分:7)

我理解的事实(如果错误,请纠正我)

  • 您有单独的域指向单独的文档根
  • 您要授予对此文档根目录下的子文件夹ftp-upload的FTP访问权限。
  • 正确的FTP配置不是此问题的一部分
  • 如果授权人员将文件上传到document_root/ftp-upload,则应通过domain.com/file而不是domain.com/ftp-upload/file
  • 访问此文件
  • .htaccess文件位于文档根目录

对于上述事实,这是一个有效的.htaccess文件。请注意我使用的文件夹名称是ftp-upload,您在问题中使用了几个不同的版本(ftp-uploadftp_uploadftpupload)确保这一点在你的配置

域名文件根目录

中的

.htaccess

RewriteEngine On
RewriteBase /
RewriteCond %{DOCUMENT_ROOT}/ftp-upload%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/ftp-upload%{REQUEST_URI} -d 
RewriteRule ^(.*)$  ftp-upload/$1       [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|robots\.txt|css|assets)
RewriteRule ^(.*)$  index.php/$1        [L]

我所做的是检查子文件夹/ftp-upload中是否存在所请求的文件。

棘手的是RewriteCond file -f需要一条完整的路径。这就是为什么你通常会对%{REQUEST_FILENAME}%进行测试的原因 如果此条件为真(文件存在),只需将请求重写为ftp-upload/filename

这也适用于ftp-folder内的子文件夹,例如文件夹ftp-folder/test/image.png可以/test/image.png

访问

第二部分只是你平常的“如果文件不存在,重写为/index.php”

修改

旁注

  OP表示“这不起作用” - 好吧,谢谢你的尝试 - 在这篇有用的评论之后,我接近删除了我的答案,但是在我完成这篇文章的工作后,我确认建议的解决方案是工作得很完美,我决定喘口气并提供一些调试技巧。

这就是说,如果这不适合你:

  • 确保您的“隐藏”上传文件夹实际上名为ftp-upload,同时,Linux 区分大小写
  • 确保您的网络服务器配置为读取.htaccess文件:

      您的vhost配置中的
    • AllowOverride指令。
    • 常用值为AllowOverride All
    • 您只需在.htaccess中添加无效内容(例如givemeanerror on)并在您的网络浏览器中打开该页面即可对此进行测试。如果读取.htaccess文件,您将在浏览器中收到500 Internal Server错误消息。如果您没有测试环境,可以在测试子文件夹中执行此操作
  • 我上面发布的配置应该替换.htaccess文件的整个内容,该文件位于DOCUMENT_ROOT(不在ftp-upload文件夹中) ,用于调试甚至删除<IfModule>包装,一旦这个工作正常,可以放回来

  • 进行测试,将图像文件复制到ftp-upload文件夹中,假设为test.png

  • 如果您仍然无法在浏览器中访问http://yourdomain.com/test.png,我希望看到此请求的响应标题
  • 如果您不知道如何观看回复标题,请转到http://www.webconfs.com/http-header-check.php,输入网址http://yourdomain.com/test.png并复制结果

希望这会有所帮助:)

答案 1 :(得分:1)

请根据您的需要http://dev.wadakkir.org/test/

检查我创建的这个空间

这是前一个空间的结构:

是你需要的吗?

如果是这样,我可以使用以下.htaccess文件

执行此行为
Options +Indexes
RewriteCond  %{REQUEST_URI} !^/test/subF/
RewriteRule ^(.*)$ /test/subF/$1

在你的情况下应该是这样的:

Options +Indexes
RewriteCond  %{REQUEST_URI} !^/ftp-upload/
RewriteRule ^(.*)$ /ftp-upload/$1

希望它有所帮助,如果不是我仍然可以再试一次:)

<强>更新

正如我之前的评论中所建议的,以下是一个快速编写的网关,您可以查看http://dev.wadakkir.org/test/执行示例(我会在那里放一段时间)

以下是我使用的源代码:

的index.php

<?php

require_once 'gateway.php';

echo "<h1>Hello World!</h1>";
?>
Existing file names are:
<ul>
    <li>01_Content_Of_Test_Folder.png</li>
    <li>02_Content_Of_SubF_Folder.png</li>
    <li>2ndTst.txt</li>
    <li>tst.txt</li>
</ul>

gateway.php

<?php

if( !empty($_GET['cf']) ){
$filename = "./subF/".$_GET['cf'];
if( is_file( $filename ) )
    dwldFunction($filename);
else{
    // TODO change this to what ever you want
    die("File not found ($filename)");
    }
    exit(1);
}


function dwldFunction( $fName ) {
// detect mime type
$mime = getMime( $fName );

header('Pragma: public');   
header('Expires: 0');       
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private',false);
header('Content-Type: '. $mime );
header('Content-Disposition: attachment; filename="'.basename($fName).'"');
header("Content-Length: " . filesize($fName));
header('Connection: close');

readfile( $fName );
}

function getMime( $fName ) {
    $r = pathinfo($fName);
    $m ;
    //TODO: 
    // complete the following list or use
    //$finfo = finfo_open(FILEINFO_MIME_TYPE);
    //finfo_file($finfo, $fName);
    //finfo_close($finfo);
    // @: http://php.net/manual/en/function.finfo-file.php
    switch ( $r['extension'] ){
        case "pdf":
            $m = "application/pdf";
            break;
        case "txt":
            $m = "text/plain";
            break;
        case "png":
                $m = "image/png";
            break;
    }
    return $m;
}

.htaccess 内容为:

Options +Indexes

RewriteCond %{REQUEST_URI} !^/test/subF/
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{REQUEST_URI} !subF
RewriteRule ^(.*)$ /test/index.php?cf=$1

您可以从此link

下载完整的源代码

答案 2 :(得分:0)

所有这些答案对我来说似乎过于复杂

假设我们有一个目录结构如下

/ home / user / www / {web root} / home / user / ftpuploadfolder / {ftp folder}

并且您希望该文件夹通过apache显示为/ home / user / www / folder

为什么不创建一个符号链接? ln -s / home / user / ftpuploadfolder / / home / user / www / publicfolder /

这样做你可以对链接文件夹拥有不同的权限,例如apache只能访问公共文件夹(不是公共读/写等),而ftp只能访问你的ftpupload文件夹

答案 3 :(得分:0)

我使用PHP文件来读取所需文件(在本例中为子文件夹中),然后将其输出给用户。但是,我认为您的解决方案可以在以下答案中找到:

https://stackoverflow.com/a/1851873/1794894

答案 4 :(得分:0)

RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^yourhost.com|^www.yourhost.com
RewriteCond %{REQUEST_URI} !^/new
RewriteRule ^(.*)$ new/$1 [L]

这意味着

www.yourhost.com/new /

实际上是

www.yourhost.com