Таблица Apache HTTPD mod_lua parseargs mutlivalue не сохраняет все значения

В настоящее время я пишу тестовую обвязку, которая вводит задержки, сбои и проксирование с использованием httpd со сценариями LUA. Это включает в себя синтаксический анализ строки запроса, которая может содержать несколько значений для одного и того же тега, т.е.:

?ref=12345678&ref=01012052&ref=30257523 

Затем это позволяет задержать сообщение в определенных точках потока сообщений или перенаправить определенные запросы на альтернативную конечную точку. Моя проблема связана с тем, что доступно для работы в предоставленных таблицах LUA.

Проблема, с которой я сталкиваюсь, заключается в том, что при использовании чего-то вроде приведенного ниже кода с приведенной выше строкой запроса просто выйти из системы, с какими значениями он работает:

function output_multi_values(r)
  local queryString, queryStringMulti = r:parseargs()
    for queryStringKey, queryStringValue in pairs(queryStringMulti) do
      r:err(queryStringKey .. "," .. queryString[queryStringKey] .. "," .. tostring(queryStringMulti[queryStringKey]) .. "," .. tostring(queryStringValue))
      for multiKey, multiValue in pairs(queryStringMulti[queryStringKey]) do
        r:err(queryStringKey .. "," .. multiKey .. "," .. multiValue)
      end
    end
  return 0
end

регистрируются только те элементы, которые относятся к окончательному предоставленному значению ref:

[Wed Jun 07 10:24:43.923877 2017] [lua:error] [pid 1370:tid 140336118597376] [client 192.168.56.101:43980] ref,30257523,table: 0x7fa264010810
[Wed Jun 07 10:24:43.923948 2017] [lua:error] [pid 1370:tid 140336118597376] [client 192.168.56.101:43980] ref,1,30257523

Как мы видим, в первой записи журнала он знает, что значение для ref — это таблица, но при повторении по этой таблице возвращается только 1 запись с последним предоставленным значением. Кроме того, стандартная таблица также включает только предоставленное окончательное значение, хотя я не уверен, что здесь должно быть, и не заинтересован.

Я считаю, что следую правильной процедуре для parseargs, как указано в документации mod_lua, который повторяет мои ожидания в отношении моей функции, но не дает примера того, как обрабатывать многозначную часть.

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

Есть ли какой-то другой способ, которым я должен просматривать многозначную таблицу для ref?

Сведения о среде

Серверное оборудование - Oracle VirtualBox 5.1.16 r113841 (2 ГБ ОЗУ, 2 ядра ЦП, 32 ГБ жесткий диск).

Серверная ОС — Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-78-универсальная x86_64).

Версия Apache httpd — версия сервера: Apache/2.4.18 (Ubuntu), сборка сервера: 2017-05-05T16:32:00. Устанавливается с использованием канонического репозитория Ubuntu.

Веб-клиент — выбирайте сами, не зависит от клиента (curl, wget, firefox 44, chrome, jmeter)

Еще немного информации

Включение различных тегов в строку запроса приводит к обработке всех тегов, но опять же, сохраняется только последнее значение для каждого тега. Строка запроса:

?ref=12345678&ref=01012052&ref=30257523&dob=01062017&dob=0101970

приводит к регистрации только следующего:

[Wed Jun 07 10:35:15.627686 2017] [lua:error] [pid 1369:tid 140336076633856] [client 192.168.56.101:43982] dob,0101970,table: 0x7fa25c0108f0
[Wed Jun 07 10:35:15.627774 2017] [lua:error] [pid 1369:tid 140336076633856] [client 192.168.56.101:43982] dob,1,0101970
[Wed Jun 07 10:35:15.627786 2017] [lua:error] [pid 1369:tid 140336076633856] [client 192.168.56.101:43982] ref,30257523,table: 0x7fa25c010810
[Wed Jun 07 10:35:15.627795 2017] [lua:error] [pid 1369:tid 140336076633856] [client 192.168.56.101:43982] ref,1,30257523

Также я знаю, что мне не следует использовать r: err, но это пониженный уровень ведения журнала установки apache, и я не могу его изменить, поэтому err обеспечил получение журналов.

В apache2 загружены следующие модули:

 core_module (static)
 so_module (static)
 watchdog_module (static)
 http_module (static)
 log_config_module (static)
 logio_module (static)
 version_module (static)
 unixd_module (static)
 access_compat_module (shared)
 alias_module (shared)
 auth_basic_module (shared)
 authn_core_module (shared)
 authn_file_module (shared)
 authz_core_module (shared)
 authz_host_module (shared)
 authz_user_module (shared)
 autoindex_module (shared)
 deflate_module (shared)
 dir_module (shared)
 env_module (shared)
 filter_module (shared)
 lbmethod_bybusyness_module (shared)
 lbmethod_byrequests_module (shared)
 lbmethod_bytraffic_module (shared)
 lbmethod_heartbeat_module (shared)
 lua_module (shared)
 mime_module (shared)
 mpm_event_module (shared)
 negotiation_module (shared)
 proxy_module (shared)
 proxy_ajp_module (shared)
 proxy_balancer_module (shared)
 proxy_http_module (shared)
 setenvif_module (shared)
 slotmem_plain_module (shared)
 slotmem_shm_module (shared)
 socache_shmcb_module (shared)
 ssl_module (shared)
 status_module (shared)

person Stuart Kenworthy    schedule 07.06.2017    source источник


Ответы (1)


при поиске другой проблемы мне пришлось изучить вашу. Я так обнаружил, что функция ap_args_to_table в коде сервера использует apr_table_set. Эта функция всегда перезаписывает запись таблицы с равным ключом, поэтому результатом, который вы получаете, всегда является таблица с одной строкой только с последним значением многозначного параметра строки запроса, имя которого является ключом. Документы недостаточно ясны, чтобы решить, является ли это ошибкой в ​​util_script.c (код сервера) или в lua_request.c (код модуля). В любом случае, я получил правильное поведение, немного изменив последний, который я также исправил, чтобы set_output_filter() работал. Я просто загружаю патч сюда: https://bz.apache.org/bugzilla/show_bug.cgi?id=62369

person Massimiliano Calandrelli    schedule 10.05.2018