Skip to content

feat: Fix binary data handling in API GET command#740

Open
yashisrani wants to merge 1 commit into
uyuni-project:mainfrom
yashisrani:feat/TODO
Open

feat: Fix binary data handling in API GET command#740
yashisrani wants to merge 1 commit into
uyuni-project:mainfrom
yashisrani:feat/TODO

Conversation

@yashisrani

Copy link
Copy Markdown

Git Commit Message
Fix binary data handling in API GET command

  • Replace TODO comment with proper binary data detection
  • Add outputResult() function to handle JSON/text/binary responses
  • Add containsBinaryData() to detect null bytes and control characters
  • Add isTextContentType() for content-type validation
  • Use cmd.OutOrStdout() instead of fmt.Print for proper output handling
    PR Description

What does this PR change?

Fixes the TODO comment in mgrctl/cmd/api/get.go regarding binary data handling. The API GET command now properly handles both text/JSON responses and binary data.

Changes:

  • Added outputResult() function that intelligently detects and handles response types
  • Added containsBinaryData() to detect binary content (null bytes, control characters)
  • Added isTextContentType() for content-type header validation
  • JSON/text responses are pretty-printed
  • Binary data is written as raw bytes to stdout

Codespace

Check if you already have a running container clicking on Running CodeSpace

Create CodeSpace About billing for Github Codespaces CodeSpace Billing Summary CodeSpace Limit

Test coverage

  • No tests: add explanation

  • No tests: already covered

  • [] Unit tests were added

  • DONE (tested with go test ./mgrctl/cmd/api/... and go build ./...)

Links

Issue(s): #

  • DONE

Changelogs

Make sure the changelogs entries you are adding are compliant with https://github.com/uyuni-project/uyuni/wiki/Contributing#changelogs and https://github.com/uyuni-project/uyuni/wiki/Contributing#uyuni-projectuyuni-repository

If you don't need a changelog check, please mark this checkbox:

  • No changelog needed

If you uncheck the checkbox after the PR is created, you will need to re-run changelog_test (see below)

Before you merge

Check How to branch and merge properly!

Signed-off-by: Yash Israni <118755067+yashisrani@users.noreply.github.com>
@sonarqubecloud

sonarqubecloud Bot commented Mar 9, 2026

Copy link
Copy Markdown

@cbosdo cbosdo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The server doesn't handle the binary returns correctly so far, so I believe that this code has never been tested: this is a first reason to not accept it in the current state.

I would also prefer to not try to parse JSON and then convert to bytes if it fails as it can hide other issues. HTTP has a header to indicate the response content type: it should be used to distinguish when to output binary blob.

Along the other things to fix for all PRs:

  • Add a copyright line for you in the file header
  • Set a useful commit description rather than a single line comment (can be used as PR description too)
  • Run the tests including the linter

Comment thread mgrctl/cmd/api/get.go
// For JSON/text data, it pretty-prints the JSON.
// For binary data, it writes raw bytes to stdout.
func outputResult(cmd *cobra.Command, res *api.APIResponse[interface{}]) error {
// Try to marshal as JSON first

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we should rely on the HTTP Header indicating the content type rather than trying first.

Comment thread mgrctl/cmd/api/get.go
return err
}
// Fallback: try to write as string
_, err := fmt.Fprint(cmd.OutOrStdout(), res.Result)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A string can always be converted to bytes: I believe this fallback will never happen.

Comment thread mgrctl/cmd/api/get.go
}

// Check if output looks like binary (contains null bytes or non-printable chars)
if containsBinaryData(out) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are handling the binary data twice: if you come to this point, the data has been marshalled as JSON… there is no point to try to look for binary data.

Comment thread mgrctl/cmd/api/get.go
}

// isTextContentType checks if the content type indicates text-based data.
func isTextContentType(contentType string) bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is not used at all

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants