У меня есть веб-сайт, отображаемый с помощью wget
, и я хотел бы обслуживать его через Apache. Проблема в том, что я не могу получить доступ к файлам со специальными символами. Например, у меня есть файлы с именами вроде этого:
$ ls -N components/com_flexicontent/librairies/phpthumb/ | head -4
phpThumb.php?src=%2Fimages%2Fpiekny-wschod%2Ffestiwal-globtroterski-lublin2020-karuzela.jpg&w=290&h=177&aoe=1&q=95
phpThumb.php?src=%2Fimages%2Fdrezyny-rowerowe.jpg&w=90&h=90&aoe=1&q=95
phpThumb.php?src=%2Fimages%2FEko-Karpaty.jpg&w=90&h=90&aoe=1&q=95
phpThumb.php?src=%2Fimages%2FHotel_Anders_SPA.jpg&w=90&h=90&aoe=1&q=95
Итак phpThumb.php? Src =% 2Fimages% 2Fpiekny-wschod% 2Ffestiwal-globtroterski-lublin2020-karuzela & w = 297 & w = 297 = 1 & q = 95
относится к одному файлу в папке.
Когда я пытаюсь прочитать этот файл в веб-браузере, я получаю «Файл не найден»:
https: // xxxx / components / com_flexicontent / librairies / phpthumb / phpThumb.php? src = / images / piekny-wschod / festiwal-globtroterski-lublin2020-karuzela.jpg & w = 290 & h = 177 & aoe = 1 & q = 95
Это мой .htaccess
:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
RewriteCond %{QUERY_STRING} ^src=/images/piekny-wschod/(.*)$
RewriteRule ^components/com_flexicontent/librairies/phpthumb/phpThumb.php?$ components/com_flexicontent/librairies/phpthumb/phpThumb.php?src=%2Fimages%2Fpiekny-wschod%2F%1 [NE,L]
</IfModule>
Я тестировал создание множества различных правил, и они работают для имен файлов без амперсандов. Например. это работает:
RewriteRule ^components/com_flexicontent/librairies/phpthumb/phpThumb.php?$ components/com_flexicontent/librairies/select2/select2.css [NC,L]
Я пробовал правила с флагами NE
, B
, без эффекта.
웹 브라우저에서이 파일을 읽으려고하면 "파일을 찾을 수 없습니다"라는 메시지가 나타납니다.
https : //xxxx/components/com_flexicontent/librairies/phpthumb/phpThumb.php? src = / images / piekny-wschod / festiwal-globtroterski-lublin2020-karuzela.jpg & w = 290 & h = 177 & aoe = 1 & q = 95
디스크의 실제 파일 이름이 phpThumb.php? src = % 2Fimages % 2Fpiekny- wschod % 2Ffestiwal-globtroterski-lublin2020-karuzela.jpg & w = 290 & h = 177 & aoe = 1 & q = 95
그렇다면 문제를 일으키는 것은 &
(앰퍼샌드)뿐 아니라 ?
및 인코딩 된 슬래시 % 2F
-전체 쿼리 문자열입니다. % 2F
이 /
로 URL 디코딩되고 있지만 파일 이름에 리터럴 문자 % 2F
가 포함되어 있으므로 요청에서 이중 인코딩해야합니다. ).
해당 URL을 요청하면 Apache는 파일 phpThump.php
을 찾고 있습니다.이 파일은 아마도 존재하지 않을 것입니다.
이상적으로 URL은 올바른 URL (퍼센트)입니다. 초기 요청에서 인코딩되지 않은 경우 이러한 문자의 URL을 수동으로 지정해야합니다. 예를 들어 올바른 URL URL은 다음과 같습니다.
... / phpThumb.php % 3Fsrc = % 252Fimages % 252Fpiekny-wschod % 252Ffestiwal-globtroterski-lublin2020-karuzela.jpg % 26w = 290 % 26h = 177 % 26aoe = 1 % 26q = 95
실제 파일에 % 2F
(인코딩 된 /
)가 포함되어 있으므로 이러한 문자는 요청 된 URL에 이중 URL로 인코딩되어야합니다. /
이 아닌 % 2F
로 디코딩합니다. 복잡한 점은 src
속성에 여러 개의 인코딩 된 슬래시가있을 수 있다는 것입니다.
고정 된 수의 URL 매개 변수가있는 것 같습니다 (예 : &
). 따라서 이들은 단일 조건으로 대체하기가 상대적으로 간단합니다.
또한 .jpg
파일이 아니기 때문에 (즉, .jpg
파일 확장자)를 사용하면 Apache가 올바른 Content-Type
헤더 (파일 확장자에 의해 결정됨)를 보내지 않습니다. 수동으로 설정해야합니다.
다음을 시도해보십시오.
# Manually encode all "%2F" in the query string as "%252F", ie. recursively search and replace
# - This is not confined just to the "src" URL parameter value
# - Backslash escape literal "%" in RewriteRule substitution string
RewriteCond %{QUERY_STRING} (.*)%2F(.*)
RewriteRule ^(.+/phpThumb\.php)$ $1?%1\%252F%2 [N]
# Manually encode "?" and "&" in the query string (occur at fixed points)
# - Backslash escape literal "%" in RewriteRule substitution string
RewriteCond %{QUERY_STRING} ^(src=[^&]+)&(w=[^&]+)&(h=[^&]+)&(aoe=[^&]+)&(q=[^&]+)$
RewriteRule ^(.+/phpThumb\.php)$ $1\%3F%1\%26%2\%26%3\%26%4\%26%5 [T=image/jpg,L]
코드 주석에서 언급했듯이 RewriteRule
substitution 문자열의 리터럴 %
은 % n
형식의 역 참조 (마지막 일치 CondPattern 에 대한 역 참조)로 해석되지 않도록 백 슬래시 이스케이프 처리되었습니다.
모든 이미지가 유형이라고 가정합니다. image / jpg
.
다른 접근 방식은 소스 애플리케이션의 URL을 "prettify"하는 것입니다 (소스 애플리케이션에서 URL 재 작성).
예를 들어 이미지 소스 URL이 형식 :
... / phpthumb / 290 / 177 / 1 / 95 / images / piekny-wschod / festiwal-globtroterski-lublin2020-karuzela.jpg
다음에서 URL 재 작성 지점을 사용할 수 있습니다. 소스 응용 프로그램 :
RewriteRule ^(.+/phpthumb)/(\d+)/(\d+)/(\d+)/(\d+)/(.+\.jpg)$ $1/phpThumb.php?src=$6&w=$2&h=$3&aoe=$4&q=$5 [L]
그러면 이러한 이미지를 제공하기 위해 "미러링 된"웹 사이트에서 특별한 작업을 수행 할 필요가 없으며 합리적으로 합리적인 파일 이름을 갖게됩니다.
웹 서버가 &
문자를 매개 변수 구분 기호로 잘못 해석하고있는 것 같습니다.
을 사용하여 사이트를 다시 다운로드하는 것이 좋습니다. ] wget --restrict-file-names = windows
, wget이 파일 이름에서 &
을 @
로 변환하도록합니다. 아니면 파일 이름을 대량으로 변경 하시겠습니까?
find -name '*&*' | while read name ; do
newname=$(echo $name | sed -e 's:&:@:g')
mv "$name" "$newname"
done