이 주제에 대해 다시 언급하여 제가 발견한 몇 가지 함정을 짚어보고, 향후 이 문제를 마주할 분들을 위해 몇 가지 단서를 남겨두고자 합니다. 이 문제를 디버깅하는 것이 정말로 어려웠기 때문입니다.
영구 링크 정규화 문자열에서의 이스케이프 처리
영구 링크 정규화 문자열의 형식은 두 가지 구성 요소로 나뉩니다.
- 정규식(Regular Expression) 문자열
- 대체(Replacement) 문자열
이들은 영구 링크 정규화 문자열 내에서 다음과 같이 바로 이어 붙어 있습니다.
Permalink Normalization
Regular Expression Replacement
<-------------------------><------------->
/(this)reallyis(intuitive)/\1reallyisn't\2
중요한 점은, 동일한 문자열 내에서도 슬래시가 각 부분에서 다르게 처리된다는 것입니다.
정규식 부분의 문자열에서 슬래시(그리고 기타 정규식 특수 문자)는 반드시 이스케이프 처리되어야 하지만, 동일한 문자열의 대체 부분에서는 슬래시를 이스케이프 처리할 필요가 없으며, 이는 문자 그대로(literally) 처리됩니다.
수신되는 URL 문자열의 형식
둘째로, 이 부분은 파악하는 데 시간이 좀 걸렸는데, URL은 루트 기준 상대 경로 설명으로 일치시키지만, 문자열의 첫 부분으로 /를 받지 않습니다.
예를 들어, 기존 포럼에서 사용하던 URL이 다음과 같다면…
http://oldforum.com/chat/the-topic-title/post/d9aa09c3-19bd-4c6e-9d8d-a8f1008000a1
…영구 링크 정규화에서 정규식이 일치시킬 URL은 다음과 같이 보일 것입니다…
chat/topic-title/post/d9aa09c3-19bd-4c6e-9d8d-a8f1008000a1
즉, 루트 기준 경로 설명이지만 앞선 / 슬래시가 없는 형태입니다. (리다이렉트하는 URL의 구조에 따라 다를 수 있다고 추측하지만, 그렇지 않을 것 같습니다.)
예시
마이그레이션 프로젝트에서 가져온 몇 가지 예시입니다.
CATEGORY_LINK_NORMALIZATION = '/(cat)\/(.*?)([#\?].*)?$/cat/\2'
POST_LINK_NORMALIZATION = '/chat\/(.*?)\/(post)\/(.+?)([#\?].*)?$/post/\3'
TOPIC_LINK_NORMALIZATION = '/(chat)\/(.*?)([#\?].*)?$/topic/\2'
처리 과정
기존 URL은 말 그대로 기존 시스템에서 해당 항목의 URL을 의미합니다.
영구 링크 정규화(permalink_normalizations 시스템 설정에 기록됨)는 수신되는 URL(앞선 슬래시 / 제외)을 가져와 정규식 매칭을 적용합니다. 그 결과 생성된 정규화된 URL은 /admin/customize/permalinks 화면에 입력된 URL 일치 텍스트와 일치시키기 위해 사용됩니다.