gitlab4j-api icon indicating copy to clipboard operation
gitlab4j-api copied to clipboard

RepositoryFileApi fails to upload large files (10MB+) due to application/x-www-form-urlencoded encoding

Open heyuqiang opened this issue 6 months ago • 1 comments

Description

When using RepositoryFileApi.createFile() or updateFile() in GitLab4J to upload a Base64-encoded file (~10MB ZIP), the request fails with HTTP 400.

Directly calling the GitLab API via curl with Content-Type: application/json works correctly.

Steps to Reproduce

Prepare a ZIP file test.zip (~10MB).

Use GitLab4J RepositoryFileApi to upload it as Base64 content:

RepositoryFile file = new RepositoryFile(); file.setFilePath("test.zip"); file.setContent(base64Content); file.setEncoding(org.gitlab4j.models.Constants.Encoding.BASE64);

RepositoryFileApi fileApi = gitLabApi.getRepositoryFileApi(); fileApi.createFile(projectId, file, "main", "add test.zip");

The API returns HTTP 400 Bad Request.

The server logs show (Rails / Workhorse):

{ "status":400, "written_bytes":11, "method":"PUT", "uri":"/api/v4/projects/2/repository/files/test.zip", "backend_id":"rails" }

Using curl works:

curl --request POST
--header "PRIVATE-TOKEN: $TOKEN"
--header "Content-Type: application/json"
--data '{ "branch": "main", "commit_message": "add test.zip", "content": "<BASE64>", "encoding": "base64" }'
"$GITLAB_URL/api/v4/projects/$PROJECT_ID/repository/files/test.zip"

Analysis

The GitLab4J post(Form formData, URL url) method sends the request as:

Entity.entity(formData.asMap(), MediaType.APPLICATION_FORM_URLENCODED_TYPE)

That is, the request uses application/x-www-form-urlencoded instead of application/json.

For large Base64 files, Rails cannot parse the form-encoded body → 400.

Small text files may succeed, which is why this only occurs for large files.

Expected Behavior

RepositoryFileApi should correctly upload large Base64 files (>10MB) using JSON requests.

Or GitLab4J should document the limitation and recommend using Project Upload API for large binary files.

Environment

GitLab4J version: 6.1.0

GitLab server version: gitlab-ce 18.3.0

Java version: jdk21

Suggested Solutions

Change RepositoryFileApi to send JSON with Content-Type: application/json.

Alternatively, clearly document that large binary files should use ProjectApi.uploadFile().

heyuqiang avatar Sep 01 '25 09:09 heyuqiang

CommitPayload payload = new CommitPayload(); payload.setBranch("main"); payload.setCommitMessage("add dict1j.zip"); CommitAction action= new CommitAction(); action.setAction(CommitAction.Action.CREATE); action.setFilePath("dict1j.zip"); action.setContent(content); action.setEncoding(Constants.Encoding.BASE64); payload.withAction(action);

Commit commit = gitLabApi.getCommitsApi().createCommit(28, payload); System.out.println(commit.toString());

heyuqiang avatar Sep 01 '25 10:09 heyuqiang