1

주제: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

http://www.tattertools.com/bbs/view.php … amp;no=160
http://www.tattertools.com/bbs/view.php … amp;no=143

일전에 태터 게시판에 썼던 내용인데,
이곳 게시판에 버그를 써야만 ticket 등록이 된다고 해서 올립니다.

현재 태터툴즈는 Apache + mod_php 환경에서만 작동하며 php를 CGI로 가동할 경우에는 작동하지 않습니다.
(이상하게 국내에서는 mod_php 보다 더 나은 퍼포먼스를 보여주는 FastCGI 방식을 잘 사용하지 않더군요.
다들 메모리가 넉넉한 서버를 쓰시나봐요.)

에러의 원인은 .htaccess 의 RedirectRule 과 태터 프로그램 내의 $_SERVER['REDIRCET_URL'] 입니다.



[1] 태터 프로그램의 문제

일단 path 방식의 멀티유저로 설치했다고 전제합니다.
blog/index.php 881행을 보면
$url=isset($_SERVER['REDIRECT_URL'])?$_SERVER['REDIRECT_URL']:$_SERVER['SCRIPT_NAME'];
이라는 문장이 있습니다.
여기뿐만 아니라 이런 식의 문장은 태터툴즈 전체에 걸쳐 무려 162군데에나 존재합니다. (함수로 만들어두는게 나을 듯 싶을 정도.)
아무튼 여기서 이 $url을 해석하여 어느 블로그인지를 찾게 되는데요.
원래 개발자가 의도했던 $url 값은 /user/123 처럼 유저명을 포함한 주소일텐데
정작 CGI환경에서는 $_SERVER['REDIRECT_URL']에는 indxe.php, /blog/owner/index.php 따위의 실행파일 주소가 들어가기 때문에
$url을 아무리 해석한다고 해도 원하는 결과를 얻을 수 없습니다.
$url=$_SERVER['REQUEST_URI']; 또는
$url=isset($_SERVER['REDIRECT_QUERY_STRING'])?$_SERVER['REDIRECT_QUERY_STRING']:$_SERVER['QUERY_STRING'];
와 같은 식으로 바꾸어야만 /blog/index.php 가 제대로 작동하게 됩니다.



[2] .htaccess 의 문제

http://도메인/유저명/owner 와 같은 주소를 입력하면
No input file specified. 라는 에러 메시지가 뜹니다.
이 에러메시지는 .htaccess 에서 RedirectRule을 제대로 정의하지 못했다는 것을 의미합니다.

즉 /blog/owner/index.php 를 찾는 대신 /blog/유저명/owner/index.php를 찾으려고 하기 때문에 발생하는 것입니다.
.htaccess 의 맨마지막줄 RedirectRule이 그렇게 정의되어있습니다.



[3] 제안하는 해결책

위의 2가지 문제를 각각 처리한다고 하여, 태터툴즈가 CGI 환경에서 제대로 작동할지는 의문입니다.
자세히 살펴보진 않았지만, URL을 해석하는 부분이 태터 프로그램 곳곳에 있는 듯 하고
그렇다면 각 PHP 페이지에서 $url 을 해석하고 redirect 시키는 것을 일일이 확인해야 할 것이기 때문입니다.

보다 손쉬운 방법은  .htaccess 룰을 단순화시키고, 각 페이지에 들어있는 $url 해석부분을 제거하는 것입니다.
즉 .htaccess 파일 내용으로
  rewriteCond %{REQUEST_FILENAME} !-f
  rewriteCond %{REQUEST_FILENAME} !-d
  rewriteRule ^(.*)$ tt.php?$1 [L,QSA]
이라고만 해두고
tt.php 파일 내에서 $_SERVER['REQUEST_URI']를 해석하게끔 함으로써
.htaccess 가 하던 역할을 tt.php 로 떠넘기는 것입니다.
(그외의 php 페이지에서는 $url을 분석해서 redirect 하는 부분이 필요없겠죠.)

이와 같이 했을때, http://도메인/blog/123 과 같은 주소를 입력할 경우
$_SERVER 환경변수는 다음과 같습니다.
    [REQUEST_URI] => /blog/123
    [QUERY_STRING] => /blog/123
    [REDIRECT_QUERY_STRING] => blog/123
    [REDIRECT_URL] => /tt.php
    [SCRIPT_NAME] => /tt.php
    [SCRIPT_FILENAME] => /실제디렉토리/tt.php
이를 참조하여 tt.php 를 작성하면 될 것 같습니다.

(개발자님께서는 mod_rewrite를 사용하지 말자는 뜻으로 오해하시는거 같던데,
그런 뜻이 아니라 URL 처리 방식의 문제를 지적하는 것입니다.)

더군다나 이렇게 할 경우, mod_rewrite를 사용하지 못하는 경우일지라도
tt.php 대신 index.php 를 사용하면
"/원하는URL" 대신 "/?원하는URL" 과 같은 주소를 사용할 수 있습니다.



[4] IIS의 경우

ISAPI_rewrite (http://www.isapirewrite.com/, 유료버전) 라든가
Ionic’s Isapi Rewrite Filter (http://cheeso.members.winisp.net/dl/Ion … writer.zip)
http://www.qwerksoft.com/products/iisrewrite/
http://www.motobit.com/help/url-replace … ewrite.asp
등의 여러 사이트를 통해
mod_rewrite가 IIS에서 작동하게끔 할 수 있습니다.
위에서 지적한 것과 마찬가지로 태터툴즈 프로그램과 RewriteRule은 변경되어야 할 것입니다.

우수한 (2006-04-19 09:13:05)에 의해 마지막으로 수정

2

답글: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

오랜만에 문제를 다시 살펴봤는데요.
현재 실험본 trunk에 있는 파일을 보니
위에 지적한 것을 반영하여, suri.php를 따로 만들어두셨더군요.
덕분에 프로그램 수정이 좀더 수월해졌네요.
고칠 부분은 다음과 같습니다.

1. suri.php 맨앞부분에 주석으로 넣어두신 부분이 있는데요.
$url = isset($_SERVER['REDIRECT_URL']) ? $_SERVER['REDIRECT_URL'] : $_SERVER['SCRIPT_NAME'];
대신에 그 주석처리한 부분
$url = isset($_SERVER['REQUEST_URI']) ? urldecode($_SERVER['REQUEST_URI']) : $_SERVER['SCRIPT_NAME'];
이 맞는 것 같습니다.

2. 루트에 생성되는 .htaccess 파일을 보면
맨마지막 3줄이 문제가 됩니다. (서버 환경에 따라 정상적으로 작동하지 않는건지...)
가령 맨마지막줄의 경우
RewriteRule ^[[:alnum:]]+/+(.+)$ blog/$1/index.php [E=SURI:1,L]
라고 되어있는데요.
abc/owner/entry 입력 -> blog/owner/entry/index.php 로 이동. 그러나 희한하게도 해당 파일이 없다고 판단함. -> 만약 ,L 옵션을 뺄 경우 owner/entry/index.php/owner/entry 로 이동 -> 진짜로 파일 없음. 에러 발생.
이런 식으로 redirect 가 제대로 작동하지 않는 문제가 있습니다. (이리저리 해보니 어쩌다 되는 경우가 있던데, 좀더 테스트해보고 고쳐쓰겠습니다.)

여하튼 .htaccess 룰은 윗 글에서 말한 것처럼 좀 단순화되었으면 좋겠습니다.

아, 그리고 여담인데 개발하시는 분들은 display_errors=On으로 놓고 작업하시길...

우수한 (2006-05-07 20:16:19)에 의해 마지막으로 수정

3

답글: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

우수한 작성:

rewriteRule ^(.*)$ tt.php?$1 [L,QSA]

이렇게 써놓고 환경변수로 처리하는 것도 괜찮을 것 같군요.
그렇게 할 경우 IIS로 포팅하기도 보다 쉬워질 겁니다.

제가 IIS에서 QSA 옵션에 해당하는 내장 옵션을 켜봤었는데 잘 안 되더군요. 제대로 아시는 분은 도움 주시면 좋겠습니다.

C:\Inetpub\AdminScripts> Cscript.exe adsutil.vbs SET /W3SVC/AllowPathInfoForScriptMappings TRUE

뭐 이런 식으로 했었던 것 같은데.. 잘 안 되더군요.

daybreaker (2006-05-07 19:56:32)에 의해 마지막으로 수정

문제의 답은 우리 안에 있다.
내면에 귀를 기울여 보자.

4

답글: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

우수한 작성:

오랜만에 문제를 다시 살펴봤는데요.
현재 실험본 trunk에 있는 파일을 보니
위에 지적한 것을 반영하여, suri.php를 따로 만들어두셨더군요.
덕분에 프로그램 수정이 좀더 수월해졌네요.

원래 소스본에는 처음부터 분리되어 설계되어 있었습니다.
(배포본과 소스의 차이에 대해서는 게시판 검색을 해 보시면 됩니다 smile )

우수한 작성:

1. suri.php 맨앞부분에 주석으로 넣어두신 부분이 있는데요.
$url = isset($_SERVER['REDIRECT_URL']) ? $_SERVER['REDIRECT_URL'] : $_SERVER['SCRIPT_NAME'];
대신에 그 주석처리한 부분
$url = isset($_SERVER['REQUEST_URI']) ? urldecode($_SERVER['REQUEST_URI']) : $_SERVER['SCRIPT_NAME'];
이 맞는 것 같습니다.

말씀하신 대로 고치면 unix기반의 apache에선 안돌아 가는 경우들이 생깁니다. -
특히 페이지 번호를 선택해서 넘길 때 작동하지 않습니다.

참고해주세요 big_smile

"Everything looks different on the other side."

-Ian Malcomm, from Michael Crichton's 'The Jurassic Park'

5

답글: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

RedirectRule 문제만 어떻게 해결되면 써보겠는데, 쉽지 않네요.
abc/owner 입력 -> blog/owner/index.php로 전환 -> abc/ 위치에서 blog/owner/index.php 를 검색 -> 에러.
이런 수순인 것 같습니다.
php 환경설정 중 cgi.fix_pathinfo, cgi.force_redirect 등의 옵션이랑 관계가 있는건지 잘 모르겠군요.

그리고 $_SERVER['REDIRECT_URL']) 을 $_SERVER['REQUEST_URI'])로 바꾸는 것이
unix기반의 apache에선 안돌아간다는 것은 좀 납득이 되지 않네요.
지금 제가 사용하고 있는 서버가 FreeBSD (unix계열) 이거든요. ^^;
php를 아파치 모듈이 아닌 FastCGI 방식으로 설치했을 뿐이랍니다.

6

답글: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

우수한 작성:

RedirectRule 문제만 어떻게 해결되면 써보겠는데, 쉽지 않네요.
abc/owner 입력 -> blog/owner/index.php로 전환 -> abc/ 위치에서 blog/owner/index.php 를 검색 -> 에러.
이런 수순인 것 같습니다.
php 환경설정 중 cgi.fix_pathinfo, cgi.force_redirect 등의 옵션이랑 관계가 있는건지 잘 모르겠군요.

그리고 $_SERVER['REDIRECT_URL']) 을 $_SERVER['REQUEST_URI'])로 바꾸는 것이
unix기반의 apache에선 안돌아간다는 것은 좀 납득이 되지 않네요.
지금 제가 사용하고 있는 서버가 FreeBSD (unix계열) 이거든요. ^^;
php를 아파치 모듈이 아닌 FastCGI 방식으로 설치했을 뿐이랍니다.

제 주위의 모든 apache모듈을 통한 php 서버에서는 돌아가지 않습니다.
(프비와 데비안 리눅스와 우분투가 있군요.)
전에 commit했을 때에도 페이지 넘김 안된다고 한 번 난리가 났었죠.

그나저나 FastCGI방식은 예전에는 시간이 흐르면 메모리를 추가로 계속 잡아먹는 유명한 버그가 있었는데, 지금은 괜찮아졌나 보네요 smile 그것때문에 안정성이 생명인 저희 분야에서는 쳐다보지도 못했었죠. 기술 참 빨리 발전합니다...

"Everything looks different on the other side."

-Ian Malcomm, from Michael Crichton's 'The Jurassic Park'

7

답글: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

제 서버에 fastCGI와 php모듈 설치해보는 중입니다.
설치 후 결과를 말씀드리겠습니다 smile

"Everything looks different on the other side."

-Ian Malcomm, from Michael Crichton's 'The Jurassic Park'

8

답글: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

페이지가 안넘어가는 문제는 http://www.tattertools.com/ko/forum/vie … d=978#p978 에 해결책을 써놨습니다. smile
다만 다른 문제가 있지 않을까 걱정이군요.;;

9

답글: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

php5를 컴파일해서 cgi로 실행하기... 실패했습니다. ;;;

모듈에 fcgi까지는 띄웠으나 php5 컴파일시 원인모를 에러가 나는군요;;

"Everything looks different on the other side."

-Ian Malcomm, from Michael Crichton's 'The Jurassic Park'

10

답글: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

[1] FastCGI 설치

말씀하신 것처럼 몇년전에는 FastCGI에서 메모리 릭이 발생하는 경우가 있었으나, 지금은 그런 문제가 드물며 특히 php5에 와서는 fastcgi 라이브러리의 수정본을 내포하고 있는 것으로 압니다.

제 경우에는 kldp.org 설명과 달리 FreeBSD 포트에 있는 것으로 설치했구요. php5 포트에서 make WITH_REDIRECT=yes WITH_DISCARD=yes WITH_FASTCGI=yes WITH_PATHINFO=yes install 해주는 것으로 끝나기 때문에 컴파일하는데서 에러가 발생하지는 않았습니다.
php를 컴파일할때 아파치용 옵션인 –with-apxs, –with-apxs2 옵션은 제거되어야 하고, –enable-fastcgi –enable-discard-path –enable-force-cgi-redirect 옵션이 추가되어야 하는 것으로 압니다.

제 경우에는 php 컴파일 이후 apache와 결합해 php-fastcgi 데몬을 띄우는 부분에서 조금 애를 먹었던 기억이 있습니다. (어설프게나마 제가 메모해둔 문서는 http://jaju.net/wiki/httpd/fastcgi_php, http://jaju.net/wiki/php/fastcgi 에 있으니 참고해보세요.)

[2] REQUEST_URI vs REDIRECT_URL

페이지가 넘어가지 않는 문제 등 일부에서 작동하지 않는 문제가 정확히 어떤 문제인지 살펴보지 않았습니다만,
만일 서버 환경에 따라 REDIRECT_URL이 각기 다르게 나타나는 것이라면
그것이 사용자로부터 입력받은 URI인지 아니면 RewriteRule을 거쳐 바뀐 URI 인지를 규명해야겠군요.
(CGI 1.1 스펙에서 QUERY_STRING, SCRIPT_NAME 만 지원하므로 SCRIPT_NAME 을 써야하는지도... neutral)
아울러 URL을 인코딩, 디코딩하는 부분 역시 일관성있게 (suri.php를 만들어서 함수화한 것과 마찬가지로) 처리해야 하지 않나 싶네요.

우수한 (2006-05-09 10:32:11)에 의해 마지막으로 수정

11

답글: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

요즘 버전업이 뜸하네요. Apache2+FastCGI 설치가 어렵다면,
lighttpd 또는 LiteSpeed 웹서버를 설치해보시는건 어떨지요?
LiteSpeed는 WordPress.org에서도 추천하는 웹서버죠. (http://www.litespeedtech.com)
standard 버전 다운 받아서 그냥 시키는대로만 설치하면 LSAPI 모듈 형태의 PHP4가 같이 설치되더군요.
(PHP5를 쓰려면 LSAPI 모듈로 새로 컴파일해야 합니다.)
이 LSAPI라는 놈은 사실상 FastCGI와 똑같습니다.

그후 태터툴즈 설치해보시면, 태터 프로그램의 URL 처리의 문제점과
"Apache + mod_php 라는게 특수한(!) 환경이구나" 하는 것을 느끼실 수 있을 것입니다.
위에 말씀드린대로 suri.php 에서 REDIRECT_URL 대신 QUERY_STRING 이나 REQUEST_URI 를 사용하면 상당부분 해결됩니다.
그리고 domain.comi/ID/owner 같은 주소를 처리하는 문제만 해결하면 될 것 같네요.



----
사족인데요.
태터 설치법에 보면 chmod 777 을 해라는 이야기가 많습니다.
초보자를 위해 이렇게 한다고 쳐도.... 전문가를 위한 설치법을 따로 준비해주시는게 좋겠어요.
chmod 777은 안전하니 않으니 attach 등의 디렉토리를 웹상에서 접근할 수 없는 곳에 만들고
웹서버가 쓸 수 있는 권한을 주라(chown www attach)는 등의 설명문 말이죠.

아직 태터를 한번도 사용해보지 못했는데, 벌써 '익숙한 사용자'가 되어버렸군요. ;-)

우수한 (2006-06-03 17:32:04)에 의해 마지막으로 수정

12

답글: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

전부 rewrite.php를 만들어서 받도록 해 봤는데 의외로 골치아픈 부분들이 있습니다. register_global 옵션이 보안상의 문제로 off이기 때문에 모든 입출력이 rewrite.php를 거칠 때 모든 POST와 GET문을 복사해서 넘겨 줘야 하는데, 의외로 로드가 있네요. (갯수제한 없이 while문 돌려주면 사뿐하게 DDoS도 가능해 보입니당)

그 이외에도 php 파서가 손 댈 필요가 없는 파일들도 (그림이라거나) 전부 한 번씩 파싱되기 때문에, 서버의 CPU가 매우 괴로워합니다. 아무래도 .htaccess를 고치는 방향으로 가야 할 듯...

덧) rewrite engine disabled mode에서는 fcgi에서 잘 돌아가는군요^^

"Everything looks different on the other side."

-Ian Malcomm, from Michael Crichton's 'The Jurassic Park'

13

답글: [URL Rewrite관련] CGI 환경을 지원하지 못하는 문제

이 부분을 해결했습니다. 오늘자 trunk에 반영되었습니다.

mod_rewrite 의존도를 최소한으로 줄이고, 걍 전부 서버 인자를 통해서 파싱하도록 했습니다. 주소 해석 루틴의 호환성은 그대로 남겨 놓고 mod_rewrite가 넘겨주는 서버 인자 값을 처리하는 wrapper를 하나 얹었습니다.

아마 이제 mod_rewrite를 사용만 할 수 있는 곳이면 fastCGI든 아니든 잘 돌아 갈겁니다. r4864 이후의 리비전에서 안정적으로 동작합니다. 제 서버를 아예 fastCGI 기반으로 엎은 후에 블로그를 돌리고 있는데, 잘 돌아가는군요. smile

"Everything looks different on the other side."

-Ian Malcomm, from Michael Crichton's 'The Jurassic Park'