Раздел 10. Модули Апача Пункты: 85 86 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 163 164 165 166 167 168 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 203 204 205 206 207 208 209 210 211 212 213 RU EN Пункт 170. Модуль Apache mod_proxy_ajp Этот модуль требует обслуживания Таким образом, для того, чтобы получить возможность обработки ПредупреждениеНе включайте прокси, пока не защитите свой сервер. Открытые прокси-серверы опасны как для вашей сети, так и для Интернета в целом. ПрименениеЭтот модуль используется для реверсирования прокси на внутренний сервер приложений (например, Apache Tomcat) с использованием протокола AJP13. Использование похоже на обратный прокси-сервер HTTP, но использует Простой обратный проксиProxyPass "/app" "ajp://backend.example.com:8009/app" Также могут использоваться балансиры: Обратный прокси балансировщика<Прокси "балансировщик://кластер"> BalancerMember "ajp://app1.example.com:8009" loadfactor=1 BalancerMember "ajp://app2.example.com:8009" loadfactor=2 ProxySet lbmethod=bytraffic </прокси> ProxyPass "/app" "balancer://cluster/app" Обратите внимание, что обычно никакая
Основное исключение — это когда путь URL-адреса на прокси-сервере отличается от пути на серверной части. В этом случае заголовок перенаправления может быть переписан относительно исходного URL-адреса хоста (а не Перезапись прокси-путиProxyPass "/apps/foo" "ajp://backend.example.com:8009/foo" ProxyPassReverse "/apps/foo" "http://www.example.com/foo" Однако обычно лучше развернуть приложение на внутреннем сервере по тому же пути, что и прокси, чем использовать этот подход. Переменные средыПеременные среды, имена которых имеют префикс, Обзор протоколаПротокол Как только соединение назначается конкретному запросу, оно не будет использоваться ни для каких других до тех пор, пока не завершится цикл обработки запроса. Другими словами, запросы не мультиплексируются по соединениям. Это значительно упрощает код на обоих концах соединения, хотя и приводит к одновременному открытию большего количества соединений. После того как веб-сервер открыл соединение с контейнером сервлетов, соединение может находиться в одном из следующих состояний:
Как только соединение назначается для обработки определенного запроса, основная информация о запросе (например, заголовки HTTP и т. д.) отправляется по соединению в очень сжатой форме (например, общие строки кодируются как целые числа). Подробная информация об этом формате приведена ниже в разделе «Структура пакета запроса». Если в запросе есть тело В этот момент контейнер сервлетов предположительно готов начать обработку запроса. При этом он может отправлять следующие сообщения обратно на веб-сервер:
Каждое сообщение сопровождается пакетом данных различного формата. Подробности см. в разделе Структуры ответных пакетов ниже. Базовая структура пакетаЭтот протокол немного унаследован от XDR, но он во многом отличается (например, нет выравнивания по 4 байтам). AJP13 использует сетевой порядок байтов для всех типов данных. В протоколе есть четыре типа данных: байты, логические значения, целые числа и строки.
Размер пакетаСогласно большей части кода, максимальный размер пакета составляет Заголовки пакетовПакеты, отправляемые с сервера в контейнер, начинаются с
Для большинства пакетов первый байт полезной нагрузки кодирует тип сообщения. Исключением являются пакеты тела запроса, отправляемые с сервера в контейнер — они отправляются со стандартным заголовком пакета ( Веб-сервер может отправлять контейнеру сервлетов следующие сообщения:
Чтобы обеспечить некоторую базовую безопасность, контейнер будет фактически выполнять только в том
Первый Контейнер сервлета может отправлять на веб-сервер следующие типы сообщений:
Каждое из приведенных выше сообщений имеет различную внутреннюю структуру, подробно описанную ниже. Структура пакета запросаДля сообщений с сервера в контейнер типа Forward Request : AJP13_FORWARD_REQUEST := префикс_код (байт) 0x02 = JK_AJP13_FORWARD_REQUEST метод (байт) протокол (строка) req_uri (строка) remote_addr (строка) удаленный_хост (строка) имя_сервера (строка) порт_сервера (целое число) is_ssl (логическое значение) num_headers (целое число) request_headers *(req_header_name req_header_value) атрибуты *(имя_атрибута значение_атрибута) request_terminator (байт) OxFF Имеют req_header_name := sc_req_header_name | (строка) [см. ниже, как это анализируется] sc_req_header_name := 0xA0xx (целое число) req_header_value := (строка) Они attribute_name := sc_a_name | (строка sc_a_req_attribute) attribute_value := (строка) Не то чтобы это был самый важный заголовок Подробное описание элементов Forward RequestПрефикс запросаДля всех запросов это будет 2. Подробнее о других кодах префиксов см. выше. МетодМетод HTTP, закодированный как один байт:
Более поздняя версия ajp13 будет передавать дополнительные методы, даже если их нет в этом списке. протокол, req_uri, удаленный_адрес, удаленный_хост, имя_сервера, порт_сервера, is_sslВсе это довольно очевидно. Каждый из них является обязательным и будет отправлен для каждого запроса. ЗаголовкиСтруктура следующая: сначала кодируется
Код Java, который читает это, захватывает первое двухбайтовое целое число, и если он видит Это работает в предположении, что никакие имена заголовков не будут иметь длину больше, чем Примечание:Заголовок content-length чрезвычайно важен. Если он присутствует и не равен нулю, контейнер предполагает, что у запроса есть тело (например, запрос POST), и немедленно считывает отдельный пакет из входного потока, чтобы получить это тело.
АтрибутыАтрибуты с префиксом
И в настоящее время И предположительно относятся к аутентификации на уровне HTTP и сообщают имя пользователя удаленного пользователя и тип аутентификации, используемый для установления его личности (например, базовая, дайджест) , ,
и относятся к соответствующим , используется Помимо этого списка основных атрибутов, любое количество других атрибутов может быть отправлено через Наконец, после того, как все атрибуты отправлены, Структура пакета ответадля сообщений, которые контейнер может отправить обратно на сервер. AJP13_SEND_BODY_CHUNK := префикс_код 3 chunk_length (целое число) чанк *(байт) chunk_terminator (байт) Ox00 AJP13_SEND_HEADERS := префикс_код 4 http_status_code (целое число) http_status_msg (строка) num_headers (целое число) response_headers * (res_header_name header_value) res_header_name := sc_res_header_name | (строка) [см. ниже, как это анализируется] sc_res_header_name := 0xA0 (байт) header_value := (строка) AJP13_END_RESPONSE := префикс_код 5 повторное использование (логическое значение) AJP13_GET_BODY_CHUNK := префикс_код 6 запрашиваемая_длина (целое число) Подробности:Отправить фрагмент телаФрагмент в основном представляет собой двоичные данные и отправляется непосредственно обратно в браузер. Отправить заголовкиКод состояния и сообщение являются обычными вещами HTTP (например,
После кода или имени заголовка строки сразу кодируется значение заголовка. Завершить ответСигнализирует об окончании этого цикла обработки запросов. Если
Получить кусок телаКонтейнер запрашивает дополнительные данные из запроса (если тело было слишком большим, чтобы поместиться в первый отправленный пакет или когда запрос разбит на части). Сервер отправит назад пакет тела с объемом данных, который является минимальным из Пункты: 85 86 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 163 164 165 166 167 168 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 203 204 205 206 207 208 209 210 211 212 213 |