[첫화면으로]UseModWiki소스수정/UTF-8로인코딩된쿼리처리

마지막으로 [b]

1. UTF-8로 인코딩된 쿼리 처리
1.1. 사용법
1.2. 문제점
1.3. wiki.pl 수정
1.3.1. wiki.pl?페이지이름 의 경우
1.3.2. wiki.pl?action=액션&id=페이지이름 의 경우
1.4. 추가 업데이트 내역
1.5. 사용자 의견

1. UTF-8로 인코딩된 쿼리 처리

http://사이트이름/디렉토리이름/wiki.pl?페이지이름 형식의 URL에서, "페이지이름" 부분이 한글이고, UTF-8로 인코딩되어 서버로 날아오면 제대로 처리하지 못하고 잘못된 페이지 이름으로 판단하게 된다.

이런 경우에 적절히 처리를 할 수 있게 해 보자.

("사이트이름", "디렉토리이름", 또는 심지어 "wiki.pl" 부분이 한글인 경우는? 그건 웹서버에서 신경쓸 문제다. 여기서는 오직 "?"뒤의 쿼리 스트링만 다루자)

1.1. 사용법

1.2. 문제점

안타깝게도, IE 6.0 (그리고 아마도 7.0에도)에서는 "?"뒤에 있는 쿼리를 UTF-8로 인코딩할 때 버그가 있어서1, 어쨌거나 UTF-8로 URL이 넘어오면 처리하지 못한다.

따라서 이 패치는 Firefox2 등 다른 브라우저를 사용하여, UTF-8로 URL을 요청했을 때3 페이지가 안 보이던 걸 보이게 해 주는 정도.

구현에 따르는 문제점은 아래 해당되는 코드에서 얘기함.

1.3. wiki.pl 수정

1.3.1. wiki.pl?페이지이름 의 경우

여기만 수정하면 될 듯:
sub DoBrowseRequest {
...
    if ($id) {                    # Just script?PageName
        if ($FreeLinks && (!-f &GetPageFile($id))) {
            $id = &FreeToNormal($id);
        }
### QUERY_STRING 이 utf-8로 들어온 경우
        if (&ValidId($id) ne "") {
            my $converted_id = encode_korean($id, 'utf-8', "$HttpCharset");
            if (&ValidId($converted_id) eq "") {
                $id = $converted_id;
            }
        }
##### 여기까지

        if (($NotFoundPg ne '') && (!-f &GetPageFile($id))) {
            $id = $NotFoundPg;
        }
        $DocID = $id;
        &BrowsePage($id)  if &ValidIdOrDie($id);
        return 1;
    }

위 코드를 보면 wiki.pl? 뒤에 페이지이름이 올 경우
  1. 페이지 파일이 없으면 일단 FreeToNormal()을 거쳐서 공백을 "_"로 바꾸는 등의 처리를 함
  2. (이 패치에서 추가한 코드) 페이지이름이 valid 한지 검사를 해서 아니라면, UTF-8이 아닐까 의심하고 EUC-KR로 변환하여 다시 검사. 만일 valid하다면, 그걸 $id값으로 할당.
  3. 여전히 페이지 파일이 없으면 이번에는 $NotFoundPg 변수에 들어있는 페이지 이름을 $id값으로 사용.
  4. 그 $id를 가지고 처리...

즉, "UTF-8 인코딩되어 들어온 스트링은 반드시 invalid할 것이다"라고 가정했다. 설마 UTF-8인데도 절묘하게 코드값이 EUC-KR로도 매치가 되어서 valid 판정을 받는 - 그 경우 유저가 원한 페이지 이름과는 다른 이름이겠지 - 경우가 있을까?

1.3.2. wiki.pl?action=액션&id=페이지이름 의 경우

이게 진짜 난감한데, 일단 다음과 같이 수정한다. 위의 수정에서 몇 줄만 아래로 내려와서 추가:

sub DoBrowseRequest {
....
        &BrowsePage($id)  if &ValidIdOrDie($id);
        return 1;
    }
    $action = lc(&GetParam('action', ''));
    $id = &GetParam('id', '');
### QUERY_STRING 이 utf-8로 들어온 경우
        if (&ValidId($id) ne "") {
            my $converted_id = encode_korean($id, 'utf-8', "$HttpCharset");
            if (&ValidId($converted_id) eq "") {
                $id = $converted_id;
                $q->param('id', $converted_id);
            }
        }
##### 여기까지

    $DocID = $id;
    if ($action eq 'browse') {
...
}

아까하고 동일한데, 이번에는 $id 변수의 값을 바꿔치는 것 뿐 아니라, "$q->param('id', $converted_id);"를 통해서 아예 CGI 파라메터값 자체를 바꿔치기하였다. 따라서 이하 각종 action 함수 등에서 다시 GetParam('id') 등을 통해서 id 파라메터 값을 얻어올 때 바뀐 값을 얻어 온다. (솔직히 말하면, 확신은 없지만 그럴 거라 생각한다)

여기서 단점은, wiki.pl? 뒤에 "이름=값" 형식으로 올 수 있는 파라메터는 무한히 많은데 그걸 다 처리할 수 없기 때문에, 오직 "id"라는 이름의 파라메터를 만지고 있다는 점이다.

테스트해보면, 대표적으로 "action=browse&id=페이지이름"과 "action=history&id=페이지이름"은 $id 값을 바꿔친 것으로 제대로 동작하고, "action=edit&id=페이지이름"은 파라메터를 바꿔친 것으로 제대로 동작한다.

외부에서 유즈모드를 링크할 때 그 외의 액션을 링크할 일은 거의 없으리라 생각함. (사실 거의 대부분은 단순히 "wiki.pl?페이지이름"의 형태가 아닐런지)

1.4. 추가 업데이트 내역

ext2 버전이 되면서 UTF-8이전작업/브라우저GET요청인코딩판별을 대신 사용한다.

1.5. 사용자 의견

뭐 큰 문제 없어 보이니까 일단 이걸로 반영.
-- Raymundo 2007-2-4 2:06 pm
이름:  
Homepage:
내용:
 

위키위키분류
각주:
1. 유니코드논의/파일명인코딩, [MS IE 6 and 7 beta 2 encoding bugs in URL's query part]
2. Firefox의 경우는, 주소창에 about:config를 입력하면 상세하게 설정을 바꿀 수 있는데, network.standard-url.encde-utf8 옵션의 기본값이 false라서 OS의 기본 인코딩에 맞춰서 보낸다고 함. 따라서 한글 윈도우즈에서는 EUC-KR로 보낼 것임
3. Firefox의 network.standard-url.encde-utf8 설정이 true이거나, UTF-8로 인코딩된 티스토리 블로그 포스트에서 유즈모드위키 페이지로 링크가 걸린 경우 등

마지막 편집일: 2007-3-9 5:50 pm (변경사항 [d])
906 hits | Permalink | 변경내역 보기 [h] | 페이지 소스 보기