2013-08-20 25 views
6

Tôi tự hỏi nếu có thể có một điều như vậy. Tôi muốn kiểm tra kích thước của tập tin và sau đó làm các quy tắc htaccess dựa trên nó. Ví dụ:quy tắc .htaccess để nhận kích thước tệp được yêu cầu

# like this line 
CheckIf {REQUESTED_FILE_SIZE} 50 # MB 
AuthName "Login title" 
AuthType Basic 
AuthUserFile /path/to/.htpasswd 
require valid-user 

Rõ ràng là tôi muốn làm cho một số tập tin với kích thước tập tin cụ thể có sẵn cho một số người dùng chỉ (Sử dụng Authentication)

Bất cứ ý tưởng được đánh giá cao.

Update # 1

nên được thực hiện trong htaccess

Update # 2

Có rất nhiều tập tin và URL của họ đã được đăng trong blog. Vì vậy, không thể tách các tệp lớn hơn thành một thư mục khác và cập nhật từng bài đăng, cũng như giới hạn kích thước tệp có thể thay đổi trong tương lai.

Update # 3

Đó là một máy chủ các cửa sổ với PHP & Helicon App cài đặt

Update # 4

Một số người đã nhầm lẫn về vấn đề thực tế và tôi đã không cũng không rõ.

.htaccess + PHP tập tin để xác thực (sử dụng API) và kiểm tra kích thước tập tin + Tất cả các tập tin tải về là tất cả trong cùng một máy chủ NHƯNG website của chúng tôi được lưu trữ trên một máy chủ khác nhau.

+0

Chỉ có thể sử dụng tập lệnh khác có thể được sử dụng trong '.htaccess'. Không có biến máy chủ nào để xác định kích thước tệp. Truy vấn duy nhất khác của bạn là giải quyết vấn đề này từ proxy phía trước. –

+0

@BurhanKhalid bạn có nghĩa là kiểm tra kích thước tệp như trong php? – revo

+0

có, một cái gì đó như thế hoặc sử dụng một proxy ngược như nginx và có nó xử lý phần này. –

Trả lời

0

Lúc đó tôi hỏi những câu hỏi Apache 2.4 đã ra để câu trả lời này có thể là đúng .

Apache Expressions

Tính đến Apache 2.4 một khả năng mới được gọi là Expressions đã được giới thiệu. Theo đó, bạn có thể sử dụng một số chức năng trong chỉ thị của bạn và cũng kết hợp với RewriteCond.

May mắn thay có một hàm có tên filesize() có khả năng so sánh kích thước tập tin cùng với Toán tử so sánh:-et -gt -ge -lt -le -ne

Nói rằng - tuy nhiên tài liệu thiếu thông tin liên quan đến chức năng này - dưới đây tương ứng với quy tắc để so sánh kích thước tập tin:

RewriteCond expr "filesize('%{REQUEST_FILENAME}') -gt 52428800" 
RewriteRule ** ** 

Sử dụng biểu thức bên trong RewriteCond nên được thực hiện trong phạm vi cú pháp sau:

RewriteCond expr "..." 

BNF:

expr  ::= "true" | "false" 
       | "!" expr 
       | expr "&&" expr 
       | expr "||" expr 
       | "(" expr ")" 
       | comp 

Bạn có thể tìm thấy trọn vẹn BNF tại trang tài liệu.

1

Không trực tiếp, nhưng với một chút sửa đổi về phía hệ thống tệp, bạn có thể làm điều đó.

Nếu đây là một hệ thống mà người dùng tải lên cũng như tải về, bạn có thể key off của Content-Length tiêu đề trong mod_rewrite để đưa các tập tin lớn hơn vào một thư mục riêng biệt. (hoặc nếu bạn có thể di chuyển theo cách khác khi tải lên)

Tiếp theo, trong thư mục có các tệp lớn hơn bạn đặt để yêu cầu auth cho tất cả các tệp.

Cuối cùng, hãy sử dụng các kiểm tra sự tồn tại trong mod_rewrite để chuyển hướng người dùng một cách minh bạch đến thư mục large_files nếu tệp đó ở đó.

Nếu bạn không thể di chuyển tệp, bạn có thể sử dụng liên kết tượng trưng để thiết lập hai bố cục.

+0

Vui lòng xem bản cập nhật thứ hai của tôi – revo

+0

Chúc bạn may mắn sau đó. Lưu ý rằng đề xuất của tôi rõ ràng sẽ không yêu cầu cập nhật các mục blog - điểm là mặc dù các tệp được đặt ở nơi khác, bạn sử dụng các kiểm tra tệp có điều kiện của mod_rewrite để các url vẫn giữ nguyên. Khá tầm thường để thiết lập hai cây bằng cách sử dụng liên kết tượng trưng + tìm trong linux, nhưng tôi e rằng tôi không biết đủ quyền hạn để cung cấp phiên bản cửa sổ. –

2

tôi muốn làm điều đó trong 2 bước sau:

1: htaccess chuyển hướng tất cả các yêu cầu đối với một php script, nói rằng bạn có các tập tin của bạn bên trong /test/ và bạn muốn làm cho nó tất cả các xử lý bởi /test/index.php, ví dụ:

RewriteEngine On 
RewriteBase /test 
RewriteCond %{REQUEST_URI} !/test/index.php 
RewriteRule ^(.+)? /test/index.php?file=$1 [L] 

RewriteCond chỉ để tránh yêu cầu vòng lặp.

2: kịch bản index.php hiện tất cả các logic auth, dựa trên kích thước tập tin được yêu cầu, như thế này:

define('LIMIT_FILESIZE',50*1024*1024); // eg.50Mb 
define('AUTH_USER', 'myuser');   // change it to your likes 
define('AUTH_PW','mypassword');  // change it to your likes 

if(filesize($_GET['file'])>LIMIT_FILESIZE){ 
    if(!isset($_SERVER['PHP_AUTH_USER'])) { 
    header('WWW-Authenticate: Basic realm="My realm"'); 
    header('HTTP/1.0 401 Unauthorized'); 
    echo 'Canceled'; 
    exit; 
    } 
    else if($_SERVER['PHP_AUTH_USER']!=AUTH_USER && 
      $_SERVER['PHP_AUTH_PW']!=AUTH_PW) { 
    header('HTTP/1.0 401 Unauthorized'); 
    echo 'Wrong credentials'; 
    exit; 
    } 
} 

// If we're here, it's fine (filesize is below or user is authenticated) 
// offer file for download 
$file = rawurldecode($_GET['file']); 
$finfo = finfo_open(FILEINFO_MIME_TYPE); 
$mime = finfo_file($finfo, $file); 
header("Content-type: ".$mime); 
header("Content-Disposition: attachment; filename=".basename($file)); 
include($file); 

Có rất nhiều cải tiến tốt với nó, nhưng nó phải làm việc như một cơ sở.

+0

Cảm ơn Paolo nhưng điều này đã hoàn tất. Khi nói đến tốc độ và hiệu suất PHP bị lỗi trong trường hợp này. Các tệp không được lưu trữ trong cùng một máy chủ để chúng tôi cần phản hồi từ một máy chủ khác để kiểm tra xem tên người dùng và mật khẩu có hợp lệ không và mất nhiều thời gian, việc xử lý hồ sơ tải xuống sẽ cần PHP không phù hợp và sẽ giảm tải xuống tốc độ so với tải xuống bình thường. Cũng bằng cách này, bắt đầu mỗi yêu cầu để nhận được một tập tin mất đến 40s (Auth) trong trường hợp của chúng tôi, vì vậy tôi thấy nó tốt hơn để xử lý nó với htaccess và htpasswd để trả lời tất cả các vấn đề này. – revo

+1

Các tệp không nằm trong cùng một máy chủ? Vì vậy, đối với mỗi yêu cầu bạn sẽ yêu cầu Apache để có được trên một mạng để kiểm tra kích thước tập tin được yêu cầu? Tôi nghĩ rằng đây sẽ là một vấn đề hiệu suất nghiêm trọng. –

+0

Tôi có nghĩa là máy chủ lưu trữ tệp tách biệt với chính trang web. chúng tôi có các tệp trong một máy chủ và trang web chuyên dụng trong một máy chủ lưu trữ khác. vì vậy nếu chúng ta muốn trải qua PHP, chúng ta nên tạo một API để kiểm tra xác nhận người dùng trên mọi yêu cầu tải xuống mà chúng ta không muốn. – revo

3

Rõ ràng là .htaccess không thể kiểm tra kích thước tệp được yêu cầu và hành động tương ứng. Những gì bạn có thể có thể làm là tận dụng External Rewriting Program feature of RewriteMap

Bạn cần phải xác định một RewriteMap như thế này cấu hình Apache của bạn đầu tiên:

RewriteMap checkFileSize prg:/home/revo/checkFileSize.php 

Sau đó bên trong .htaccess của bạn xác định một quy tắc như vậy bằng cách:

RewriteRule - ${checkFileSize:%{REQUEST_FILENAME}} 

%{REQUEST_FILENAME} được chuyển sang tập lệnh PHP trên STDIN.

Sau đó, bên trong /home/revo/checkFileSize.php bạn có thể đặt mã PHP để kiểm tra kích thước tệp và hành động tương ứng như chuyển hướng đến URI hiển thị hộp thoại xác thực cơ bản.

+0

Điểm khác biệt của «RewriteRule'» với «RewriteRule (. *) /path/to/php/checkFileSize.php» URI = $ 1' sau đó là gì? – revo

+0

Tôi nghĩ cả hai người sẽ hành xử giống nhau. Cá nhân tôi đã luôn sử dụng kiểu 'RewriteRule ^/some/target' cũng giống nhau. – anubhava

2

Tôi nghĩ cả hai câu trả lời từ @Paolo Stefan và @anubhava đều hợp lệ (+1).

Lưu ý rằng việc sử dụng RewriteMap sẽ thực thi sửa đổi cấu hình apache, không chỉ trên tệp .htaccess. Nếu bạn nghĩ một chút về hiệu suất bạn nên, trên thực tế, đặt tất cả những thứ bạn có trong các tập tin .htaccess vào chỉ thị <directory /same/filesystem/path/as/the/.htaccess/file/> và đặt một AllowOverride None trong cấu hình VirtualHost. Bạn chắc chắn sẽ đạt được một số tốc độ bằng cách tránh các tệp I/O và các cài đặt tệp cấu hình kiểm tra động cho apache cho mỗi truy vấn (các tệp .htaccess là xấu, thực sự). Vì vậy, thực tế là RewriteMap không có sẵn trong .htaccess không phải là một vấn đề.

Đề xuất hai câu trả lời cung cấp một cách để thay đổi thực tế các tiêu đề Xác thực dựa trên kích thước tệp. Bây giờ, một thực tế quan trọng bạn quên đề cập đến trong câu hỏi của bạn là các tệp không có sẵn trực tiếp trên cùng một máy chủ so với các tệp PHP và cũng không phải bạn muốn khởi chạy tập lệnh trên mỗi lần tải xuống.

Với giải pháp @anubhava hiện tại, bạn sẽ có cuộc gọi trên hệ điều hành cho kích thước tệp ở mỗi quyền truy cập và dĩ nhiên tập lệnh này sẽ được chạy trên máy chủ lưu trữ tệp.

Một giải pháp có thể lưu trữ ở đâu đó (lưu trữ giá trị khóa hoặc cơ sở dữ liệu chuyên dụng?) Chỉ mục kích thước tệp. Bạn có thể nạp chỉ mục này sau mỗi lần tải xuống, bạn có thể quản lý một số tác vụ không đồng bộ để duy trì nó. Sau đó, trên cấu hình apache của máy chủ lưu trữ tập tin, bạn sẽ phải khởi chạy một kịch bản kiểm tra kích thước tập tin.Sử dụng RewriteMap bạn có một vài lựa chọn:

  • sử dụng một rất nhanh script với prg: từ khóa (viết bằng C, Perl, bất cứ điều gì, bạn đang không gắn với PHP), yêu cầu đối với chỉ số này của kích thước tập tin trong lưu trữ dữ liệu này, hoặc thậm chí fastdbd: để trực tiếp thực hiện truy vấn SQL trong apache. Nhưng điều này có nghĩa là một truy vấn ở mỗi yêu cầu, vì vậy bạn có các giải pháp khác.
  • use directly o mapping file với txt: từ khóa, có cho mỗi tên tập tin kích thước phù hợp đã được tính toán, truy vấn không còn nữa, chỉ
  • thậm chí tốt hơn, sử dụng một hashmap of this file với dbm: `từ khóa.

Với hai tùy chọn cuối cùng, chỉ mục kích thước tệp là tệp văn bản hoặc phiên bản băm của tệp văn bản này. Apache đang lưu bộ nhớ đệm vào băm và biên dịch lại bộ nhớ đệm khi khởi động lại hoặc khi thời gian sửa đổi của tệp bị thay đổi. Vì vậy, bạn sẽ chỉ cần recompute hashmap này sau mỗi lần tải về để có được một tấm séc filesize rất nhanh trong một RewriteRule như thể hiện bởi anubhava nhưng sử dụng

RewriteMap checkFileSize dbm:/path/to/filesize_precomputed_index.map 

Bạn cũng có thể thử sử dụng mod_security trên các máy chủ file và kiểm tra Content-Length để thêm HTTP Auth. Kiểm tra this thread để bắt đầu câu trả lời về chủ đề đó. Nhưng cấu hình mod_security không phải là một nhiệm vụ dễ dàng.

+0

Tôi sẽ đọc về chúng và vui lòng xem bản cập nhật thứ 4 của tôi. – revo

+0

nhưng sử dụng rewritemap theo ý kiến ​​của tôi sẽ không khác với việc sử dụng rewriterule như tôi đã bình luận về câu trả lời anubhava và nếu đó là sự thật nó không thể giúp tôi – revo

+0

RewriteMap có thể cung cấp cho bạn một công cụ có thể nhanh hoặc chậm mà bạn có thể sử dụng rewriteRule, và sử dụng PHP hoặc một cái gì đó elese trên máy chủ tập tin không có nghĩa là bạn sử dụng cùng một PHP như là một được sử dụng trên máy chủ ứng dụng web. Và rewriteMap có thể tránh sử dụng các script nếu nó sử dụng một nguồn băm. – regilero

1

Theo thismod_rewrite hỗ trợ một "-s"CondPattern mà kiểm tra nếu các quy định TestString là một tập tin thường xuyên với kích thước khác không. patch được đính kèm mở rộng tùy chọn "-s" để hỗ trợ so sánh với kích thước tùy ý.

Vì vậy, đặt câu hỏi:

CheckIf {REQUESTED_FILE_SIZE} 50 # MB 

nên làm việc với .htaccess mã này:

RewriteCond %{REQUEST_FILENAME} -s=52428800 
+0

Có nhưng tệp đính kèm này không bao giờ được vá! – revo

+0

Tôi đã sử dụng đầu mối nhất định của bạn để trả lời câu hỏi này. Cảm ơn – revo

+0

Bạn được chào đón nhiều nhất. Tôi cũng đã thay đổi kích thước 50MB theo của bạn. – hyip

Các vấn đề liên quan