При создании запроса через postman на аналогии статьи с confluence все получилось хорошо.
Указал заголовки:
X-Atlassian-Token: nocheck
Произвел Basic аутентификацию
В Body добавил файл с ключом file.
По итогу вернулся ответ 200 с телом, в котором описывается прикрепленный файл.
Задача стояла следующая для прикрепленных файлов (БСП) в документе по кнопке отправлять эти файлы в JIRA.
Начал с простого, прикрепил txt файл к документу, чтобы не шаманить в content type.
Покопался в документации БСП, так как сам являюсь начальным программистом на 1С, нашел модуль РаботаСФайлами и написал простенькие функции.
И так что у меня по итогу есть:
Процедура, которая возвращает массив присоединенных файлов:
&НаСервере
Функция ПолучитьДанныеФайловНаСервере()
ПрисоединенныеФайлы = Новый Массив;
ДанныеФайлов = Новый Массив;
РаботаСФайлами.ЗаполнитьПрисоединенныеФайлыКОбъекту(ВладелецФайла, ПрисоединенныеФайлы);
Если ПрисоединенныеФайлы.Количество() > 0 Тогда
Для Каждого ПрисоединенныйФайл из ПрисоединенныеФайлы Цикл
ДанныеПрисоединенногоФайла = РаботаСФайлами.ДанныеФайла(ПрисоединенныйФайл);
ДанныеФайлов.Добавить(ДанныеПрисоединенногоФайла);
КонецЦикла;
КонецЕсли;
Возврат ДанныеФайлов;
КонецФункции
Показать
И собственно мой код по отработке этих файлов, о нем поподробнее:
&НаСервере
Процедура ОтработатьПрисоединенныеФайлыНаСервере()
//Здесь я получаю массив с прикрепленными файлами
ДанныеФайлов = ПолучитьДанныеФайловНаСервере();
Если ДанныеФайлов.Количество() > 0 Тогда
//Проверяю заполнение реквизитов в документе дял интеграции с JIRA
Отказ = Ложь;
ПроверитьЗаполнениеОсновныхРеквизитовJIRA(Отказ);
Если Отказ Тогда
Возврат;
КонецЕсли;
//Получаю из собственного РС ОбщиеНастройки параметры для подключения
//
//ПараметрыJIRA.Протокол - протокол для соединения
//ПараметрыJIRA.Сервер - сервер, где у меня равзернута JIRA
//ПараметрыJIRA.Порт - Порт для подключения по умолчанию для JIRA 8080
//ПараметрыJIRA.RESTAPI - ссылка на rest API
//ПараметрыJIRA.КлючJIRA - ключ проекта JIRA
//ПараметрыJIRA.Пользователь
//ПараметрыJIRA.Пароль
//
ПараметрыJIRA = ПолучитьПараметрыJIRAНаСервере();
//Подключаюсь по HTTP к проекту и получаю Cookie, до этого этим не занимался, думал проблема в этом
Cookie = ПолучитьКукиJIRA(Отказ, ПараметрыJIRA);
//Начинаю перебирать файлы для отправки по http и прикреплению к задаче
Для Каждого ПрисоединенныйФайл из ДанныеФайлов Цикл
//Так как в отличие от Postman файл находится в двоичных данных пришлось почитать rfc7578 и понять, что для передачи таких файлов, чтобы не сохранять их на локалку
//а у меня все работает на сервере, необходимо пользоваться методом multipart/form-data
//Получаю двоичные данные файла
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(ПрисоединенныйФайл.СсылкаНаДвоичныеДанныеФайла);
//Проверяю не пустой ли файл
Если ДвоичныеДанныеФайла <> Неопределено Тогда
//Получаю значение для заголовка авторизации base64
КодированнаяСтрока = ЗашифроватьBase64Сервер(ПараметрыJIRA.Пользователь+":"+ПараметрыJIRA.Пароль);
Авторизация = "Basic " + КодированнаяСтрока;
//Определяю Boundary
Boundary = "------------------------------63a4b224c59f";
//Проверяю какой у меня стоит протокол в настройках и при необходимости устанавливаю ssl
Если ПараметрыJIRA.Протокол="https://" Тогда
ssl = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
Иначе
ssl = Неопределено;
КонецЕсли;
//Новое соединение
Соединение = Новый HTTPСоединение(
ПараметрыJIRA.Сервер, //Сервер
ПараметрыJIRA.Порт, //Порт
,,, //Пользователь/Пароль/Прокси
1000, //Таймаут
ssl //Защищенное соединение
);
//Для отладки создаваемового файла генерирую имя нового файла
Каталог = КаталогВременныхФайлов();
ИмяФайла = Строка(Новый УникальныйИдентификатор) + ".txt";
ИмяВременногоФайла = Каталог + ИмяФайла;
#Область ПотокВерсияПервая
//Создаю новый поток, куда пишу тело запроса
ПотокТело = Новый ПотокВПамяти();
ЗаписьДанных = Новый ЗаписьДанных(ПотокТело);
ЗаписьДанных.ЗаписатьСтроку(Boundary);
ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""file""; filename="""+ ПрисоединенныйФайл.ИмяФайла +"""");
ЗаписьДанных.ЗаписатьСтроку("Content-Type: text/plain; charset=""utf-8""");
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.Записать(ДвоичныеДанныеФайла);
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.ЗаписатьСтроку(Boundary);
ЗаписьДанных.Закрыть();
#КонецОбласти
#Область ПотокВерсияВторая
//Второй вариант создания тела, где я передаю имя поля для записи
ПотокТело = Новый ПотокВПамяти();
ЗаписьДанных = Новый ЗаписьДанных(ПотокТело);
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.ЗаписатьСтроку(Boundary);
ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""field""");
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.ЗаписатьСтроку("attachment");
ЗаписьДанных.ЗаписатьСтроку(Boundary);
ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""file""; filename="""+ ПрисоединенныйФайл.ИмяФайла +"""");
ЗаписьДанных.ЗаписатьСтроку("Content-Type: text/plain; charset=""utf-8""");
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.Записать(ДвоичныеДанныеФайла);
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.ЗаписатьСтроку(Boundary);
ЗаписьДанных.Закрыть();
#КонецОбласти
//Получаю тело двоичных данных
ДвоичныеДанныеТело = ПотокТело.ЗакрытьИПолучитьДвоичныеДанные();
//Записываю файл для отладки
ДвоичныеДанныеТело.Записать(ИмяВременногоФайла);
//Создаю заголовки
ЗаголовкиHTTP = Новый Соответствие;
//Указываю данные для basic аутентификации, которую определил ранее
ЗаголовкиHTTP.Вставить("Authorization", Авторизация);
//Для JIRA обязательно указать данный заголовок, так как для метода multipart/form-data действует проверка на XSRF
ЗаголовкиHTTP.Вставить("X-Atlassian-Token", "nocheck");
//По идее в rfc сказано, что данный заголовок не обязательный
ЗаголовкиHTTP.Вставить("Content-Length", XMLСтрока(ДвоичныеДанныеТело.Размер()));
//Указываю boundary
ЗаголовкиHTTP.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);
//Передаю Cookie, опять же это уже я делаю из-за безысходности
ЗаголовкиHTTP.Вставить("Cookie", Cookie);
//Указываю ссылку на API, где "TEKITPL-51" ключ моей задачи, куда собираюсь прикрепить файлы
СсылкаНаРесурс = ПараметрыJIRA.RESTAPI + "/issue/TEKITPL-51/attachments";
HTTPЗапрос = Новый HTTPЗапрос(СсылкаНаРесурс,ЗаголовкиHTTP);
//Устанавливаю тело для запроса
HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеТело);
Попытка
HTTPОтвет = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
Исключение
ОписаниеОшибки = "Ошибка при выполнении HTTP запроса: " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки);
КонецПопытки;
//Смотрю что мне вернул запрос
Сообщить("Нам вернули код: " + HTTPОтвет.КодСостояния);
Сообщить("Тело результата: " + HTTPОтвет.ПолучитьТелоКакСтроку());
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Показать
По итогу выполнения запроса, мне возвращается:
Код ответа: 200
Тело ответа: "[]"
А в задаче JIRA соответственно нечего не прикрепляется
(4) На самом деле можно было и твой разделитель использовать, главное что бы тело запроса начиналось с "--"+Разделитель. И заканчивалось "--"+Разделитель+"--". Разделитель это то что ты передал в заголовке
//Указываю boundary
ЗаголовкиHTTP.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);
так как в rfc7578 и в сниппете postman этого не было.
А есть ли возможность авто определения Content-Type в теле запроса или это уже кем-то реализовано?)