Skip to content

Fix decoration API calls#154

Merged
eeisegn merged 5 commits intomainfrom
bugfix/SP-4234-fix-decoration-api-calls
Apr 6, 2026
Merged

Fix decoration API calls#154
eeisegn merged 5 commits intomainfrom
bugfix/SP-4234-fix-decoration-api-calls

Conversation

@eeisegn
Copy link
Copy Markdown
Contributor

@eeisegn eeisegn commented Apr 5, 2026

  • Switch from /api/v2 to /v2
  • Add x-api-key to file contents
  • Fix decoration REST response body parsing

Summary by CodeRabbit

  • Bug Fixes

    • Corrected API key header usage for remote file requests.
    • Updated decoration API endpoint path from /api/v2 to /v2.
    • Fixed handling and reading of decoration API responses when operations are cancelled, preventing lost or unread responses.
  • Documentation

    • Added CHANGELOG entry for version 0.12.1 (2026-04-06) with compare link to v0.12.0...v0.12.1.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 5, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0cf3a617-aaaf-4c88-8a86-8dcaca63cb04

📥 Commits

Reviewing files that changed from the base of the PR and between d64ed5a and e1e45fc.

📒 Files selected for processing (1)
  • CHANGELOG.md
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md

📝 Walkthrough

Walkthrough

Adds v0.12.1 changelog entry; sets X-API-Key header for remote file GETs when token is present; changes decoration API paths from /api/v2 to /v2; updates ScanOSS HTTP service to accept caller-provided contexts and to read response bodies fully before JSON unmarshal, with added debug logging.

Changes

Cohort / File(s) Summary
Version Documentation
CHANGELOG.md
Adds v0.12.1 entry under "Fixed" with three fixes and a new compare link [0.12.1] for v0.12.0...v0.12.1.
API Authentication
backend/repository/file_repository_impl.go
When an API token is available, include X-API-Key: <token> alongside existing X-Session for remote file GET requests.
ScanOSS HTTP Service
backend/service/scanoss_api_service_http_impl.go
GetWithParams signature now takes context.Context; callers derive cancellable contexts when needed. Endpoints changed from "/api/v2/..." to "/v2/...". Switched from streaming JSON decode to io.ReadAll + json.Unmarshal; added body-read error handling and extra debug logging; removed internal WithCancel lifecycle so cancellation is caller-driven.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ScanOSS as ScanOSS Service
    participant Repo as File Repository
    participant Remote as Decoration API

    Client->>ScanOSS: SearchComponents / GetLicensesByPurl (ctx)
    ScanOSS->>ScanOSS: ensure ctx (background -> WithCancel if nil)
    ScanOSS->>Remote: GET "/v2/..." (GetWithParams with ctx)
    Remote-->>ScanOSS: HTTP response (body)
    ScanOSS->>ScanOSS: io.ReadAll(resp.Body)
    ScanOSS->>ScanOSS: json.Unmarshal(body)
    ScanOSS-->>Client: parsed result / error

    Client->>Repo: ReadRemoteFileByMD5 (with token)
    Repo->>Remote: GET file (headers: X-Session, X-API-Key)
    Remote-->>Repo: file response
    Repo-->>Client: file content / error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I hopped through headers, nibbling keys,
I trimmed the paths and calmed the trees,
I read the bytes before they'd flee,
Contexts cradled, logs set free,
A changelog carrot — joy for me! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix decoration API calls' directly summarizes the main change: fixing issues with the decoration API by correcting the API endpoint path and request/response handling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfix/SP-4234-fix-decoration-api-calls

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 5, 2026

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 190
  • Detected files undeclared: 0
  • Detected files declared: 190
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/service/scanoss_api_service_http_impl.go`:
- Around line 180-183: The structured log in the json.Unmarshal error handling
is using the stale variable err instead of the actual JSON decode error
(jsonErr); update the log call(s) where you have log.Error().Err(err).Msgf(...)
to pass jsonErr (e.g., in the json.Unmarshal error block around jsonErr and the
similar block at lines 232-234) so the .Err(...) field contains the real
decoding error and the returned fmt.Errorf still wraps jsonErr.
- Around line 169-177: Both SearchComponents and GetLicensesByPurl call
io.ReadAll into variables body/bodyErr but continue processing when bodyErr !=
nil; update each function to immediately return a descriptive error (and avoid
using the unread body) if bodyErr is non-nil. Specifically, in SearchComponents
and GetLicensesByPurl, replace the current log-only branch for bodyErr with a
return that wraps bodyErr (including context like "failed to read response body"
and the response status if available) so subsequent checks on resp.StatusCode or
JSON parsing never proceed with an invalid payload.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 340174ae-d4a0-47c4-be7e-557ba8a2d6b6

📥 Commits

Reviewing files that changed from the base of the PR and between c25837e and ce4f5ce.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • backend/repository/file_repository_impl.go
  • backend/service/scanoss_api_service_http_impl.go

Comment thread backend/service/scanoss_api_service_http_impl.go
Comment thread backend/service/scanoss_api_service_http_impl.go
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 5, 2026

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 190
  • Detected files undeclared: 0
  • Detected files declared: 190
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 5, 2026

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 190
  • Detected files undeclared: 0
  • Detected files declared: 190
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
backend/service/scanoss_api_service_http_impl.go (1)

169-174: ⚠️ Potential issue | 🟠 Major

Return immediately when reading the response body fails.

After io.ReadAll returns an error, body is partial/untrusted. Continuing into the status check and json.Unmarshal can turn a transport failure into a misleading HTTP or JSON error. This is still unresolved from the earlier review.

Also applies to: 221-226

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/service/scanoss_api_service_http_impl.go` around lines 169 - 174,
When io.ReadAll(resp.Body) returns an error (bodyErr), return immediately
instead of continuing — the partial `body` is untrusted and should not be used
for status checks or json.Unmarshal; update the logic in the HTTP handling
function that reads resp.Body (where `body, bodyErr := io.ReadAll(resp.Body)` is
used) to log the error and return an appropriate error/response to the caller
right away. Apply the same fix to the second occurrence around the block using
json.Unmarshal to avoid converting transport/read failures into JSON or HTTP
errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/service/scanoss_api_service_http_impl.go`:
- Around line 156-161: The code currently mutates s.ctx during request handling
(see s.ctx usage and the context.WithCancel call), which creates a race for
concurrent requests; instead, capture the field into a local variable (e.g.,
localCtx := s.ctx), if localCtx == nil assign localCtx = context.Background(),
then call context.WithCancel(localCtx) and use that local context for the
request—do this for both occurrences that assign s.ctx (the block using s.ctx
and the similar block at lines ~209-211) so the service field is never modified
during request handling.

---

Duplicate comments:
In `@backend/service/scanoss_api_service_http_impl.go`:
- Around line 169-174: When io.ReadAll(resp.Body) returns an error (bodyErr),
return immediately instead of continuing — the partial `body` is untrusted and
should not be used for status checks or json.Unmarshal; update the logic in the
HTTP handling function that reads resp.Body (where `body, bodyErr :=
io.ReadAll(resp.Body)` is used) to log the error and return an appropriate
error/response to the caller right away. Apply the same fix to the second
occurrence around the block using json.Unmarshal to avoid converting
transport/read failures into JSON or HTTP errors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2616c884-34b7-478d-b3aa-9a1a639fc820

📥 Commits

Reviewing files that changed from the base of the PR and between 4b99774 and d64ed5a.

📒 Files selected for processing (1)
  • backend/service/scanoss_api_service_http_impl.go

Comment on lines +156 to +161
if s.ctx == nil {
log.Warn().Msg("No context provided, using default context")
s.ctx = context.Background()
}
ctx, cancel := context.WithCancel(s.ctx)
defer cancel()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n backend/service/scanoss_api_service_http_impl.go | head -50

Repository: scanoss/scanoss.cc

Length of output: 2049


🏁 Script executed:

wc -l backend/service/scanoss_api_service_http_impl.go

Repository: scanoss/scanoss.cc

Length of output: 114


🏁 Script executed:

cat -n backend/service/scanoss_api_service_http_impl.go | sed -n '140,180p'

Repository: scanoss/scanoss.cc

Length of output: 1785


🏁 Script executed:

cat -n backend/service/scanoss_api_service_http_impl.go | sed -n '200,230p'

Repository: scanoss/scanoss.cc

Length of output: 1453


🏁 Script executed:

cat -n backend/service/scanoss_api_service_http_impl.go | sed -n '1,80p'

Repository: scanoss/scanoss.cc

Length of output: 2905


🏁 Script executed:

rg -n "NewScanossApiServiceHttpImpl|ScanossApiServiceHttpImpl" --type go -A 3 -B 1 | head -100

Repository: scanoss/scanoss.cc

Length of output: 4101


🏁 Script executed:

rg -n "SetContext" --type go -A 2 -B 1

Repository: scanoss/scanoss.cc

Length of output: 6672


🏁 Script executed:

rg -n "go func" backend/service/scanoss_api_service_http_impl.go

Repository: scanoss/scanoss.cc

Length of output: 44


🏁 Script executed:

# Check if there's any synchronization (mutex, locks) in the struct or usage
rg -n "sync\.|Mutex|RWMutex|Lock" backend/service/ --type go

Repository: scanoss/scanoss.cc

Length of output: 1125


🏁 Script executed:

cat -n main.go | sed -n '100,130p'

Repository: scanoss/scanoss.cc

Length of output: 1184


🏁 Script executed:

# Check if there's an HTTP server handling concurrent requests
rg -n "http.Server|Server|ListenAndServe|Handler" main.go -A 3 -B 1

Repository: scanoss/scanoss.cc

Length of output: 214


🏁 Script executed:

# Check if Wails framework enables concurrent request handling
cd backend && find . -name "*.go" -type f | head -20 | xargs grep -l "goroutine\|concurrent\|channel" | head -5

Repository: scanoss/scanoss.cc

Length of output: 44


🏁 Script executed:

# Check the app binding to see what methods can be called concurrently from UI
cat -n main.go | sed -n '110,140p'

Repository: scanoss/scanoss.cc

Length of output: 1031


🏁 Script executed:

# Verify if there are any other places where s.ctx is read/modified
rg "s\.ctx" backend/service/scanoss_api_service_http_impl.go -n

Repository: scanoss/scanoss.cc

Length of output: 285


Use a local variable for context fallback instead of mutating the service field.

Lines 156-158 and 209-211 mutate s.ctx during request handling. Since this service instance is reused across requests and exposed via Wails bindings (allowing concurrent invocation), this creates a race condition. Concurrent requests can interfere with each other's context, and the fallback assignment can persist to unrelated calls.

Capture s.ctx once in a local variable before the nil check to ensure each request operates on a stable context value:

Suggested change
-	if s.ctx == nil {
-		log.Warn().Msg("No context provided, using default context")
-		s.ctx = context.Background()
-	}
-	ctx, cancel := context.WithCancel(s.ctx)
+	baseCtx := s.ctx
+	if baseCtx == nil {
+		log.Warn().Msg("No context provided, using default context")
+		baseCtx = context.Background()
+	}
+	ctx, cancel := context.WithCancel(baseCtx)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if s.ctx == nil {
log.Warn().Msg("No context provided, using default context")
s.ctx = context.Background()
}
ctx, cancel := context.WithCancel(s.ctx)
defer cancel()
baseCtx := s.ctx
if baseCtx == nil {
log.Warn().Msg("No context provided, using default context")
baseCtx = context.Background()
}
ctx, cancel := context.WithCancel(baseCtx)
defer cancel()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/service/scanoss_api_service_http_impl.go` around lines 156 - 161, The
code currently mutates s.ctx during request handling (see s.ctx usage and the
context.WithCancel call), which creates a race for concurrent requests; instead,
capture the field into a local variable (e.g., localCtx := s.ctx), if localCtx
== nil assign localCtx = context.Background(), then call
context.WithCancel(localCtx) and use that local context for the request—do this
for both occurrences that assign s.ctx (the block using s.ctx and the similar
block at lines ~209-211) so the service field is never modified during request
handling.

Copy link
Copy Markdown
Collaborator

@isasmendiagus isasmendiagus left a comment

Choose a reason for hiding this comment

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

One thing to consider for a follow-up, the ctx stored as a struct field on ScanossApiServiceHttpImpl is a Go anti-pattern and introduces a potential race condition

Context should be passed per-request as a function parameter rather than living on the service struct. Not blocking this PR since it's unlikely to hit in practice with the current UI

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 6, 2026

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 190
  • Detected files undeclared: 0
  • Detected files declared: 190
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

@eeisegn eeisegn merged commit 595a305 into main Apr 6, 2026
6 checks passed
@eeisegn eeisegn deleted the bugfix/SP-4234-fix-decoration-api-calls branch April 6, 2026 11:47
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