Как правильно загрузить архивированный проект на Checkmarx по API?
Возникли проблемы при попытке загрузки архивированного проекта на сервис Checkmarx.
- Пробовал загрузить архив, следуя документации Checkmarx SAST API: документация
import requests
def upload_source(token: str, path_to_archive: str, host: str, project_id: int) -> None:
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json;v=1.0',
'Authorization': 'Bearer {token}'
}
data = {'zippedSource': open(path_to_archive, 'rb').read()}
response = requests.post(f'{host}/projects/{project_id}/sourceCode/attachments',
headers=headers, data=data)
Получил следующий ответ от сервера:
{
"messageCode": 27000,
"messageDetails": "The requested file not found in Http-Message body"
}
На первый взгляд, вероятная проблема может быть в неправильно составленных заголовках, либо в чтении архива, но при использовании библиотеки CheckmarxPythonSDK, где все операции производятся автоматически, была получена точно такая же ошибка.
- Листинг загрузки через SDK:
from CheckmarxPythonSDK.CxRestAPISDK import ProjectsAPI
def upload_source(path_to_archive: str, project_id: int) -> None:
cx_loader = ProjectsAPI()
cx_loader.upload_source_code_zip_file(project_id, path_to_archive)
Под капотом SDK составляющие запроса выглядят следующим образом. Попытка использовать эти составляющие в первом примере не дали результата.
data = {"zippedSource": ("archive_name", open('path_to_arhive', 'rb'), "application/zip")}
headers = {
'Content-Type': 'multipart/form-data; boundary=1d8174c7f75344e0b5dcd64a9f874c1a',
'cxOrigin': 'Checkmarx Python SDK 1.0.5',
'Authorization': f'Bearer {token}'
}
Запуск скриптов осуществлялся через WSL Ubuntu. Проект архивировал разными способами:
- 7zip
- python.shutil.make_archive()
- Cx7zip
На результат это не повлияло
Ответы (1 шт):
Решение было найдено. Для успешной загрузки необходимо правильно создать объект с метаданными архива (переменная files) и убрать лишние заголовки.
import requests
def upload_source(token: str, source_path: str, host: str, project_id: int) -> None:
with open(source_path, "rb") as binary_file:
file = binary_file.read()
url = f'{host}/projects/{project_id}/sourceCode/attachments'
files = {"zippedSource": ("source.zip", file, "application/zip")}
headers = {'Authorization': f'Bearer {token}'}
requests.post(url, headers=headers, files=files)