Строчные URL-адреса в лаке - PullRequest
1 голос
/ 28 июля 2011

В Лак (3.0), URL обрабатываются с учетом регистра. Я имею в виду, что http://test.com/user/a4556 трактуется иначе, чем http://test.com/user/A4556. На моем веб-сервере они обрабатываются как один и тот же URL. То, что я хотел бы сделать, это иметь лакированную строчную букву для всех URL-адресов запросов по мере их поступления.

Мне удалось найти это обсуждение , но создатель Varnish указывает, что мне придется использовать встроенный C, чтобы сделать это. Я мог бы добиться этого в упрощенном виде, используя несколько регулярных выражений, но это только кажется, что он обязательно потерпит неудачу.

В идеале, для этого мне нужна конфигурация VCL (пример этого может быть найден здесь ), но я бы согласился на функцию C, которая принимает const char * и возвращает const char * (я не программист на C, так что простите, если я неправильно понял синтаксис).

Ответы [ 6 ]

2 голосов
/ 26 февраля 2016

Спустя почти 5 лет после того, как был задан первоначальный вопрос, я думаю, что у нас теперь есть более четкий ответ. Этот ТАК вопрос все еще занимает первое место в поиске «Строчный лак».

Вот упрощенный вариант примера, который 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

2 голосов
/ 30 августа 2011

Я просто поделюсь своим решением, которое расширяет код Ричарда в полное решение.

Если 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 * ...мы модифицируем строку на месте, несмотря на то, что Varnish говорит нам не делать этого.Вроде работает.: -)

2 голосов
/ 29 июля 2011

Хорошо, я решил и решил это для себя.Вот 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, а затем добавил для него включение.

1 голос
/ 30 сентября 2014

Следует отметить, что Varnish включает в себя возможность ввода строчных и прописных строк в std vmod (https://www.varnish -cache.org / docs / trunk / reference / vmod_std.generated.html # func-tolower )

Это намного чище, чем встроенный маршрут C (который по умолчанию отключен в Varnish 4).Вот пример, который я использую для нормализации запроса Host и 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 голосов
/ 17 октября 2011

Обратите внимание, что для установки URL из блока C и избегайте сбоев используйте:

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 голосов
/ 28 июля 2011

Если вы ищете функцию C, которая преобразует строку в верхнем регистре в нижний регистр, это будет делать:

#include <ctype.h>

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

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

Обратите внимание, что это изменяет строку на месте.Поэтому вы можете передать копию исходной строки в качестве аргумента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...