2011-07-28 4 views
1

Varnish (3.0)에서 URL은 대소 문자를 구분하여 처리합니다. 즉, http://test.com/user/a4556http://test.com/user/A4556과 다르게 취급됩니다. 내 웹 서버에서는 동일한 URL로 취급됩니다. 내가 무엇을하고 싶은지 와서 들어오는 모든 요청 URL을 소문자로 바꿔야합니다.바니시의 소문자 URL (인라인 C)

this discussion을 찾을 수 있었지만 Varnish의 작성자는 인라인 C를 사용하여이를 수행해야 함을 나타냅니다. 나는 이것을 여러 가지 정규식을 사용하는 단순한 방법으로 달성 할 수는 있지만, 실패 할 것 같아 보인다.

이상적으로는, 내가 원하는 것은 (이 예는 found here를 할 수 있습니다)하지만 난 const char *에 소요 const char *를 반환하는 C 함수에 대한 정착 줄이 할 수있는 VCL 구성입니다 (내가 아닌거야 C 프로그래머가 구문을 잘못 이해하면 용서해주십시오.)

답변

1

이 바니시 성병 VMOD의 능력 대문자와 소문자 문자열을 포함하는 것으로 언급되어야한다 (https://www.varnish-cache.org/docs/trunk/reference/vmod_std.generated.html#func-tolower)

이것은 임베디드 C 경로보다 훨씬 깔끔합니다 (기본적으로 Varnish 4에서는 비활성화 됨). 다음은 요청 호스트 및 URL을 정규화하는 데 사용하는 예입니다.

import std; 

    sub vcl_recv { 

     # normalize Host header 
     set req.http.Host = std.tolower(regsub(req.http.Host, ":[0-9]+", "")); 
     .... 

    } 

    sub vcl_hash { 
     # set cache key to lowercased req.url 
     hash_data(std.tolower(req.url)); 
     .... 
    } 
+0

이것은 Varnish 4.0에서만 사용할 수 있다고 생각했지만 v3.0 (https://www.varnish-cache.org/docs/3.0/reference/vmod_std.html#tolower)에있는 것 같습니다. 내가 그걸 알았 으면 좋겠어. –

+1

Enter 키를 누르 자마자 Firefox 44와 Chrome 48 둘 다 호스트 요청 헤더를 소문자로 표시합니다. 호스트의 tolower()가 더 이상 필요하지 않다는 것을 완전히 확신하지 못합니다. 나는 그것이 상처를주지 않는다고 생각한다. –

+0

Varnish docs는 호스트가 작은 브라우저를 확인합니다. "Varnish는"Varnish.org/ "및"varnish.org/ "를 사용하면 캐시 항목이 달라지기 때문에 해시하기 전에 바니시가 호스트 이름이나 URL을 소문자로 처리하지 않는 것이 좋습니다. 그러나 브라우저는 소문자를 사용하는 경향이 있습니다 호스트 이름. " - https://www.varnish-cache.org/docs/trunk/users-guide/vcl-hashing.html –

0

는 소문자로 대문자 문자열을 변환하는 C 함수를 찾고 있다면,이 할 것입니다 :이 현재 위치에서 문자열을 수정하게

#include <ctype.h> 

static char * 
to_lower (char *str) 
{ 
    char *s = str; 

    while (*s) 
    { 
     if (isupper (*s)) 
     *s = tolower (*s); 
     s++; 
    } 
    return str; 
} 

참고. 따라서 원래 문자열의 복사본을 인수로 전달할 수 있습니다.

+0

내가 to_lower ''에 대한 충돌 유형 '의 오류'나는 프로토 타입의 콘솔 응용 프로그램에 넣을 때. 함수 이름을 sto_lower로 변경하면 'sto_lower'에 대한 충돌 유형이 발생합니다. –

2

좋아, 나는 앞장서 ​​서 나 자신을 위해이 문제를 해결했다. 다음은 VCL입니다.

C{ 
    #include <ctype.h> 
    //lovingly lifted from: 
    //https://github.com/cosimo/varnish-accept-language/blob/master/examples/accept-language.vcl 
    static void strtolower(const char *s) { 
     register char *c; 
     for (c=s; *c; c++) { 
      if (isupper(*c)) { 
       *c = tolower(*c); 
      } 
     } 
     return; 
    } 
}C 

sub vcl_recv { 
    C{ 
     strtolower(VRT_r_req_url(sp)); 
    }C 
} 

별도의 VCL 파일에이 파일을 넣은 다음 include를 추가했습니다.

2

리차드의 코드를 완전한 솔루션으로 확장하는 솔루션 만 공유합니다.

URL에 대문자가 포함되어있는 경우 캐시 기계에 들어가기 전에 URL을 정규화하는 대신 사용자를 올바른 URL로 리디렉션합니다. 이렇게하면 검색 엔진이 대소 문자가 혼용 된 URL을 소문자로 구분할 수 없습니다. 하지에 우리에게 말하고 니스에도 불구하고 기본적으로, 우리는 현재 위치에서 문자열을 수정하고 ... 소문자를하는 req.url을 변환 할 때

# Define a function that converts a string to lower-case in-place. 
# http://stackoverflow.com/questions/6857445 
C{ 
    #include <ctype.h> 

    static void strtolower(char *c) { 
     for (; *c; c++) { 
      if (isupper(*c)) { 
       *c = tolower(*c); 
      } 
     } 
    } 
}C 

sub vcl_recv { 
    if (req.http.host ~ "[A-Z]" || req.url ~ "[A-Z]") { 
     # Convert host and path to lowercase in-place. 
     C{ 
      strtolower(VRT_GetHdr(sp, HDR_REQ, "\005host:")); 
      strtolower((char *)VRT_r_req_url(sp)); 
     }C 
     # Use req.http.location as a scratch register; any header will do. 
     set req.http.location = "http://" req.http.host req.url; 
     error 999 req.http.location; 
    } 

    # Fall-through to default 
} 

sub vcl_error { 
    # Check for redirects - redirects are performed using: error 999 "http://target-url/" 
    # Thus we piggyback the redirect target in the error response variable. 
    if (obj.status == 999) { 
     set obj.http.location = obj.response; 
     set obj.status = 301; 
     set obj.response = "Moved permanently"; 
     return(deliver); 
    } 

    # Fall-through to default 
} 

const char *에서 char *에 못생긴 캐스트있다. 작동하는 것 같습니다. 도 :-) C 블록의 URL을 설정하고 않도록 충돌 사용하는

0

참고

VRT_l_req_url(sp,"new-string", vrt_magic_string_end); 

여기 안된 수요일 수정이다. ("varnishd -C"출력으로부터 본 세부 뽑아)를 행 제 않음 :

C{ 
    #include <ctype.h> 
    //lovingly lifted from: 
    //https://github.com/cosimo/varnish-accept-language/blob/master/examples/accept-language.vcl 
    static void strtolower(const char *s) { 
     register char *c; 
     for (c=s; *c; c++) { 
      if (isupper(*c)) { 
       *c = tolower(*c); 
      } 
     } 
     return; 
    } 
}C 

sub vcl_recv { 
    C{ 
     const char *url = VRT_r_req_url(sp); 
     char urlRewritten[1000]; 
     strcat(urlRewritten, url); 
     strtolower(urlRewritten); 
     VRT_l_req_url(sp, urlRewritten, vrt_magic_string_end); 
    }C 
} 
+0

충돌을 피하십시오, 응? 요청이 1000 자 URL로 수신되면 어떻게됩니까? :) –

2

원래 질문이 나온 지 거의 5 년이 지난 지금 거의 깨끗한 답을 얻을 수 있습니다. 이 SO 질문은 여전히 ​​"소문자 바니시"에 대한 검색에서 계속됩니다.여기

는 Fastly 권장 예에 대한 단순화 된 변형 :

# at the top of your VCL 
import std; 

sub vcl_recv { 
    # Lowercase all incoming URLs. It will also be lowercase by the time the hash is computed. 
    set req.url = std.tolower(req.url); 
} 

https://www.fastly.com/blog/varnish-tip-case-insensitivity