2011-07-28 14 views
1

Varnish(3.0)のURLは大文字と小文字を区別して扱われます。これによって、http://test.com/user/a4556http://test.com/user/A4556とは異なった扱いになります。私のウェブサーバーでは、彼らは同じURLとして扱われます。ワニスの小文字のURL(インラインC)

this discussionが見つかりましたが、ワニスの作成者は、インラインでCを使用しなければならないことを示しています。私はこれを単純な方法で複数の正規表現を使って実現することができましたが、失敗する可能性が高いようです。

は、理想的には、どのような私がしたいことはこれを行うためのVCLの構成です(この例は、found hereすることができます)が、私はconst char *に取り、const char *を返すC関数のために解決したい(私はしませんよ私は文法が間違っている場合、Cプログラマは私を許してください)。

答えて

1

ニスがSTDのVMODで大文字能力と小文字の文字列が含まれていることを言及しなければならない(https://www.varnish-cache.org/docs/trunk/reference/vmod_std.generated.html#func-tolower

これは、埋め込まれたCルートよりもはるかにクリーンです(ワニス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.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

:ここ

はしっかりと推奨しています例の簡素化バリエーションです。関数名を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ファイルに入れて、それにインクルードを追加しました。

2

リチャードのコードを完全なソリューションに拡張する私のソリューションを共有します。

URLに大文字が含まれている場合、キャッシュ機構に入る前にURLを正規化するのではなく、正しいURLにユーザーをリダイレクトします。これにより、検索エンジンが大文字と小文字の区別された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 
} 

-小文字にreq.urlを変換する際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の質問はまだ "小文字のワニス"の検索で一番上に来る。私はプロトタイプのコンソールアプリケーションでそれを置くto_lower「『のための競合タイプ』」のエラーが出ます

# 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

関連する問題