Имя: Пароль:
1C
 
Почему Новый HTTPСоединение возвращает ошибку 500?
0 program345
 
07.04.25
13:43
привет форумчане!

Пытаюсь получить с сервера по Апи данные:

        ЗаголовокЗапроса = Новый Соответствие();
	ЗаголовокЗапроса.Вставить("Authorization", "корректный пароль");
	ЗаголовокЗапроса.Вставить("inn", "ввожу инн");
	ЗаголовокЗапроса.Вставить("kpp", "ввожу кпп");
	HTTP = Новый HTTPСоединение("mysite.ru/api/contract",,,,,,Новый ЗащищенноеСоединениеOpenSSL());
	ЗапросGET = Новый HTTPЗапрос("/", ЗаголовокЗапроса);
	Результат = HTTP.Получить(ЗапросGET);


возвращает ошибку 500.


вот описание апи в формате yml:

servers:
  - url: https://mysite.ru/api
paths:
  /contract:
    get:
      summary: Активный договор по реквизитам (ИНН/КПП)
      operationId: getContract
      parameters:
        - in: query
          name: inn
          required: true
          schema:
            type: string
            example: "ИНН из договора"
        - in: query
          name: kpp
          schema:
            type: string
            example: "КПП из договора, необязательное поле, если КПП нет"
      tags:
        - Contract
      responses:
        "200":
          description: Возвращает текущий договор
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PromoContractDto"
        "401":
          description: Неавторизован
        "404":
          description: По реквизитам не найден договор
        default:
          $ref: "#/components/responses/BackEndError"


Куда копать?
1 Волшебник
 
07.04.25
13:44
500 - внутренняя ошибка сервера (BackEndError)
Обратитесь к админам сайта, куда вы подключаетесь, пусть разберутся.
2 Мультук
 
гуру
07.04.25
13:50
(0)

Сравни

HTTP = Новый HTTPСоединение("mysite.ru/api/contract",,,,,,Новый ЗащищенноеСоединениеOpenSSL());
ЗапросGET = Новый HTTPЗапрос("/", ЗаголовокЗапроса);


и

HTTP = Новый HTTPСоединение("mysite.ru",,,,,,Новый ЗащищенноеСоединениеOpenSSL());
ЗапросGET = Новый HTTPЗапрос("/api/contract/", ЗаголовокЗапроса);




Во избежании прочих "а как" ? Советую взять

https://github.com/vbondarevsky/Connector

Все примеры на русском, хотя... поможет ли это ?
3 program345
 
07.04.25
14:14
(2) сравнил

HTTP = Новый HTTPСоединение("mysite.ru/api/contract",,,,,,Новый ЗащищенноеСоединениеOpenSSL());
ЗапросGET = Новый HTTPЗапрос("/", ЗаголовокЗапроса);



и

HTTP = Новый HTTPСоединение("mysite.ru",,,,,,Новый ЗащищенноеСоединениеOpenSSL());
ЗапросGET = Новый HTTPЗапрос("/api/contract/", ЗаголовокЗапроса);


та же ошибка 500 (Internal Server Error).

Если убираю строку с аутентификацией (ЗаголовокЗапроса.Вставить("Authorization", "корректный пароль");) то ошибка уже 401.
4 программистище
 
07.04.25
14:18
(3) читаем (1), это шибка скрипта на который вы обращаетесь, на стороне сервера он не смог выполниться, и отдал ответ 500
5 Garykom
 
гуру
07.04.25
14:25
(3) тело ответа 500 какое?
обычно там в нормальных сервисах пишут что случилось
6 АгентБезопасной Нацио
 
07.04.25
14:25
Параметры Запроса от Заголовков запроса - отличаем?
7 Garykom
 
гуру
07.04.25
14:29
и уверен что parameters (inn, kpp) надо в заголовках запроса передавать?
может в строке (url) запроса?

ну типа
ЗапросGET = Новый HTTPЗапрос("/api/contract/?inn=...&kpp=...", ЗаголовокЗапроса);
8 vbus
 
07.04.25
15:07
HTTP = Новый HTTPСоединение("mysite.ru",443,,,,,Новый ЗащищенноеСоединениеOpenSSL());
ЗапросGET = Новый HTTPЗапрос("/api/contract/", ЗаголовокЗапроса);
Так тоже ошибка?
9 timurhv
 
07.04.25
15:12
(0) Что в заголовках Authorization передается и должно передаваться по документации?
10 BaZZiL
 
07.04.25
15:28
Пробуйте отправить запрос из Postman.
11 program345
 
08.04.25
11:35
(5) вот тело ответа.
12 Garykom
 
гуру
08.04.25
12:57
(11) это не тело ответа а заголовки
13 АгентБезопасной Нацио
 
08.04.25
11:39
(11)  а (6),(7)?
14 program345
 
08.04.25
11:40
(9) В ответ на аутентификацию пришел JSON access_token, из которого беру значение access_token и token_type

Аутентификация подставляется в заголовок запроса, параметр Aurhorization значение Bearer ACCESS_TOKEN
15 АгентБезопасной Нацио
 
08.04.25
11:57
(12) тело, заголовки, параметры - какая разница?
"Теорема о бесконечных обезьянах"® в действии
16 novichok79
 
08.04.25
11:58
curl -v mysite.ru/api/contract, увидите где падает
обычно клиент отправляет к серверу запросы с заголовком Authorization: Bearer <token>.

ЗаголовокЗапроса.Вставить("Authorization", "Bearer " + access_token);

но это как лечить геморрой по фотографии анального кольца.
в общем, вывод curl -v в студию
17 novichok79
 
08.04.25
11:57
странно, зачем вытащили Span-Id, обычно хватает X-Open-Telemetry-Trace-Id
(0) Span-Id и Trace-Id можно было не заблюривать, все равно их не посмотреть, не имея доступа к продовому zipkin/jaeger mysite
18 novichok79
 
08.04.25
12:01
кстати, да, иногда присылают refresh_token еще, чтобы новый access_token получить.
пока диагноз такой что просто неправильно передается Authorization заголовок после авторизации, сервис не может прочесть или найти Bearer и падает в какой-нибудь эксепшн или панику с internal error и 500-кой.
19 АгентБезопасной Нацио
 
08.04.25
12:29
(18) да все проще - он параметры в заголовках передает, а сервер удивляется, что запрос пришел без параметров, и чо ему отвечать-то? вот он 500 и отвечает...
20 Garykom
 
гуру
08.04.25
12:56
(19) а ведь говорят (15) могут войну и мир написать...
21 program345
 
08.04.25
14:51
(6)  пробовал передать параметры в строке (url) запроса, таже ошибка 500.

        ЗаголовокЗапроса = Новый Соответствие();
	ЗаголовокЗапроса.Вставить("Authorization", "корректный пароль");
	
	HTTP = Новый HTTPСоединение("mysite.ru/api/contract?inn=ввожу_инн&kpp=ввожу_кпп",,,,,,Новый ЗащищенноеСоединениеOpenSSL());
	ЗапросGET = Новый HTTPЗапрос("/", ЗаголовокЗапроса);
	Результат = HTTP.Получить(ЗапросGET);




(5) {"timestamp":"2025-04-08T11:46:10.849+00:00","status":500,"error":"Internal Server Error","path":"/api/contract"}
22 программистище
 
08.04.25
14:55
так может к руководствуй api обратиться, как параметры передвать
хотя mysite.ru говорит что это он его и пишет, тогда еще больше вопросов, как можно писать апи и не знать что делать
23 Garykom
 
гуру
08.04.25
14:56
(21) ты тупой и необучаемый
хотя бы СП почитай (HTTPСоединение, HTTPЗапрос)
и примеры рабочие

тебе выше уже написали что в HTTPСоединение надо указывать только адрес (домен или ip) сервера!
а строку запроса в HTTPЗапрос начиная с /
24 Garykom
 
гуру
08.04.25
15:00
HTTPСоединение (HTTPConnection)
HTTPСоединение (HTTPConnection)
По указанному серверу

Синтаксис:
Новый HTTPСоединение(<Сервер>, <Порт>, <Пользователь>, <Пароль>, <Прокси>, <ЗащищенноеСоединение>)
Параметры:
<Сервер> (обязательный)
Тип: Строка.
Хост сервера, с которым осуществляется соединение.
Примечание: Имя хоста не должно содержать указание протокола. Например, example.com.
<Порт> (необязательный)
Тип: Число.
Порт сервера, с которым осуществляется соединение.
Значение по умолчанию для HTTP соединений равно 80, для защищенных HTTPS соединений - 443.
Значение по умолчанию: порт по умолчанию для используемого протокола.
<Пользователь> (необязательный)
Тип: Строка.
Имя пользователя на указанном сервере.
<Пароль> (необязательный)
Тип: Строка.
Пароль пользователя на указанном сервере.
<Прокси> (необязательный)
Тип: ИнтернетПрокси.
Прокси, используемый для соединения с сервером.
<ЗащищенноеСоединение> (необязательный)
Тип: Булево.
Определяет используемый протокол:
Истина - HTTPs,
Ложь - HTTP.
Значение по умолчанию: Ложь.
Пример:
ПроксиСервер = Новый ИнтернетПрокси;
ПроксиСервер.Пользователь = ИмяПользователя;
ПроксиСервер.Пароль       = ПарольПользователя;
Попытка
    HTTP = Новый HTTPСоединение(СерверИсточник,,,, ПроксиСервер);
Исключение
КонецПопытки;


HTTPЗапрос (HTTPRequest)
HTTPЗапрос (HTTPRequest)
По адресу ресурса и заголовкам
Синтаксис:
Новый HTTPЗапрос(<АдресРесурса>, <Заголовки>)
Параметры:
<АдресРесурса> (обязательный)
Тип: Строка.
Адрес ресурса, к которому будет происходить HTTP-запрос.
Адрес указывается в виде строки, которая автоматически кодируется под требования стандарта RFC 3986, с учетом особенностей:
не кодируются разделители сегментов пути,
если адрес ресурса содержит символ "%", то считается, что после него указан код закодированного символа и повторно он не кодируется.
Недопустимые символы, не являющиеся специальными символами URI, будут автоматически кодированы.
Примеры:
Обращение к ресурсу по адресу "/example%segment":
/example%25segment

Обращение к ресурсу "/example#segment", содержащему символ "#", в качестве сегмента, а не разделителя сегмента пути:
/example%23segment

Обращение к ресурсу "/пример"("/%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80"):
"/пример"

или
"/%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80"
<Заголовки> (необязательный)
Тип: Соответствие.
Содержит заголовки в виде соответствия "Название заголовка" - "Значение".
Описание:
Создает объект по адресу ресурса и заголовкам.

25 program345
 
08.04.25
15:02
(19) Странно, но когда передаю параметры через тело в JSON
ошибка уже 404:

        
        ЗаголовокЗапроса = Новый Соответствие();
	ЗаголовокЗапроса.Вставить("Authorization", "корректный пароль");


        ЗаписьJS = Новый ЗаписьJSON();
        ЗаписьJS.УстановитьСтроку();
        ЗаписатьJSON(ЗаписьJS, Новый Структура("inn, kpp", "мой инн", "мой кпп"));
        ТекстJSON = ЗаписьJS.Закрыть();    

	
	HTTP = Новый HTTPСоединение("mysite.ru/api/contract",,,,,,Новый ЗащищенноеСоединениеOpenSSL());
	ЗапросGET = Новый HTTPЗапрос("/", ЗаголовокЗапроса);
        ЗапросGET.УстановитьТелоИзСтроки(ТекстJSON);
	Результат = HTTP.Получить(ЗапросGET);


26 Мультук
 
гуру
08.04.25
15:07
(25)

Я в (2) намекнул. Привёл библиотеку "для тех кто в танке"

В (23) (24) уже открытым текстом написали, а он всё своё.


HTTP = Новый HTTPСоединение("mysite.ru/api/contract",,,,,,Новый ЗащищенноеСоединениеOpenSSL());
27 Garykom
 
гуру
08.04.25
15:05
(25) GET с передачей тела - это недоступная из 1С фишка
по стандарту HTTP вроде и разрешено, но на практике куча серверов/сервисов/клиентов такое не умеют
28 АгентБезопасной Нацио
 
08.04.25
15:08
(25) Ошибка в ДНК
29 Garykom
 
гуру
08.04.25
15:09
(27)+ хотя может в новых версиях платформы 1С уже и разрешили
раньше если делать GET (неважно через Получить или ВызватьHTTPМетод)
то тело тупо резалось и не передавалось
30 Garykom
 
гуру
08.04.25
15:11
(29)+ СП глянул в свежих и там
Примечание:
При использовании метода GET тело запроса на сервер отправлено не будет.
31 program345
 
08.04.25
15:13
+ когда указал порт 443 в адресной строке тоже 404

        
        ЗаголовокЗапроса = Новый Соответствие();
	ЗаголовокЗапроса.Вставить("Authorization", "корректный пароль");
	ЗаголовокЗапроса.Вставить("inn", "ввожу инн");
	ЗаголовокЗапроса.Вставить("kpp", "ввожу кпп");
	HTTP = Новый HTTPСоединение("mysite.ru/api/contract",443,,,,,Новый ЗащищенноеСоединениеOpenSSL());
	ЗапросGET = Новый HTTPЗапрос("/", ЗаголовокЗапроса);
	Результат = HTTP.Получить(ЗапросGET);
32 Garykom
 
гуру
08.04.25
15:18
(31) у тебя китайцев в родне не было?
из анекдота про пароль?
33 Garykom
 
гуру
08.04.25
15:19
Китайцы взломали сервер Пентагона и вот как им это удалось:
1. Каждый китаец попробовал один пароль.
2. Каждый второй пароль был "Мао Цзедун"
3. На 74357181-й попытке- сервер согласился, что у него пароль "Мао Цзедун"
34 Мультук
 
гуру
08.04.25
15:22
(31)

1С считает, что имя сайта
mysite.ru

А вовсе не
mysite.ru/api/contract
35 программистище
 
08.04.25
15:24
походу это бот
человек 404
36 АгентБезопасной Нацио
 
08.04.25
15:41
(35) боты вроде как обучаемы...
37 novichok79
 
09.04.25
14:13
(31) передавать надо в query строке.
тут же написано все, даже тип и DTO в ответе.
```
/contract:
    get:
      summary: Активный договор по реквизитам (ИНН/КПП)
      operationId: getContract
      parameters:
        - in: query
          name: inn
          required: true
          schema:
            type: string
            example: "ИНН из договора"
        - in: query
          name: kpp
          schema:
            type: string
            example: "КПП из договора, необязательное поле, если КПП нет"
      tags:
        - Contract
      responses:
        "200":
          description: Возвращает текущий договор
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PromoContractDto"
        "401":
          description: Неавторизован
        "404":
          description: По реквизитам не найден договор
        default:
          $ref: "#/components/responses/BackEndError"
```

на 1с не писал уже 4 года, наверное вот так
access_token - это то что тебе возвращается при авторизации в теле ответа видимо.
```
        ЗаголовокЗапроса = Новый Соответствие();
    ЗаголовокЗапроса.Вставить("Authorization", "Bearer " + access_token);
        // порт можно опустить ты же SSL делаешь.
    HTTP = Новый HTTPСоединение("mysite.ru", , , , , , Новый ЗащищенноеСоединениеOpenSSL());
    ЗапросGET = Новый HTTPЗапрос("/api/contract?inn=" + "ввожу инн" + "&kpp=" + "ввожу kpp", ЗаголовокЗапроса);
    Результат = HTTP.Получить(ЗапросGET);
```
вернется вот эта залупа #/components/schemas/PromoContractDto
наверное как-то так

параметры запроса (query params) != заголовки запроса (request headers).
для того чтобы понимать как работает HTTP, достаточно посмотреть на http запрос на уровне TCP/IP, там достаточно просто реализовано - кусок текста отправляется в порт
38 программистище
 
08.04.25
15:44
(36) ну они учатся то:
задача - решение
а тут только задача, а его посылают почитать
39 KJlag
 
08.04.25
15:46
(0) оффтоп, но все же спрошу: знаешь ли такие ники как найтхантер или ливингстар?
40 Волшебник
 
08.04.25
23:22
(39) у него есть слабая зацепка (3% сходства) на ник sidalexsandr
41 program345
 
09.04.25
09:15
(10) постман неплохая штука. Походу там на стороне сервака что-то изменилось. В 1c в этом отношении тяжелее отлаживать http запросы.

А как в постмане брать параметр access_token (B3bQMMXCiQ2k) и token_type (Bearer) из ответа post и подставлять в заголовок следующего запроса get?



(37) смущало описание parameters:

        - in: query (в параметрах url??)

до этого получаю токен через --header (как я понимаю заголовок)

пока не прочилал:
параметры запроса (query params) != заголовки запроса (request headers).

4.8.12.1 Местоположения Параметров
Существует четыре возможных местоположения параметра, определяемых полем in:

path – Используется вместе с шаблонизацией пути (Path Templating), где значение параметра фактически является частью URL операции. Это не включает хост или базовый путь API. Например, в /items/{itemId} параметром пути является itemId.

query – Параметры, добавляемые к URL. Например, в /items?id=### параметром запроса является id.

header – Пользовательские заголовки, ожидаемые в составе запроса. Согласно [RFC7230], раздел 3.2, имена заголовков нечувствительны к регистру.

cookie – Используется для передачи конкретного значения cookie в API.  https://spec.openapis.org/oas/latest.html#parameter-object

спасибо за помощь!
42 craxx
 
09.04.25
08:56
(39) Не, на Ливингстара не похож. Кстати, имел честь лично лицезреть.
43 АгентБезопасной Нацио
 
09.04.25
09:45
(42) это он внешне не похож. А интеллектуально - вполне.
44 Garykom
 
гуру
09.04.25
13:50
Postman это не для тру-прогов а для смузи-аналитиков
Для тру-прогов: wiki:CURL
45 novichok79
 
09.04.25
14:12
> постман неплохая штука.

insomnia еще лучше, но в сложных кейсах только curl и аналогичные.
есть еще bloomrpc, но он лучше для grpc запросов.

> А как в постмане брать параметр access_token (B3bQMMXCiQ2k) и token_type (Bearer) из ответа post и подставлять в заголовок следующего запроса get?

наверное из тела ответа авторизационного запроса?
ну или из кук

> - in: query (в параметрах url??)

swagger spec в помощь

> 4.8.12.1 Местоположения Параметров

жесть...
46 novichok79
 
09.04.25
14:12
(44) +10000000000005000000000000
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший