Не могу обслуживать статические файлы с амперсандом в имени

У меня есть веб-сайт, отображаемый с помощью 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 , без эффекта.

2
задан 10 November 2020 в 14:29
2 ответа

웹 브라우저에서이 파일을 읽으려고하면 "파일을 찾을 수 없습니다"라는 메시지가 나타납니다.

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]

그러면 이러한 이미지를 제공하기 위해 "미러링 된"웹 사이트에서 특별한 작업을 수행 할 필요가 없으며 합리적으로 합리적인 파일 이름을 갖게됩니다.

1
ответ дан 4 January 2021 в 08:05

웹 서버가 & 문자를 매개 변수 구분 기호로 잘못 해석하고있는 것 같습니다.

을 사용하여 사이트를 다시 다운로드하는 것이 좋습니다. ] wget --restrict-file-names = windows , wget이 파일 이름에서 & @ 로 변환하도록합니다. 아니면 파일 이름을 대량으로 변경 하시겠습니까?

find -name '*&*' | while read name ; do
  newname=$(echo $name | sed -e 's:&:@:g')
  mv "$name" "$newname"
done
1
ответ дан 4 January 2021 в 08:05

Теги

Похожие вопросы