Uzyskaj subdomenę z adresu URL


102

Uzyskanie subdomeny z adresu URL wydaje się na początku łatwe.

http://www.domain.example

Przeskanuj pierwszy okres, a następnie zwróć to, co pojawiło się po „http: //” ...

Wtedy sobie przypominasz

http://super.duper.domain.example

O. Więc myślisz: ok, znajdź ostatnią kropkę, cofnij słowo i zbierz wszystko wcześniej!

Wtedy sobie przypominasz

http://super.duper.domain.co.uk

I wróciłeś do punktu wyjścia. Czy ktoś ma jakieś świetne pomysły poza przechowywaniem listy wszystkich domen najwyższego poziomu?


To pytanie zostało już tutaj zadane: Pobieranie części adresu URL Edycja: Podobne pytanie zadano tutaj
:)

Cam, wyjaśniasz, czego chcesz? Wygląda na to, że szukasz „oficjalnej” domeny adresu URL (np. Domena.co.uk), niezależnie od tego, ile etykiet DNS występuje przed nią?
Alnitak

Nie wydaje mi się, że to to samo pytanie - wydaje się, że chodzi bardziej o cięcia administracyjne w nazwie domeny, których nie można rozwiązać po prostu patrząc na ciąg
Alnitak

Zgadzam się. Dowiedz się więcej o swoim celu końcowym.
BuddyJoe

Odpowiedzi:


74

Czy ktoś ma jakieś świetne pomysły poza przechowywaniem listy wszystkich domen najwyższego poziomu?

Nie, ponieważ każda TLD różni się tym, co liczy się jako subdomena, domena drugiego poziomu itp.

Pamiętaj, że istnieją domeny najwyższego poziomu, domeny drugiego poziomu i subdomeny. Technicznie rzecz biorąc, wszystko oprócz TLD jest subdomeną.

W przykładzie domena.com.uk „domena” to subdomena, „com” to domena drugiego poziomu, a „uk” to TLD.

Pytanie pozostaje więc bardziej złożone niż na pierwszy rzut oka i zależy od tego, jak zarządzana jest każda TLD. Będziesz potrzebować bazy danych wszystkich domen TLD, które obejmują ich określone partycjonowanie, oraz tego, co liczy się jako domena drugiego poziomu i subdomena. Nie ma jednak zbyt wielu domen najwyższego poziomu, więc lista jest rozsądnie zarządzana, ale zebranie wszystkich tych informacji nie jest trywialne. Taka lista może już być dostępna.

Wygląda na to, że http://publicsuffix.org/ jest jedną z takich list - wszystkie popularne sufiksy (.com, .co.uk itp.) Na liście nadającej się do wyszukiwania. Nadal nie będzie łatwo go przeanalizować, ale przynajmniej nie musisz utrzymywać listy.

„Publiczny przyrostek” to taki, pod którym użytkownicy Internetu mogą bezpośrednio rejestrować nazwy. Niektóre przykłady publicznych sufiksów to „.com”, „.co.uk” i „pvt.k12.wy.us”. Lista publicznych sufiksów to lista wszystkich znanych publicznych sufiksów.

Lista Sufiksów Publicznych jest inicjatywą Fundacji Mozilla. Jest dostępny do użytku w dowolnym oprogramowaniu, ale pierwotnie został stworzony, aby zaspokoić potrzeby producentów przeglądarek. Pozwala przeglądarkom na przykład:

  • Unikaj ustawiania szkodliwych dla prywatności „supercookies” dla sufiksów nazw domen wysokiego poziomu
  • Podświetl najważniejszą część nazwy domeny w interfejsie użytkownika
  • Dokładnie sortuj wpisy historii według witryny

Przeglądając listę , widać, że nie jest to trywialny problem. Myślę, że lista to jedyny właściwy sposób na osiągnięcie tego ...


Mozilla ma kod, który korzysta z tej usługi. Projekt został odrzucony, ponieważ oryginalna specyfikacja plików cookie łączyła domeny TLD, aby ufać plikom cookie, ale nigdy nie działała. Błąd „Cookie Monster” był pierwszym problemem, a architektura nigdy nie została naprawiona ani wymieniona.
benc

Preferowanego języka do rozwiązania tego problemu nie ma na liście, ale istnieje projekt open source, który używa tej listy w kodzie C # tutaj: code.google.com/p/domainname-parser
Dan Esparza

To, czy domena jest „publicznym sufiksem”, czy też nie, powinno być udostępniane za pośrednictwem samego protokołu DNS, być może za pośrednictwem flagi EDNS. W takim przypadku właściciel może to ustawić i nie ma potrzeby prowadzenia oddzielnej listy.
Pieter Ennes

@PieterEnnes EDNS jest przeznaczony dla flag „związanych z transportem” i nie można go używać do metadanych związanych z treścią. Zgadzam się, że te informacje najlepiej umieścić w samym DNS. ISTR planuje zorganizowanie „sesji BoF” na zbliżającym się IETF w Vancouver, aby to omówić.
Alnitak

Dzięki (+1) za link do http://publicsuffix.org, opublikowałem kilka funkcji powłoki i bash w oparciu o Twoją odpowiedź: stackoverflow.com/a/63761712/1765658
F. Hauri

26

Jak mówi Adam, nie jest to łatwe, a obecnie jedynym praktycznym sposobem jest użycie listy.

Nawet wtedy są wyjątki - na przykład .ukistnieje kilka domen, które są ważne od razu na tym poziomie, a które nie są.co.uk , więc należy je dodać jako wyjątki.

Tak obecnie robią to popularne przeglądarki - konieczne jest upewnienie się, że example.co.uknie mogą ustawić pliku cookie, .co.ukktóry byłby następnie wysyłany do dowolnej innej witryny pod adresem .co.uk.

Dobra wiadomość jest taka, że ​​jest już dostępna lista pod adresem http://publicsuffix.org/ .

Jest też trochę pracy w IETF stworzeniem pewnego rodzaju standardu umożliwiającego TLD deklarowanie, jak wygląda struktura ich domeny. Jest to nieco skomplikowane przez tego typu .uk.com, który działa tak, jakby był publicznym sufiksem, ale nie jest sprzedawany przez .comrejestr.


1
Eugh, IETF powinien wiedzieć lepiej, niż pozwolić na śmierć swoich adresów URL. Wersja robocza (ostatnia aktualizacja we wrześniu 2012 r.) Jest teraz dostępna tutaj: tools.ietf.org/html/draft-pettersen-subtld-structure
IMSoP

Grupa robocza IETF zajmująca się tym tematem (DBOUND) została zamknięta.
Patrick Mevzek,

Zauważ, że odkąd to napisałem, .ukrejestr domen pozwala teraz na rejestrację bezpośrednio na drugim poziomie. Znajduje to odpowiednie odzwierciedlenie w PSL.
Alnitak,

22

Wydaje się, że Publicsuffix.org jest właściwą drogą. Istnieje wiele implementacji, które pozwalają łatwo przeanalizować zawartość pliku danych publicsuffix:


2
Ale pamiętaj, że to nie tylko kwestia analizy! Ta lista na Publicsuffix.org jest nieoficjalnym projektem, który jest niekompletny (na przykład brakuje eu.org), NIE odzwierciedla automatycznie zasad TLD i może w każdej chwili nie zostać utrzymany.
bortzmeyer


7
Lista na publicsuffix.org nie jest „nieoficjalna” bardziej niż cokolwiek innego, co robi Mozilla. Biorąc pod uwagę, że używają go Mozilla, Opera i Chrome, jest mało prawdopodobne, że zostanie on zaniedbany. Jeśli chodzi o niekompletność, każdy operator domeny, takiej jak eu.org, może ubiegać się o włączenie, jeśli chce, i rozumie konsekwencje takiego działania. Jeśli chcesz dodać domenę, poproś właściciela o złożenie wniosku. Tak, nie odzwierciedla automatycznie zasad dotyczących TLD, ale nic tak nie jest - nie ma programowego źródła tych informacji.
Gervase Markham

dagger / android: okhttp da ci topPrivateDomain
bladerunner

9

Jak już powiedzieli Adam i John publicsuffix.org jest właściwą drogą. Ale jeśli z jakiegoś powodu nie możesz użyć tego podejścia, oto heurystyka oparta na założeniu, które działa dla 99% wszystkich domen:

Jest jedna właściwość, która odróżnia (nie wszystkie, ale prawie wszystkie) „prawdziwe” domeny od subdomen i TLD, a jest nią rekord MX DNS. Możesz stworzyć algorytm, który wyszukuje to: Usuń części nazwy hosta jeden po drugim i odpytuj DNS, aż znajdziesz rekord MX. Przykład:

super.duper.domain.co.uk => no MX record, proceed
duper.domain.co.uk       => no MX record, proceed
domain.co.uk             => MX record found! assume that's the domain

Oto przykład w php:

function getDomainWithMX($url) {
    //parse hostname from URL 
    //http://www.example.co.uk/index.php => www.example.co.uk
    $urlParts = parse_url($url);
    if ($urlParts === false || empty($urlParts["host"])) 
        throw new InvalidArgumentException("Malformed URL");

    //find first partial name with MX record
    $hostnameParts = explode(".", $urlParts["host"]);
    do {
        $hostname = implode(".", $hostnameParts);
        if (checkdnsrr($hostname, "MX")) return $hostname;
    } while (array_shift($hostnameParts) !== null);

    throw new DomainException("No MX record found");
}

Czy to właśnie sugeruje tutaj IETF ?
Ellie Kesselman

1
Nawet publicsuffix.org mówi (patrz szósty akapit), że właściwym sposobem na to jest przez DNS, tak jak powiedziałeś w swojej odpowiedzi!
Ellie Kesselman

1
Tyle że możesz całkowicie mieć domenę bez rekordu MX. I że algorytm zostanie oszukany przez rekordy z symbolami wieloznacznymi. A po przeciwnej stronie masz domeny TLD, które mają rekordy MX (jak .ailub .axżeby wymienić tylko kilka).
Patrick Mevzek,

@patrick: Całkowicie się zgadzam; tak jak powiedziałem we wstępie, ten algorytm nie jest kuloodporny, to tylko heurystyka, która działa zaskakująco dobrze.
Francois Bourgeois

2

Jak już wspomniano, lista sufiksów publicznych to tylko jeden sposób na poprawne przeanalizowanie domeny. W przypadku PHP możesz wypróbować TLDExtract . Oto przykładowy kod:

$extract = new LayerShifter\TLDExtract\Extract();

$result = $extract->parse('super.duper.domain.co.uk');
$result->getSubdomain(); // will return (string) 'super.duper'
$result->getSubdomains(); // will return (array) ['super', 'duper']
$result->getHostname(); // will return (string) 'domain'
$result->getSuffix(); // will return (string) 'co.uk'

1

Właśnie napisałem program do tego w clojure na podstawie informacji z publicsuffix.org:

https://github.com/isaksky/url_dom

Na przykład:

(parse "sub1.sub2.domain.co.uk") 
;=> {:public-suffix "co.uk", :domain "domain.co.uk", :rule-used "*.uk"}

1

Dla biblioteki C (z generowaniem tabel danych w Pythonie) napisałem http://code.google.com/p/domain-registry-provider/ który jest szybki i zajmuje miejsca.

Biblioteka wykorzystuje ~ 30kB dla tabel danych i ~ 10kB dla kodu C. Nie ma narzutu związanego z uruchamianiem, ponieważ tabele są konstruowane w czasie kompilacji. Zobacz http://code.google.com/p/domain-registry-provider/wiki/DesignDocWięcej informacji można .

Aby lepiej zrozumieć kod generujący tabele (Python), zacznij tutaj: http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/registry_tables_generator/registry_tables_generator.py

Aby lepiej zrozumieć interfejs API C, zobacz: http://code.google.com/p/domain-registry-provider/source/browse/trunk/src/domain_registry/domain_registry.h


1
Mam również bibliotekę C / C ++, która ma własną listę, chociaż jest również sprawdzana z listą publicsuffix.org. Nazywa się libtld i działa pod systemami Unix i MS-Windows snapwebsites.org/project/libtld
Alexis Wilke

1

i wersje

Oprócz poprawnej odpowiedzi Adama Davisa , chciałbym zamieścić własne rozwiązanie dla tej operacji.

Ponieważ lista jest duża, istnieją trzy z wielu różnych sprawdzonych rozwiązań ...

Najpierw przygotuj swoją listę TLD w ten sposób:

wget -O - https://publicsuffix.org/list/public_suffix_list.dat |
    grep '^[^/]' |
    tac > tld-list.txt

Uwaga: tacodwróci listę, aby zapewnić .co.uk wcześniejsze przetestowanie .uk.

wersja powłoki

splitDom() {
    local tld
    while read tld;do
        [ -z "${1##*.$tld}" ] &&
            printf "%s : %s\n" $tld ${1%.$tld} && return
    done <tld-list.txt
}

Testy:

splitDom super.duper.domain.co.uk
co.uk : super.duper.domain

splitDom super.duper.domain.com
com : super.duper.domain

wersja

Aby zmniejszyć rozwidlenia (uniknąć myvar=$(function..)składni), wolę ustawiać zmienne zamiast zrzucać dane wyjściowe na standardowe wyjście, w funkcjach bash:

tlds=($(<tld-list.txt))
splitDom() {
    local tld
    local -n result=${2:-domsplit}
    for tld in ${tlds[@]};do
        [ -z "${1##*.$tld}" ] &&
            result=($tld ${1%.$tld}) && return
    done
}

Następnie:

splitDom super.duper.domain.co.uk myvar
declare -p myvar
declare -a myvar=([0]="co.uk" [1]="super.duper.domain")

splitDom super.duper.domain.com
declare -p domsplit
declare -a domsplit=([0]="com" [1]="super.duper.domain")

Szybciej wersja:

Przy takim samym przygotowaniu:

declare -A TLDS='()'
while read tld ;do
    if [ "${tld##*.}" = "$tld" ];then
        TLDS[${tld##*.}]+="$tld"
      else
        TLDS[${tld##*.}]+="$tld|"
    fi
done <tld-list.txt

Ten krok jest znacznie wolniejszy, ale splitDomfunkcja będzie znacznie szybsza:

shopt -s extglob 
splitDom() {
    local domsub=${1%%.*(${TLDS[${1##*.}]%\|})}
    local -n result=${2:-domsplit}
    result=(${1#$domsub.} $domsub)
}

Testy na moim raspberry-pi:

Obie skrypty zostały przetestowane z:

for dom in dom.sub.example.{,{co,adm,com}.}{com,ac,de,uk};do
    splitDom $dom myvar
    printf "%-40s %-12s %s\n" $dom ${myvar[@]}
done

wersja została przetestowana ze szczegółową for pętlą, ale

Wszystkie skrypty testowe generują te same dane wyjściowe:

dom.sub.example.com                      com          dom.sub.example
dom.sub.example.ac                       ac           dom.sub.example
dom.sub.example.de                       de           dom.sub.example
dom.sub.example.uk                       uk           dom.sub.example
dom.sub.example.co.com                   co.com       dom.sub.example
dom.sub.example.co.ac                    ac           dom.sub.example.co
dom.sub.example.co.de                    de           dom.sub.example.co
dom.sub.example.co.uk                    co.uk        dom.sub.example
dom.sub.example.adm.com                  com          dom.sub.example.adm
dom.sub.example.adm.ac                   ac           dom.sub.example.adm
dom.sub.example.adm.de                   de           dom.sub.example.adm
dom.sub.example.adm.uk                   uk           dom.sub.example.adm
dom.sub.example.com.com                  com          dom.sub.example.com
dom.sub.example.com.ac                   com.ac       dom.sub.example
dom.sub.example.com.de                   com.de       dom.sub.example
dom.sub.example.com.uk                   uk           dom.sub.example.com

Pełny skrypt zawierający odczyt pliku i splitDompętlę zajmuje ~ 2m z wersją posix, ~ 1m29s z pierwszym skryptem bash opartym na $tldstablicy, ale ~22sz ostatnim skryptem bash opartym na $TLDS tablicy asocjacyjnej .

                Posix version     $tldS (array)      $TLDS (associative array)
File read   :       0.04164          0.55507           18.65262
Split loop  :     114.34360         88.33438            3.38366
Total       :     114.34360         88.88945           22.03628

Więc jeśli wypełnianie tablicy asocjacyjnej jest trudniejsze, splitDomfunkcja staje się dużo szybsza!


0

Nie działa to dokładnie, ale być może możesz uzyskać przydatną odpowiedź, próbując pobrać domenę kawałek po kawałku i sprawdzając odpowiedź, tj. Pobierz „ http: // uk ”, a następnie „ http://co.uk ” , a następnie „ http://domain.co.uk ”. Kiedy otrzymasz odpowiedź bez błędu, masz domenę, a reszta to subdomena.

Czasami po prostu musisz spróbować :)

Edytować:

Tom Leys zwraca uwagę w komentarzach, że niektóre domeny zakładane są tylko na subdomenie www, co dałoby nam błędną odpowiedź w powyższym teście. Słuszna uwaga! Może najlepszym podejściem byłoby sprawdzenie każdej części za pomocą „ http: // www ” oraz „http: //” i policzenie trafienia jako trafienia w tej sekcji nazwy domeny? Nadal brakowałoby nam niektórych „alternatywnych” rozwiązań, takich jak „web.domain.com”, ale od jakiegoś czasu nie napotkałem żadnego z nich :)


Nie ma gwarancji, że x.com wskazuje serwer WWW na porcie 80, nawet jeśli www.x.com tak. W tym przypadku www jest prawidłową subdomeną. Być może pomoże tutaj automatyczny whois.
Tom Leys,

Słuszna uwaga! Whois wyjaśniłby to, chociaż utrzymywałby listę serwerów whois, które mają być używane i dla których poziomów tld / 2nd oznaczałoby rozwiązanie tego samego problemu dla przypadków skrajnych.
jTresidder,

zakładasz, że w każdej domenie działa serwer HTTP
Francois Bourgeois

Nie będzie działać dla .DKi niektórych innych, tak jak http://dk/działa. Tego rodzaju heurystyki nie są
właściwą

0

Użyj URIBuilder, a następnie pobierz atrybut URIBUilder.host i podziel go na tablicę na „.” masz teraz tablicę z podzieloną domeną.


0
echo tld('http://www.example.co.uk/test?123'); // co.uk

/**
 * http://publicsuffix.org/
 * http://www.alandix.com/blog/code/public-suffix/
 * http://tobyinkster.co.uk/blog/2007/07/19/php-domain-class/
 */
function tld($url_or_domain = null)
{
    $domain = $url_or_domain ?: $_SERVER['HTTP_HOST'];
    preg_match('/^[a-z]+:\/\//i', $domain) and 
        $domain = parse_url($domain, PHP_URL_HOST);
    $domain = mb_strtolower($domain, 'UTF-8');
    if (strpos($domain, '.') === false) return null;

    $url = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';

    if (($rules = file($url)) !== false)
    {
        $rules = array_filter(array_map('trim', $rules));
        array_walk($rules, function($v, $k) use(&$rules) { 
            if (strpos($v, '//') !== false) unset($rules[$k]);
        });

        $segments = '';
        foreach (array_reverse(explode('.', $domain)) as $s)
        {
            $wildcard = rtrim('*.'.$segments, '.');
            $segments = rtrim($s.'.'.$segments, '.');

            if (in_array('!'.$segments, $rules))
            {
                $tld = substr($wildcard, 2);
                break;
            }
            elseif (in_array($wildcard, $rules) or 
                    in_array($segments, $rules))
            {
                $tld = $segments;
            }
        }

        if (isset($tld)) return $tld;
    }

    return false;
}

0

Możesz użyć tego lib tld.js: JavaScript API do pracy ze złożonymi nazwami domen, subdomen i URI.

tldjs.getDomain('mail.google.co.uk');
// -> 'google.co.uk'

Jeśli pobierasz domenę główną w przeglądarce. Możesz użyć tego lib AngusFu / browser-root-domain .

var KEY = '__rT_dM__' + (+new Date());
var R = new RegExp('(^|;)\\s*' + KEY + '=1');
var Y1970 = (new Date(0)).toUTCString();

module.exports = function getRootDomain() {
  var domain = document.domain || location.hostname;
  var list = domain.split('.');
  var len = list.length;
  var temp = '';
  var temp2 = '';

  while (len--) {
    temp = list.slice(len).join('.');
    temp2 = KEY + '=1;domain=.' + temp;

    // try to set cookie
    document.cookie = temp2;

    if (R.test(document.cookie)) {
      // clear
      document.cookie = temp2 + ';expires=' + Y1970;
      return temp;
    }
  }
};

Używanie plików cookie jest trudne.


0

Jeśli chcesz wyodrębnić subdomeny i / lub domeny z dowolnej listy adresów URL, ten skrypt w języku Python może być pomocny. Uważaj jednak, to nie jest idealne. Jest to ogólnie trudny problem do rozwiązania i jest bardzo pomocny, jeśli masz białą listę domen, których się spodziewasz.

  1. Uzyskaj domeny najwyższego poziomu z publicsuffix.org
żądania importu

url = 'https://publicsuffix.org/list/public_suffix_list.dat'
page = request.get (url)

domeny = []
dla linii w page.text.splitlines ():
    if line.startswith ('//'):
        kontyntynuj
    jeszcze:
        domain = line.strip ()
        jeśli domena:
            domains.append (domena)

domains = [d [2:] if d.startswith ('*.') else d for d in domains]
print ('znaleziono {} domeny'.format (len (domeny)))
  1. Utwórz wyrażenie regularne
import re

_regex = ''
dla domeny w domenach:
    _regex + = r '{} |' .format (domain.replace ('.', '\.'))

subdomain_regex = r '/([^/]*)\.[^/.]+\.({})/.*$'. format (_regex)
domain_regex = r '([^ /.] + \. ({})) /.*$'. format (_regex)
  1. Użyj wyrażenia regularnego na liście adresów URL
FILE_NAME = '' # wstaw tutaj nazwę pliku CSV
URL_COLNAME = '' # wstaw tutaj nazwę kolumny URL

importuj pandy jako pd

df = pd.read_csv (FILE_NAME)
urls = df [URL_COLNAME] .astype (str) + '/' # uwaga: dodanie / jako hack, aby pomóc w wyrażeniu regularnym

df ['sub_domain_extracted'] = urls.str.extract (pat = subdomain_regex, expand = True) [0]
df ['domain_extracted'] = urls.str.extract (pat = domain_regex, expand = True) [0]

df.to_csv ('extract_domains.csv', index = False)


-3

Po szybkim spojrzeniu na listę publicsuffix.org wydaje się, że można dokonać rozsądnego przybliżenia, usuwając ostatnie trzy segmenty („segment” oznacza tutaj sekcję między dwiema kropkami) z domen, w których ostatni segment ma dwa znaki, przy założeniu, że jest to kod kraju i zostanie dalej podzielony. Jeśli ostatni segment to „my”, a przedostatni segment również składa się z dwóch znaków, usuń ostatnie cztery segmenty. We wszystkich innych przypadkach usuń ostatnie dwa segmenty. na przykład:

„Przykład” nie składa się z dwóch znaków, więc usuń „domena.example”, pozostawiając „www”

„przykład” nie składa się z dwóch znaków, więc usuń „domena.example”, pozostawiając „super.duper”

„uk” to dwa znaki (ale nie „us”), więc usuń „domain.co.uk”, pozostawiając „super.duper”

„us” to dwa znaki i to „nas”, a „wy” to także dwa znaki, więc usuń „pvt.k12.wy.us”, pozostawiając „foo”.

Zauważ, że chociaż działa to dla wszystkich przykładów, które widziałem w dotychczasowych odpowiedziach, pozostaje tylko rozsądnym przybliżeniem. Nie jest to całkowicie poprawne, chociaż podejrzewam, że jest tak blisko, jak najprawdopodobniej bez tworzenia / uzyskiwania rzeczywistej listy do wykorzystania w celach informacyjnych.


3
Istnieje wiele przypadków niepowodzeń. To jest rodzaj algorytmów używanych przez przeglądarki. Nie rób tego, korzystaj z PSL - to działa i są biblioteki, które Ci pomogą.
Gervase Markham

Nic nie stoi na przeszkodzie, aby domeny gTLD były również „segmentowane”, tak było np. Na początku .NAME, kiedy można było kupić tylko firstname.lastname.namenazwy domen. I w przeciwnym kierunku, teraz .USjest również płaski, więc możesz x.y.z.whatever.uspo prostu kupić whatever.usw rejestrze, a wtedy twój algorytm się nie powiedzie.
Patrick Mevzek,

1
Również o („segment” oznacza tutaj sekcję między dwiema kropkami) : w świecie DNS nazywa się to etykietą, nie ma potrzeby wymyślania nowej nazwy.
Patrick Mevzek
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.