request.format возвращает */*

В настоящее время я разрабатываю API для своего приложения на RoR.

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

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

Но теперь мне нужно применить другое поведение, если запрос был сделан с XML или нет, что меня беспокоит, так это то, почему в контроллере request.format дает */*.

Любые подсказки?

curl -v -H "Content-Type: application/xml; charset=utf-8" --data-ascii @client.xml  http://foo.com:3000/clients?api_key=xxx

def create
  logger.debug request.format # produces "*/*"
  if request.format.xml?
    # never gets here 
  end
end

person Pedro Cunha    schedule 20.10.2009    source источник


Ответы (2)


*/* означает, что пользовательский агент принимает все форматы и не заботится о том, какой формат вы ему зададите. Я считаю, что Safari делает это, среди прочего. По умолчанию curl отправляет заголовок Accept */*.

Вот дамп заголовков, которые curl отправляет по умолчанию:

User-Agent: curl/7.18.1 (i386-apple-darwin9.6.0) libcurl/7.18.1 zlib/1.2.3
Host: example.com
Accept: */*
Content-Type: 

Однако в этом случае похоже, что вы хотите отправить обратно XML, если полезная нагрузка, отправленная вам, была XML? Если это так, вы хотите напрямую проверить заголовок Content-Type запроса. т. е. request.content_type - это метод, который вам нужен.

Дополнения: я еще немного подумал об этом, и я думаю, что лучший подход — сначала проверить request.format, и только если это неубедительно, проверить request.content_type. По сути, спецификация HTTP позволяет клиентам сообщать серверам: «Я даю вам XML, но я хочу вернуть JSON». Заголовок Accept — это то, как клиенты сообщают вам, что они хотят вернуть, и если кто-то действительно отправляет это, вы должны соблюдать это. Используйте Content-Type запроса только в качестве подсказки, если клиент не указал.

person Bob Aman    schedule 20.10.2009
comment
браузер? Хм, теперь вы меня запутали. Я отправляю запрос через командную строку, тип браузера не должен быть проблемой. - person Pedro Cunha; 20.10.2009

*/* просто означает, что принимаются все типы MIME.

В коде метода request.format определяется тип MIME. по расширению файла или, если его нет, по значению заголовка HTTP Accept. Таким образом, вам нужно либо передать Curl XML-файл, сохраненный на диске, либо заставить Curl установить для заголовка Accept тип XML MIME (например, text/xml), когда он делает запрос к вашему API.

person John Topley    schedule 20.10.2009
comment
Это неправильно. Он передает файл XML. Полезная нагрузка запроса не влияет на request.format. Вы должны обнаружить это вручную. Метод request.format использует компонент пути запрошенного URI для получения формата. Поэтому, если ваш URI заканчивается на .xml, он получит ожидаемое значение. Однако если цель состоит в том, чтобы предоставить единую конечную точку API, которая обрабатывает несколько типов содержимого, это не поможет. - person Bob Aman; 20.10.2009
comment
В настоящее время я использую тип содержимого как application/xml, измененный на text/xml, и он по-прежнему создает тот же формат request.format ( / ). Файл, переданный curl, сохраняется на диске - person Pedro Cunha; 20.10.2009
comment
@Yise Верно. Content-Type запроса не влияет на возвращаемое значение request.format. - person Bob Aman; 20.10.2009