Доступ к HTTP-запросу (заголовки, строка запроса, куки, тело) в лямбда с конечной точкой http

Я пытаюсь увидеть, как получить доступ к заголовкам запроса и значениям тела из с помощью лямбда-кода. Если тело запроса находится в формате JSON, оно автоматически, по-видимому, анализируется и становится доступным в объекте события.

Как я могу получить доступ к полной строке запроса, телу запроса, заголовкам запроса (куки) для любого типа входящего запроса "Content-Type" внутри Lambda?


Ниже перечислены данные, которые я собрал, чтобы помочь решить вопрос, который может быть или не быть релевантным. Пожалуйста, проигнорируйте их, если хотите.


EDIT:

Я рассмотрел существующие вопросы по SE здесь и здесь. В соответствии с этим thread использование $input.json('$') должно сделать трюк. Я полагаю, что ответы на эти выше ссылки уже устарели, поскольку шлюз API по умолчанию, по-видимому, распознает JSON в запросе, и если это делает его доступным в объекте event без настройки шаблонов сопоставления.

Настройка отображения, как было предложено, не работает для меня. Он не содержит информацию заголовка запроса.

Вот скриншоты о том, как он настроен.

введите описание изображения здесь


введите описание изображения здесь

Ключ "заголовки" возвращает пустое значение. Использование ошибок $input.params('$') или "$input.params('$')".


ИЗМЕНИТЬ 2

Пробовал определять заголовки в запросе метода. Все еще не получает значение User-Agent внутри lambda.

введите описание изображения здесь


ИЗМЕНИТЬ 3

Я использовал следующее сопоставление шаблонов в шлюзе API

{
    "request": $input.json('$'),
    "headers": "$input.params()"
}

и ниже код в lambda

context.succeed("event.key32:"+JSON.stringify(event, null, 2) );

И ответ, созданный шлюзом API, показывает это введите описание изображения здесь

Рассматривая значение "заголовков" в ответе, похоже, что шлюзы AWS-SDK/API/облачные полосы удаляются из всех заголовков, полученных от HTTP-клиента? Вот полный текст из JSON, возвращаемый заголовком $input.params().

header={CloudFront-Forwarded-Proto=https, CloudFront-Is-Desktop-Viewer=true, CloudFront-Is-Mobile-Viewer=false, CloudFront-Is-SmartTV-Viewer=false, CloudFront-Is-Tablet-Viewer=false, Content-Type=application/json, Via=1.1 5d53b9570d94ce920abbd471.cloudfront.net (CloudFront), 1.1 95eea7baa7ec95c9a41eca9e3ab7.cloudfront.net (CloudFront), X-Amz-Cf-Id=GBqmObLRy6Iem9bJbVPrrW1K3YoWRDyAaMpv-UkshfCsHAA==, X-Forwarded-For=172.35.96.199, 51.139.183.101, X-Forwarded-Port=443, X-Forwarded-Proto=https}}

В заголовке нет строки User-Agent, хотя, как показано выше, снимок экрана был отправлен клиентом REST. Интересно, что вся строка запроса доступна. Не уверен, что это предназначен для доступа к нему.

Ответ 1

Доступ к заголовкам запросов можно получить с помощью $input.params('header-name')

Удивительно, что к заголовку User-Agent не удается получить доступ с помощью вышеуказанного кода. Вам нужно перепрыгнуть через следующее обруч, чтобы получить его:

$context.identity.userAgent

Тело запроса/полезная нагрузка должны быть доступны с использованием следующего кода. Больше ссылок здесь, здесь и здесь:

{
   "reqbody": "$input.path('$')"
}

Пока неясно, будет ли тело запроса находиться в JSON. Следует отметить, что запрос обрабатывается как UTF-8 в соответствии с этот пост.


В настоящее время существует два ошибки:

  • Заголовок "User-Agent" отсутствует/удаляется API-интерфейсом Amazon.
  • Когда значения заголовка содержат двойную кавычку ("), функция лямбда не выполняется. (я не вижу записи журнала в журналах облачного просмотра для таких запросов)., тело ответа http содержит следующее:

    {
       "Type": "User",
       "message": "Could not parse request body into json."
    }
    

Пример запроса, который не работает в API Amazon введите описание изображения здесь

Я считаю, что это должно быть исправлено, чтобы иметь возможность реализовать механизм ETag для кэширования.

Литература:

Предполагается, что Etag будет заключен в двойные кавычки. Ожидается, что браузер отправит это точное значение через заголовок If-None-Match, и здесь разрывается API Amazon.

Синтаксис для ETag?

HTTP: максимальная длина etag

http://gsnedders.com/http-entity-tags-confusion

Ответ 2

Кажется, что если "Content-Type" не отправлен, AWS API Gateway по умолчанию использует его "application/json": https://forums.aws.amazon.com/thread.jspa?threadID=215471

Итак, просто определите шаблон сопоставления для "application/json".

Ответ 3

Вы должны получить необходимую информацию в сопоставлении шаблонов и отправить их обратно своей функции Lambda, это один из шаблонов, которые я использовал для отправки информации в функцию лямбда:

{
   "params" : "$input.params()",
   "content-type-value" : "$input.params().header.get('Content-Type')",
   "body" : "$input.json('$')",
   "request-id": "$context.requestId",
   "method": "$context.httpMethod",
   "resource": "$context.resourcePath",
   "id": "$input.params('id')" //This is a path parameter in my case
}

Вы можете сделать то же самое, или вы можете получить доступ к params.path.id (опять же в моем случае). Вот ссылка в документацию.

Приветствия,

Ответ 4

Я обновил шаблон сопоставления, который я использовал в ответе на один из ссылочных вопросов, чтобы содержать свойство userAgent.

{
  "method": "$context.httpMethod",
  "body": $input.json('$'),
  "userAgent": "$context.identity.userAgent",
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "queryParams": {
    #foreach($param in $input.params().querystring.keySet())
    "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "pathParams": {
    #foreach($param in $input.params().path.keySet())
    "$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end

    #end
  }  
}

Подробное описание шаблона доступно здесь: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api-gateway/