Как правильно загрузить архивированный проект на Checkmarx по API?

Возникли проблемы при попытке загрузки архивированного проекта на сервис Checkmarx.

  1. Пробовал загрузить архив, следуя документации 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, где все операции производятся автоматически, была получена точно такая же ошибка.

  1. Листинг загрузки через 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. Проект архивировал разными способами:

  1. 7zip
  2. python.shutil.make_archive()
  3. Cx7zip

На результат это не повлияло


Ответы (1 шт):

Автор решения: SemaTheSlayer

Решение было найдено. Для успешной загрузки необходимо правильно создать объект с метаданными архива (переменная 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)
→ Ссылка