Perl & Apache

Несколько ранее справочник состоял всего из двух статей моего сайта - «Perl - SYNOPSIS» и «Справочник по Perl». Но со временем количество собственнх статей и количество общественно-доступных статей по этой теме значительно увеличилось

Когда-то давно, в начале 2000-х я задался целью написать краткое руководство по Perl, и довёл дело до своей логической точки, вышло в свет издание под титулом «Perl - SYNOPSIS». По этой ссылке преведена черновая версия этого издания в электронном виде

Ниже приведен список основных ссылок на тему Perl

CGI ENV

Список переменнх окружения (%ENV) стандарта CGI

REQUEST_METHOD
Это одно из самых главных поле используемое для определения метода запроса HTTP Протокол HTTP использует методы GET и POST для запроса к серверу.Они отличаются тем что при методе GET запрос является как-бы частью URL т.е. http://www..../myscript.cgi?request а при методе POST данные передаются в теле HTTP-запроса (при GET тело запроса пусто) и следовательно для CGI тоже есть различие при GET запрос идет в переменную QUERY_STRING а при POST подается на STDIN скрипта.
Пример: REQUEST_METHOD=GET
QUERY_STRING
Это строка запроса при методе GET. Вам всем известно что запрос из формы кодируется браузером поскольку не все символы разрешены в URL некоторые имеют специальное назначение. Теперь о методе urlencode: неплохо бы чисто формально напомнить,что все пробелы заменяются в URL на знак '+', а все специальные и непечатные символы на последовательность %hh ,где hh-шестнадцатиричный код символа,разделитель полей формы знак '&',так что при обработке форм надо произвести декодирование.
Пример:QUERY_STRING= name=quake+doomer&age=20&hobby=games
CONTENT_LENGTH
Длина в байтах тела запроса.При методе запроса POST необходимо считать со стандартного входа STDIN CONTENT_LENGTH байт,а потом производить их обработку.Обычно методом POST пользуются для передачи форм,содержащих потенциально большие области ввода текста TEXTAREA.При этом методе нет никаких ограничений,а при методе GET существуют ограничения на длину URL .
Пример:CONTENT_LENGTH=31
CONTENT_TYPE
Тип тела запроса(для форм кодированых выше указаным образом он application/x-www-form-urlencoded)
GATEWAY_INTERFACE
Версия протокола CGI.
Пример:GATEWAY_INTERFACE=CGI/1.1
REMOTE_ADDR
IP-Адрес удаленого хоста,делающего данный запрос.
Пример:REMOTE_ADDR=139.142.24.157
REMOTE_HOST
Если запрашивающий хост имеет доменное имя,то эта переменная содержит его, в противном случае -тот же самый IP-адресс что и REMOTE_ADDR
Пример:REMOTE_HOST=idsoftware.com
SCRIPT_NAME
Имя скрипта,исполизованое в запросе.Для получения реального пути на сервере используйте SCRIPT_FILENAME
Пример:SCRIPT_NAME=/~paaa/guestbook.cgi
SCRIPT_FILENAME
Имя файла скрипта на сервере.
Пример:SCRIPT_FILENAME=/home/p/paaa/public_html/cgi-bin/guestbook.cgi
SERVER_NAME
Имя серера ,чаще всего доменное как www.microsoft.com ,но в редких случаях за неимением такового может быть IP-адресом как 157.151.74.254
Пример:SERVER_NAME=www.uic.nnov.ru
SERVER_PORT
TCP-Порт сервера используюшийся для соединения .По умолчаниию HTTP-порт 80, хотя может быть в некоторых случаях другим.
Пример:SERVER_PORT=80
SERVER_PROTOCOL
Версия протокола сервера.
Пример:SERVER_PROTOCOL=HTTP/1.1
SERVER_SOFTWARE
Програмное обеспечение сервера.
Пример:Apache/1.0
AUTH_TYPE, REMOTE_USER
Эти переменные определены в том случае,когда запрошеный ресурс требует аутентификации пользователя.
Переменные заголовка HTTP-запроса.
За исключением тех строк из заголовка HTTP-запроса которые были включены в другие переменные,сервер приделывает строкам префикс HTTP_ и заменяет знаки '-' на '_':
HTTP_ACCEPT
Давая запрос на сервер браузер обычно расчитывает получить информацию определеного формата,и для этого он в заголовке запроса указывает поле Accept:,Отсюда скрипту поступает cписок тех MIME,которые браузер готов принять в качестве ответа от сервера.
Пример:HTTP_ACCEPT=text/html,text/plain,image/gif
HTTP_USER_AGENT
Браузер обычно посылает на сервер и информацию о себе,чтоб базируясь на знании особеностей и недостатков конкретных браузеров CGI-скрипт мог выдать информацию с учетом этого. Например,разные браузеры могут поддерживать или не поддерживать какие-то HTMLые тэги.
Пример:HTTP_USER_AGENT=Mozila/2.01 Gold(Win95;I)
HTTP_HOST
Имя хоста к которому обращается браузер. Так как физически на одном сервере может находиться сразу много серверов (Виртуальные Хосты), то должен быть способ сообщить серверу к какому именно идет обращение. Скрипт же может тоже в зависимости от этой переменной производить различные действия, таким если он используется на сайтах сразу нескольких виртуальных хостов.
Пример:HTTP_HOST=www.nnov.city.ru

SSI (Apache Server Side Includes)

SSI (Server Side Includes — включения на стороне сервера) - малоизвестная технология, которая при этом очень мощная и полезная. SSI активно использовалась с 1996 года. SSI несложный язык для динамической «сборки» веб-страниц на сервере из отдельных составных частей и выдачи клиенту полученного HTML-документа. Реализован в веб-сервере Apache при помощи модуля mod_include. Включённая в настройках по умолчанию веб-сервера возможность позволяет подключать HTML-файлы, поэтому для использования инструкций файл должен оканчиваться расширением .shtml, .stm или .shtm. Необходимо помнить, что некоторые сервисы не исполняют команды SSI, если расширение файла будет отличное от приведенных выше. Например, если расширение - .html. Синтаксис SSI позволяет включать в текст страницы другие SSI-страницы, вызывать внешние CGI-скрипты, реализовывать условные операции (if/else), работать с переменными и т.п. Благодаря крайней простоте языка, сборка SSI-страниц происходит очень быстро, однако многие возможности полноценных языков программирования, например, работа с файлами, в SSI отсутствуют.

Для начала о причинах, побудивших написать меня эту статью: в обсуждениях членов Всероссийского Клуба Вебмастеров не раз возникали споры о том, что лучше применять в случае овторяющейся разметки (информации) на большом количестве страниц - фреймы, JavaScript или SSI (Server Side Includes). Моим глубоким убеждением является то, что фреймы следует спользовать только там, где без этого действительно никак не обойтись, JavaScript (да и любые другие клиентские скрипты) слишком капризен и зависит от настроек браузера, поэтому его можно использовать только для дополнительных возможностей, но никак для простроения, допустим, системы навигации. Я не буду с пеной у рта доказывать, что технология SSI круче всех гор и яиц, а просто приведу решения часто встречающихся на практике задач с применением этой технологии.

(Сразу предвижу возмущение со стороны приверженцев технологий ASP и PHP, с использованием которых также возможны решения подобных задач, поэтому специально для них: технология SSI значительно проще, в ней всего десяток операций, поэтому для не программиста это более удачный выбор хотя бы потому, что ее можно быстрее освоить)

Дата последней модификации документа
Простая директива:

            <!--#echo var="LAST_MODIFIED"-->
        

Сегодняшнее число в нужном формате
Если нам нужно вывести дату не в стандартном для данной конфигурации программных средств виде, а в том, какой нам нужен (например, "вторник, 30 мая, 2000"), то можно воспользоваться следующей конструкцией:Получение дня недели

    <!--#config timefmt="%u" -->
    <!--#set var="NUM_DAY" value="$DATE_LOCAL"-->
    <!--#if expr="$NUM_DAY=1" -->
    <!--#set var="DAY" value="понедельник" -->
    <!--#elif expr="$NUM_DAY=2" -->
    <!--#set var="DAY" value="вторник" -->
    <!--#elif expr="$NUM_DAY=3" -->
    <!--#set var="DAY" value="среда" -->
    <!--#elif expr="$NUM_DAY=4" -->
    <!--#set var="DAY" value="четверг" -->
    <!--#elif expr="$NUM_DAY=5" -->
    <!--#set var="DAY" value="пятница" -->
    <!--#elif expr="$NUM_DAY=6" -->
    <!--#set var="DAY" value="суббота" -->
    <!--#else -->
    <!--#set var="DAY" value="воскресенье" -->
    <!--#endif -->
    

Получение числа

<!--#config timefmt="%e" -->
    <!--#set var="DATE" value="$DATE_LOCAL"-->

Получение названия месяца

<!--#config timefmt="%m" -->
    <!--#set var="NUM_MONTH" value="$DATE_LOCAL"-->
    <!--#if expr="$NUM_MONTH=01" -->
    <!--#set var="MONTH" value="января" -->
    <!--#elif expr="$NUM_MONTH=02" -->
    <!--#set var="MONTH" value="февраля" -->
    <!--#elif expr="$NUM_MONTH=03" -->
    <!--#set var="MONTH" value="марта" -->
    <!--#elif expr="$NUM_MONTH=04" -->
    <!--#set var="MONTH" value="апреля" -->
    <!--#elif expr="$NUM_MONTH=05" -->
    <!--#set var="MONTH" value="мая" -->
    <!--#elif expr="$NUM_MONTH=06" -->
    <!--#set var="MONTH" value="июня" -->
    <!--#elif expr="$NUM_MONTH=07" -->
    <!--#set var="MONTH" value="июля" -->
    <!--#elif expr="$NUM_MONTH=08" -->
    <!--#set var="MONTH" value="августа" -->
    <!--#elif expr="$NUM_MONTH=09" -->
    <!--#set var="MONTH" value="сентября" -->
    <!--#elif expr="$NUM_MONTH=10" -->
    <!--#set var="MONTH" value="октября" -->
    <!--#elif expr="$NUM_MONTH=11" -->
    <!--#set var="MONTH" value="ноября" -->
    <!--#else -->
    <!--#set var="MONTH" value="декабря" -->
    <!--#endif -->
    

Получение года

<!--#config timefmt="%G" --> <!--#set var="YEAR" value="$DATE_LOCAL"-->

Собственно вывод получившейся строки

<!--#echo var="DAY" -->, <!--#echo var="DATE" --> <!--#echo var="MONTH" -->, <!--#echo var="YEAR"-->

Форматы параметров для config timefmt надо смотреть для каждой конфигурации веб-сервера отдельно. Приведенный пример - FreeBSD, Apache. Более подробно см. man timefmt
Подобная конструкция используется на веб-узле интернет-магазина Levingston.Ru

Дата модификации внешнего файла
Часто на компьютерных сайтах выкладывают прайс-лист в формате MS Excel или Word и каждый раз руками прописывают дату его изготовления. С помощью SSI это делается примерно следующим образом:

        <a href=pricelst.doc>Прайс-лист</a>
        <!--#config timefmt="%d.%m.%y" -->
        (MS Word 6.0/95, <!--#flastmod virtual="pricelst.doc" -->)
    

Такая конструкция используется на веб-узле компании Дункан Сервис

Борьба с <noframes>
Как правило, в этом контейнере пишут "извините, но вам следует обновить браузер", по идее же там должны быть альтернатива для пользователей старых версий браузеров. Поскольку на нормальном сервере информация часто меняется, а вебмастеру же лениво каждый раз вносить правки в двух местах. С помощью SSI проблема решается раз и навсегда: в контейнер <noframes></noframes> вносится директива, вставляющая тот самый файл, в котором делаются правки или попросту линейку навигации.

Борьба с прямыми ссылками на документы на веб-узле с фреймами
Одним из аргументов против использования фреймовых структур при создании веб-узлов является неудобство прямых ссылок на содержательные файлы. Например, при ссылке из поисковых машин или на конкретный (не корневой) документ с другого веб-узла пользователь попадает на страницу, лишенную оформления или элементов навигации, которые обычно помещаются в отдельный навигационный фрейм. С помощью нехитрой конструкции SSI эту проблему можно решить. Для этого необходимо проанализировать, откуда пришел пользователь (переменная HTTP_REFERER) Если он пришел не с нашего сервера, а извне - построить фреймовую структуру и в качестве содержательного фрейма подставить документ, запрошенный пользователем.

В примере ниже файл content.html - это тот документ, на который стоит прямая ссылка (допустим, из поисковой машины), frame.html - файл в котором строится фреймовая структура. В QUERY_STRING подставляется значение done для того, чтобы избежать бесконечной вложенности фреймовых структур.

Файл content.html

<html>
    <head>
    ...
    <!--#include virtual="frame.html" -->
    </head>
    <body>
    ...
    </body>
    </html>

Файл frame.html

<!--#if expr="$QUERY_STRING!=done
    &&
     $HTTP_REFERER!=/your_domain\.ru/" -->
    <frameset rows="150,*">
    <frame name="NAVIGATION" src="/navigation.html">
    <frame name="CONTENT" src="<!--#echo
    var="DOCUMENT_URI" -->?done">
    </frameset>
    <!--#endif -->

Подобная конструкция используется на веб-узле интернет-магазина Болеро

Версия страницы для печати
Часто возникает прикладная задача - красивый многоколоночный дизайн с верхней и нижней шапками, туча баннеров, но при печати все это не нужно - лишняя бумага, ненужная информация... Поэтому хочется сделать простой альтернативный вид страницы специально для печати. Чтобы это проделать, достаточно подготовить два варианта верхней и нижней шапок, один --для экранного отображения, другой - для печати. В качестве переключения между этими вариантами используем переменную QUERY_STRING. Ниже приведены принципиальные структуры для самой страницы (file.html) и для верхней и нижней шапок (top.html и bottom.html).

Структура самой страницы (file.html):

<!--#include virtual="top.html?$QUERY_STRING" -->
    здесь тело документа
    <!--#include virtual="bottom.html?$QUERY_STRING" -->

Структура top.html и bottom.html

<!--#if expr="$QUERY_STRING == /for_printing/" -->
    шапка для печати
    <!--#else -->
    шапка для просмотра
    <!--#endif -->

Ссылка на каждой странице должна быть вида

<a href=<!--echo var="$DOCUMENT_URI" -->?for_printing>версия для печати</a>

Подобная конструкция используется на веб-узле Всероссийского Клуба Вебмастеров

Борьба с пунктами меню
Предположим, у нас есть несколько разделов веб-узла, документы, относящиеся к разделам, лежат в разных директориях. Задача - сделать так, чтобы в меню навигации по этим разделам пропадала (или не подсвечивалась, выделялась другим цветом и т.д.) ссылка на тот раздел, в котором находится пользователь в данный момент. Для этого можно использовать переменную DOCUMENT_URI.

<!--#if expr="$DOCUMENT_URI!=/^\/index.html/" -->
    <a href="/">Первая страница</a><br>
    <!--#endif -->
    <!--#if expr="$DOCUMENT_URI!=/\/about\/index.html/" -->
    <a href="/about/">О нас</a><br>
    <!--#endif -->
    <!--#if expr="$DOCUMENT_URI!=/\/done\/index.html/" -->
    <a href="/done/">Наши работы</a><br>
    <!--#endif -->
    <!--#if expr="$DOCUMENT_URI!=/\/partner\/index.html/" -->
    <a href="/partner/">Наши партнеры</
    a><br>
    <!--#endif -->
    <!--#if expr="$DOCUMENT_URI!=/\/client\/index.html/" -->
    <a href="/client/">Наши клиенты</
    a><br>
    <!--#endif -->
    <!--#if expr="$DOCUMENT_URI!=/\/price\/
    index.html/" -->
    <a href="/price/">Наши цены</a><br>
    <!--#endif -->
    <!--#if expr="$DOCUMENT_URI!=/\/contacts\/
    index.html/" -->
    <a href="/contacts/">Наши координаты</
    a><br>
    <!--#endif -->
    <!--#if expr="$DOCUMENT_URI!=/\/history\/index.html/" -->
    <a href="/history/">Наша история</a><br>
    <!--#endif -->
    <!--#if expr="$DOCUMENT_URI!=/\/search.html/" -->
    <a href="/search.html">Поиск</a><br>
    <!--#endif -->

Подобная конструкция используется веб-узле компании Веб 2000

Контекстный вывод текста в зависимости от условий
Предположим, у нас стоит задача менять внешний вид первой страницы узла в зависимости от того, откуда пришел пользователь. Для реализации этой задачи используется следующая конструкция:

<!--#if expr="$HTTP_REFERER=/www.zzz.ru/" -->
    Здесь совершаются необходимые действия
    <!--#endif -->

т.е. сравнивается переменная HTTP_REFERER

Борьба с разными версиями дизайна для разных браузеров
Всем известно, что браузеры различных производителей и версий по-разному отображают одну и ту же HTML-разметку документа, начиная от специальных тагов и атрибутов и заканчивая поддержкой различных версий JavaScript. Для того, чтобы веб-узел выглядел нормально и для одной версии браузера и для другой или чтобы не сыпались ошибки JavaScript средствами SSI можно сделать проверку версий или браузеров и выдавать различные варианты HTML-разметки. Для этого анализируется переменная HTTP_USER_AGENT, в которой содержится информация о типе и производителе браузера:

    <!--#if expr="$HTTP_USER_AGENT=/Mozilla\/4/ || $HTTP_USER_AGENT=/Mozilla\/5/"-->
    Если версия браузера не ни же 4 или 5, то вывести вариант дизайна,
    использующий, например, DHTML
<!--#else -->
Здесь вывести простой дизайн
<!--#endif -->

Подобная конструкция использовалась для построения фреймовой структуры и выводе внутреннего меню (для Netscape - на DHTML, для MSIE - на ActiveX) на веб-узле журнала "ОМ"

Борьба с оформлением результатов работы скриптов
Самая большая проблема со скриптами заключается в том, что если есть большое количество наработанного ПО - при смене дизайна требуется их перенастройка. Хорошо, если ПО сделано правильно и изменение шаблонов отображения не касается самой математики, однако и в таких случаях существуют проблемы. Например, на странице поиска было бы неплохо крутить баннеры и рекламных сетей, но директивы SSI не отрабатываются в файлах .cgi. Решить подобные проблемы можно использованием SSI следующим образом: не скриптом обрабатывать шаблоны отображения, а вызывать скрипт из HTML-документа через SSI (к сожалению, таким образом можно работать только с теми скриптами, которые используют метод GET - переменная CONTENT_LENGTH не доступна в SSI) Итак, как это делается Есть HTML-документ, который размечен в общем стиле дизайна. В него вставляется директива

    <!--#include virtual="
    /cgi-bin/script.cgi?$QUERY_STRING" -->

На первом шаге, пока QUERY_STRING пуста - вызывается первый шаг скрипта, на последующих шагах работы скрипта - передаются необходимые параметры. В самом скрипте важны три строчки:

...
    # определение адреса, куда направлять данные
    $query = $ENV{QUERY_STRING};
    # определение места, из которого был вызван скрипт
    $uri = $ENV{DOCUMENT_URI};
    ...
    # отправка данных в тот же HTML-документ,
    из которого был вызван скрипт
    print "<form action=$uri method=get>\n";
    ...

Подобная конструкция использована в разделе "Голосования" для интернет-супермаркета Levingston.Ru

Что можно сделать, используя Cookie и SSI
Часто встречается конструкция на JavaScript, которая выводит "Здравствуйте, Иван Иваныч!" при заходе на страницу веб-узла. То же самое можно проделать с помощью SSI директивой

<!--#echo var="HTTP_COOKIE" -->

Баннеры, кэширование и SSI
Прислал Кирил Хлопов (NewTech)
Как известно, баннерные системы предлагают включать в код некоторую случайную величину в URL скрипта показа - защита от кеширования.

А можно еще так:

<!--#config timefmt="%s"-->
    <!--#set var="RND" value="$DATE_LOCAL"-->
    <!-- Russian LinkExchange code START -->
    <iframe src=http://www.linkexchange.ru/
    cgi-bin/erle.cgi?some_id?
    <!--#echo var="RND"-->
    frameborder=0 vspace=0 hspace=0 width=468
    height=60 marginwidth=0
     marginheight=0 scrolling=no>
    <a href=http://www.linkexchange.ru/users/
    some_id/goto.map target=_top>
    <img src=http://www.linkexchange.ru/
    cgi-bin/rle.cgi??<!--#echo var="RND"-->
    alt="RLE Banner Network" border=0 height=60
    width=468></a>
    </iframe>
    <!-- Russian LinkExchange code END -->

То есть как случайная величина выступит количество секунд от 1970 года. Не тратится время и память на запуск скрипта-генератора, Java-Script (как среди некоторых пользователей сейчас это модно) может быть выключен. На мой взгляд вполне радужно :-)
Все это проверено и применяется нашим администратором на http://www.j2.ru/

Один шаблон отображения - разное содержание
Прислал Евгений Беспальчиков (KADIS)
Часто шаблоны используют таким образом:
есть только один файл, который описывает структуру страницы, а основное содержание включается директивой

<!--#include virtual="$QUERY_STRING.html"-->

ссылки, соответственно, будут иметь вид:

href="www.your_domain.ru/index.html?page1"
    href="www.your_domain.ru/index.html?page2"
    ...

Проблема возникает, если пользователь набирает адрес непосредственно http://www.your_domain.ru, т.е. QUERY_STRING=""

Решение:

<!--#if expr="$QUERY_STRING" -->
    <!--#include virtual="$QUERY_STRING.html"-->
    <!--#else -->
    <!--#include virtual="default.html"-->
    <!--#endif -->

где default.html - страница корневого индекса (оглавления) и просто заглушка.

Источник: Российский клуб вебмастеров, Андрей Аликберов, Webclub.Ru

REST AND CRUD

The acronym CRUD refers to all of the major functions that are implemented in relational database applications. Each letter in the acronym can map to a standard Structured Query Language (SQL) statement, Hypertext Transfer Protocol (HTTP) method (this is typically used to build RESTful APIs) or Data Distribution Service (DDS) operation:

      CRUD            | SQL    | HTTP           | RESTful| DDS       | Prefix
    ------------------+--------+----------------+--------+-----------+--------
     Create           | INSERT | PUT/POST       | POST   | write     | add
     Read (Retrieve)  | SELECT | GET            | GET    | read/take | get/is
     Update (Modify)  | UPDATE | PUT/POST/PATCH | PUT    | write     | set
     Delete (Destroy) | DELETE | DELETE         | DELETE | dispose   | del/rm

Note! Create - PUT with a new URI; POST to a base URI returning a newly created URI

Note! Update - PUT with an existing URI

Note! HTTP PATCH - When PUTting a complete resource representation is cumbersome and utilizes more bandwidth, e.g.: when you have to update partially a column

PRINCIPIES OF REST

HTTP METHODS

Use HTTP methods to map CRUD (create, retrieve, update, delete) operations to HTTP requests.

GET

Retrieve information. GET requests must be safe and idempotent, meaning regardless of how many times it repeats with the same parameters, the results are the same. They can have side effects, but the user doesn't expect them, so they cannot be critical to the operation of the system. Requests can also be partial or conditional.

Retrieve an address with an ID of 1:

    GET /addresses/1

POST

Request that the resource at the URI do something with the provided entity. Often POST is used to create a new entity, but it can also be used to update an entity.

Create a new address:

    POST /addresses

PUT

Store an entity at a URI. PUT can create a new entity or update an existing one. A PUT request is idempotent. Idempotency is the main difference between the expectations of PUT versus a POST request.

Modify the address with an ID of 1:

    PUT /addresses/1

Note: PUT replaces an existing entity. If only a subset of data elements are provided, the rest will be replaced with empty or null.

PATCH

Update only the specified fields of an entity at a URI. A PATCH request is neither safe nor idempotent (RFC 5789). That's because a PATCH operation cannot ensure the entire resource has been updated.

    PATCH /addresses/1

DELETE

Request that a resource be removed; however, the resource does not have to be removed immediately. It could be an asynchronous or long-running request.

Delete an address with an ID of 1:

    DELETE /addresses/1

HTTP 1.1 STATUS CODES

1XX - informational
    100 HTTP_CONTINUE                        Continue
    101 HTTP_SWITCHING_PROTOCOLS             Switching Protocols
2XX - success
    200 HTTP_OK                              OK
    201 HTTP_CREATED                         Created
    202 HTTP_ACCEPTED                        Accepted
    203 HTTP_NON_AUTHORITATIVE               Non-Authoritative Information
    204 HTTP_NO_CONTENT                      No Content
    205 HTTP_RESET_CONTENT                   Reset Content
    206 HTTP_PARTIAL_CONTENT                 Partial Content
3XX - redirection
    300 HTTP_MULTIPLE_CHOICES                Multiple Choices
    301 HTTP_MOVED_PERMANENTLY               Moved Permanently
    302 HTTP_MOVED_TEMPORARILY               Found
    303 HTTP_SEE_OTHER                       See Other
    304 HTTP_NOT_MODIFIED                    Not Modified
    305 HTTP_USE_PROXY                       Use Proxy
    306                                      (Unused)
    307 HTTP_TEMPORARY_REDIRECT              Temporary Redirect
4XX - client error
    400 HTTP_BAD_REQUEST                     Bad Request
    401 HTTP_UNAUTHORIZED                    Unauthorized
    402 HTTP_PAYMENT_REQUIRED                Payment Required
    403 HTTP_FORBIDDEN                       Forbidden
    404 HTTP_NOT_FOUND                       Not Found
    405 HTTP_METHOD_NOT_ALLOWED              Method Not Allowed
    406 HTTP_NOT_ACCEPTABLE                  Not Acceptable
    407 HTTP_PROXY_AUTHENTICATION_REQUIRED   Proxy Authentication Required
    408 HTTP_REQUEST_TIMEOUT                 Request Timeout
    409 HTTP_CONFLICT                        Conflict
    410 HTTP_GONE                            Gone
    411 HTTP_LENGTH REQUIRED                 Length Required
    412 HTTP_PRECONDITION_FAILED             Precondition Failed
    413 HTTP_REQUEST_ENTITY_TOO_LARGE        Request Entity Too Large
    414 HTTP_REQUEST_URI_TOO_LARGE           Request-URI Too Long
    415 HTTP_UNSUPPORTED_MEDIA_TYPE          Unsupported Media Type
    416 HTTP_RANGE_NOT_SATISFIABLE           Requested Range Not Satisfiable
    417 HTTP_EXPECTATION_FAILED              Expectation Failed
5XX - server error
    500 HTTP_INTERNAL_SERVER_ERROR           Internal Server Error
    501 HTTP_NOT IMPLEMENTED                 Not Implemented
    502 HTTP_BAD_GATEWAY                     Bad Gateway
    503 HTTP_SERVICE_UNAVAILABLE             Service Unavailable
    504 HTTP_GATEWAY_TIME_OUT                Gateway Timeout
    505 HTTP_VERSION_NOT_SUPPORTED           HTTP Version Not Supported

See Apache Constants