Отправка PUT запроса средствами 1С 8.3

Программирование - Практика программирования

HTTP запрос с использованием метода PUT средствами 1С 8.3 на практике - проблема и решение

При разработке процедуры отправки на сайт информации из 1С с версией платформы 8.3.9.2170 столкнулся с проблемой: разработчик сайта предоставил мне возможность записывать нужную информацию только при помощи HTTP запроса методом PUT.

Недолго думая, я набросал простенький код:
    Соединение = Новый HTTPСоединение("www.mysite.ru");
    Заголовки = Новый Соответствие;
    Заголовки["Content-Type"] = "application/x-www-form-urlencoded";
    Запрос = Новый HTTPЗапрос("/api/order_items/93076?order_item[qnt_income]=30", Заголовки);
    Соединение.Записать(Запрос);

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

Однако, как вы уже наверно поняли, ничего не произошло. После того как я убедился, что на сайте ошибок нет  (путем отправки аналогичного запроса через плагин к Хрому), я запустил на своем локальном компьютере web-сервер и стал экспериментировать.
Сразу же выяснилась странная вещь: вышеприведенный код генерирует не PUT, а HEAD запрос!
В логах апача я увидел следующее:
127.0.0.1 - - [16/Feb/2017:14:38:54 +0400] "HEAD /api/order_items/93076?order_item[qnt_income]=30 HTTP/1.1"
Я немного удивился (в руководстве ведь было черным по белому написано PUT), но не растерялся - можно ведь вызвать метод напрямую:
Соединение.ВызватьHTTPМетод("PUT",Запрос);
В логах то же самое:
127.0.0.1 - - [16/Feb/2017:14:40:52 +0400] "HEAD /api/order_items/93076?order_item[qnt_income]=30 HTTP/1.1"
"Может быть я что-то не так делаю?" - задал я себе вопрос. Но в интернете и в мануалах не было никаких подсказок. Что ж, метод научного тыка еще никто не отменял. Для начала я попробовал сделать так: 
Соединение.ВызватьHTTPМетод("фывфыв",Запрос);
В логах получил:
127.0.0.1 - - [16/Feb/2017:14:53:03 +0400] "?????? /api/order_items/93076?order_item[qnt_income]=30 HTTP/1.1"

Любопытно, значит 1С заменяет конкретно метод PUT (чем же он 1С не угодил?).

После еще нескольких попыток я пришел к варианту: 
Соединение.ВызватьHTTPМетод("PUT ",Запрос);
В логах получил:
127.0.0.1 - - [16/Feb/2017:14:53:03 +0400] "PUT  /api/order_items/93076?order_item[qnt_income]=30 HTTP/1.1"

И уже этот вариант отработал на сайте и все остались довольны.

UPD.

Алексей 1 (AlX0id)  подсказал более корректное решение проблемы: необходимо задать тело запроса, любое, даже пустое. Например, сработает такой вариант:
    Соединение = Новый HTTPСоединение("www.mysite.ru");
    Заголовки = Новый Соответствие;
    Заголовки["Content-Type"] = "application/x-www-form-urlencoded";
    Запрос = Новый HTTPЗапрос("/api/order_items/93076?order_item[qnt_income]=30", Заголовки);
    Запрос.УстановитьТелоИзСтроки("", КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); 
    Соединение.Записать(Запрос);

И уже совсем правильно, наверное, передавать в теле запроса сами значения параметров.

Вывод следующий: PUT запрос без тела платформа 1С считает ошибочным и заменяет метод на HEAD.
Любопытно что POST запрос без тела 1С никак не отслеживает и не превращает в GET, проверял ради спортивного интереса.
Как сказал бы всем известный Вовочка из знаменитого анекдота: "Где логика?".

Надеюсь кому-то моя публикация сбережет несколько часов жизни в поисках ответа. =)))

См. также

Комментарии
1. Евгений Бочкарев (Ликреонский) 76 17.02.17 08:11 Сейчас в теме
Странно:
Соединение.ВызватьHTTPМетод("PUT",Запрос);
Соединение.ВызватьHTTPМетод("PUT ",Запрос);

Разница в один пробел и в этом все дело?
2. Виктор Щербенков (hspeed79) 59 17.02.17 09:26 Сейчас в теме
(1) да, удивительно, но факт =)
3. Евгений Бочкарев (Ликреонский) 76 17.02.17 10:10 Сейчас в теме
(2)Чудны дела твои, Нуралиев :)
4. Петр Базелюк (pbazeliuk) 1290 17.02.17 10:49 Сейчас в теме
Спасибо, полезная информация.
5. Андрей Лукин (frkbvfnjh) 204 17.02.17 15:36 Сейчас в теме
Вам бы на форуме специалистов поднять это вопрос. Возможно это как всегда ошибка в платформе. Вы наверное первый кто воспользовался PUT в 1С. Есть чувство что сами разработчики даже проверять не стали...
6. Алексей 1 (AlX0id) 17.02.17 16:17 Сейчас в теме
(5)
ЗапросКСайту = Новый HTTPЗапрос(ТекстЗапроса,ЗаголовокЗапроса(Заголовки));
	
	Если Тело <> Неопределено Тогда
		ЗапросКСайту.УстановитьТелоИзСтроки(Тело, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); 
	КонецЕсли;
	
Результат = Соединение.ВызватьHTTPМетод("PUT", ЗапросКСайту, РезультатИмяФайла);
...Показать Скрыть


Так работало еще с полгода назад.
7. Sergey Andreev (starik-2005) 1041 17.02.17 16:42 Сейчас в теме
(6) все зависит от того, как работает. Если на стороне сайта нет разницы, пут пришел или хид, то и так сработает. Если с файлом генерится пут, то, видимо, какая-то мистика в 1С.
8. Сергей Галюк (dj_serega) 250 17.02.17 17:25 Сейчас в теме
(7)
на стороне сайта нет разницы

Я бы хотел уточнить. Может на стороне вебсервера сайта? :)
9. Алексей 1 (AlX0id) 17.02.17 18:51 Сейчас в теме
(7)
Полез проверять.. Думаю, вроде фиддлером все проверял, и в документации был именно PUT..
&НаКлиенте
Процедура Команда2(Команда)
	
	Тело = "фывафыва";
	Соединение = Новый HTTPСоединение("mysite.tk");
    Заголовки = Новый Соответствие;
    Заголовки["Content-Type"] = "application/x-www-form-urlencoded";
	Запрос = Новый HTTPЗапрос("/api/order_items/93076?order_item[qnt_income]=30", Заголовки);
	Запрос.УстановитьТелоИзСтроки(Тело, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); 
	Соединение.ВызватьHTTPМетод("PUT",Запрос);
	
КонецПроцедуры

&НаКлиенте
Процедура Команда3(Команда)
	
	Тело = "фывафыва";
	Соединение = Новый HTTPСоединение("mysite.tk");
    Заголовки = Новый Соответствие;
    Заголовки["Content-Type"] = "application/x-www-form-urlencoded";
	Запрос = Новый HTTPЗапрос("/api/order_items/93076?order_item[qnt_income]=30", Заголовки);
	Соединение.ВызватьHTTPМетод("PUT",Запрос);
	
КонецПроцедуры
...Показать Скрыть


Вот Команда2 - дает PUT. А Команда3 - уже HEAD. Так что, видимо, дело-то не в пробеле, а в отсутствии тела как такового..
yurii_host; Yimaida; +2 Ответить 1
10. Виктор Щербенков (hspeed79) 59 17.02.17 19:40 Сейчас в теме
(9) Понятно, добрая 1С не дает нам ошибиться и отеческой рукой меняет метод за нас.
Спасибо за подсказку, все таки у меня изначально был некорректный скрипт.
11. v p (vitaliy1911) 11 20.02.17 09:32 Сейчас в теме
да, сталкивался с этой проблемой. довольно странное поведение. вот тут поднимал эту тему http://www.forum.mista.ru/topic.php?id=784496
12. Дмитрий Кодник (kodnik) 67 20.02.17 10:57 Сейчас в теме
13. Андрей Овсянкин (Evil Beaver) 4202 12.03.17 08:40 Сейчас в теме
Ваабче-то, метод PUT (как и POST) предполагает наличие тела, т.е. именно того, что вы будете "Помещать" и "Постить". Без тела эти методы смысла не имеют. Другой вопрос, имеет ли право 1С подменять метод, если не видит тело. На мой взгляд, тут должно быть исключение, а не неочевидная замена на HEAD. Но в любом случае, без "тела" эти методы не должны применяться.
Оставьте свое сообщение