Nowe kody odpowiedzi HTTP

Niedawno pojawił się nowy dokument RFC o numerze 6585 zawierający informacje o nowych kodach odpowiedzi HTTP. Poniżej więcej informacji o nowych kodach, ich przeznaczeniu i celu ich wprowadzenia.

Bywają takie sytuacje, kiedy programista zastanawia się, jakiś kodów odpowiedzi HTTP użyć, aby najbardziej odpowiadały one temu, co chce osiągnąć. Okazuje się, że niektóre kody HTTP w dość naciągany i niepraktyczny sposób były używane w niektórych sytuacjach. Dokument RFC 6585 opisuje nowe kody i wspomina, że serwery nie muszą ich wspierać, choć powinny, aby prawidłowo je rozpoznać.

428 Precondition Required

Kod ten wskazuje, że serwer wymaga warunkowego żądania.

Warunkowe żądanie to takie, które zawiera nagłówek “If-Match”, “If-None-Match”, “If-Modified-Sience”, “If-Unmodified-Sience”, “Etag” (dodany w HTTP w wersji 1.1), itd. Nagłówek taki, najprościej ujmując zawiera zazwyczaj identyfikator który jest przypisany do pobranego zasobu metodą GET. Jeśli zasób zmienia zawartość, w nagłówku pojawi się inny identyfikator.

Teraz weźmy za przykład jakieś API. Klient pobiera z serwera zasób metodą GET, modyfikuje go i zapisuje metodą PUT. Nie ma zatem pewności, ze inny klient w tym czasie nie zdążył zmodyfikować tego zasobu i nie zostanie nadpisany. Jeśli metoda GET zwróci identyfikator, a klient przy pomocy metody PUT także użyje tego identyfikatora, po stronie serwera możliwa jest walidacja, czy żądanie klienta dotyczy aktualnej wersji zasobu. Jeśli nie, serwer w odpowiedzi zwraca klientowi kod 412 (Precondition Failed). Tak w przybliżeniu wygląda warunkowe żądanie. Ale co w sytuacji, gdy klient ignoruje warunkowe żądanie i nie używa jednego z określonych nagłówków (nie przeprowadza żądania warunkowego)? Do tej pory nie było kodu odpowiedzi, którym serwer mógłby odpowiedzieć jednoznacznie klientowi. Tym kodem jest właśnie 428 (Precondition Required).

Odpowiedź z serwera z kodem 428 powinna wyjaśniać, jak prawidłowo przesłać dane do serwera. Nie może być cache-owana.

Przykład odpowiedzi z serwera:

HTTP/1.1 428 Precondition Required
Content-Type: text/html

<html>
    <head>
        <title>Precondition Required</title>
    </head>
    <body>
        <h1>Precondition Required</h1>
        <p>This request is required to be conditional;
        try using "If-Match".</p>
     </body>
</html>

429 Too Many Requests

W przypadku kodu 429 sytuacja jest prosta. Niekiedy występuje potrzeba limitowania ilości żądań, jakie klient wysyła do serwera w określonym czasie. Przyczyn może być wiele, np. kontrola antyflooowa, konieczność utrzymania wysokiej jakości usług… Do tej pory nie istniał kod, który jednoznacznie określał by klientowi, że wykonał zbyt wiele żądań do serwera. Programiści radzili sobie na rożne sposoby, np używając kodu 509 (Bandwidth Limit Exceeded), który nijak tu nie pasuje. Inni używali nieistniejących kodów, np. 420 (nazwanego Enhance Your Calm) w przypadku Twittera (informacja w dokumentacji API).

Odpowiedź serwera z kodem 429 powinna zawierać informacje wyjaśniające ten stan, oraz opcjonalnie może zawierać nagłówek Retry-After określający czas po jakim klient może ponowić żądanie. Specyfikacja nie określa sposobu w jaki serwer zlicza żądania klienta, zanim odeśle ten kod odpowiedzi – to leży po stronie programistów. Odpowiedź z kodem 429 nie może być cache-owana.

Przykład odpowiedzi z serwera:

HTTP/1.1 431 Request Header Fields Too Large
Content-Type: text/html

<html>
    <head>
        <title>Request Header Fields Too Large</title>
    </head>
     <body>
       <h1>Request Header Fields Too Large</h1>
        <p>The "Example" header was too large.</p>
    </body>
</html>

431 Request Header Fields Too Large

Kod 431 oznacza, że serwer odmówił przetwarzania żądania, ponieważ rozmiar pól nagłówka jest za duży. Kod ten może być zwrócony zarówno gdy jedno z pół jest za duże, lub wszystkie sumarycznie mają zbyt duży rozmiar. Jak powyżej, odpowiedź z tym kodem nie może być cache-owana.

Przykład odpowiedzi z serwera:

HTTP/1.1 431 Request Header Fields Too Large
Content-Type: text/html

<html>
    <head>
        <title>Request Header Fields Too Large</title>
    </head>
    <body>
        <h1>Request Header Fields Too Large</h1>
        <p>The "Example" header was too large.</p>
    </body>
</html>

511 Network Authentication Required

Ten kod odpowiedzi jest dość ciekawy. Istnieją hotspoty czy lub sieci wewnętrzne (np. w korporacjach), które wymagają autoryzacji przed rozpoczęciem korzystania z nich (ja przykładowo będąc w Krakowie w nowej serwerowni Onetu podłączyłem się do sieci WiFi, w której musiałem zautoryzować się swoim kontem domenowym). Sytuacja najczęściej wygląda tak, że blokowane są wszystkie porty docelowe poza potem TCP 80. Użytkownik łączący się przez przeglądarkę z jakąkolwiek stroną internetową, zamiast zawartości tej strony otrzymuje formularz do logowania, co więcej z kodem odpowiedzi 200 (OK). Problem jeszcze nie jest aż tak duży, gdy następuje przekierowanie do innej domeny w której umieszczony jest formularz. Nie jest duży dla użytkownika. Jeśli nie nastąpi przekierowanie, a zostanie wprost wyświetlony formularz, użytkownik loguje się i po udanej autoryzacji otrzymuje już właściwą zawartość. Prawie. Jeśli formularz zawierał favicon-ę, może się okazać, prze przeglądarka ją zkeszuje i będzie nadal widoczna na docelowej stronie.

Sytuacja jest nieco gorsza, gdy żądanie nie wychodzi z przeglądarki użytkownika, a z aplikacji, która po otrzymaniu odpowiedzi z kodem 200 (OK) “sądzi”, że otrzymała właściwą treść, np xml z danymi. Niespodzianka – zamiast xml-a jest html z zawartością formularza. Nie trudno przewidzieć skutki, jeśli aplikacja jest nie do końca dobrze napisana. Jak by nie było, kod 200 (OK) nie był tu wcale oczekiwany, aplikacja “nie wie” w czym problem, użytkownik aplikacji zapewne również.

W tym właśnie celu powstał kod 511. Odpowiedź z serwerem z takim kodem powinna zawierać link do formularza do autoryzacji, za to nie powinna zawierać bezpośrednio treści formularza (ponieważ będzie to wyglądać jak formularz przesłany przez docelowy serwer). Kod 511 nie powinien być generowany przez docelowy serwer, a przez interfejs służący do autoryzacji. Odpowiedzi z tym kodem, uwaga… tak, nie powinny być cache-owane ;)

Przykład żądania przed autoryzacją:

GET /index.htm HTTP/1.1
Host: www.example.com

I przykład odpowiedzi:

HTTP/1.1 511 Network Authentication Required
Content-Type: text/html

<html>
    <head>
        <title>Network Authentication Required</title>
        <meta http-equiv="refresh" content="0;
            url=https://login.example.net/">
    </head>
    <body>
        <p>You need to <a href="https://login.example.net/">
        authenticate with the local network</a> in order to
        gain access.</p>
    </body>
</html>

 

Źródło: The Internet Engineering Task Force (IETF)
Obrazek: [1]

Ten wpis został opublikowany w kategorii Internet, Programowanie, Serwery i oznaczony tagami , , . Dodaj zakładkę do bezpośredniego odnośnika.

Jedna odpowiedź na „Nowe kody odpowiedzi HTTP

Dodaj komentarz

Musisz się zalogować (także Facebook, Google+, Twitter), aby móc dodać komentarz.