2

Varnish (3.0)では、URL は大文字と小文字を区別して処理されます。つまり、http://test.com/user/a4556は とは異なる扱いを受けhttp://test.com/user/A4556ます。私の Web サーバーでは、それらは同じ URL として扱われます。私がやりたいのは、着信時にすべてのリクエスト URL を小文字にすることです。

私はなんとかこの議論を見つけましたが、Varnish の作成者は、それを行うにはインライン C を使用する必要があることを示しています。複数の正規表現を使用して単純な方法でこれを実現できますが、それは失敗するに決まっているようです。

理想的には、これを行うための VCL 構成が必要です (この例はここconst char *にあります) const char *。構文が間違っている場合)。

4

6 に答える 6

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
}

小文字に変換するときにfrom const char *toという醜いキャストがあります。うまくいくようです。:-)char *req.url

于 2011-08-30T14:22:14.410 に答える
2

Varnish には、std 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));
      ....
    }
于 2014-09-30T08:46:07.870 に答える
2

最初の質問が出されてから 5 年近く経ちましたが、今ではより明確な回答が得られていると思います。この SO の質問は、「lowercase Varnish」の検索で依然として上位に表示されます。

以下は、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

于 2016-02-26T03:09:29.953 に答える
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 ファイルに入れ、インクルードを追加しました。

于 2011-07-29T10:28:05.363 に答える
0

CブロックからURLを設定し、クラッシュを回避するには、次の点に注意してください。

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
}
于 2011-10-17T19:59:10.783 に答える
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;
}

これにより、文字列がその場で変更されることに注意してください。そのため、元の文字列のコピーを引数として渡したい場合があります。

于 2011-07-28T11:21:28.857 に答える