Skip to content

feat: support Protocol Buffers payload inspection - #81

Merged
easyhooon merged 6 commits into
mainfrom
codex/issue-80-protobuf-support
Aug 4, 2026
Merged

easyhooon merged 6 commits into
mainfrom
codex/issue-80-protobuf-support

Conversation

@easyhooon

@easyhooon easyhooon commented Aug 4, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • add an opt-in ProtobufDariInterceptor and app-provided decoder without introducing a protobuf runtime dependency
  • persist original byte size, content type, decode status, and a bounded raw preview for protobuf payloads
  • expose Decoded/Raw views with Hex and Base64 in the detail UI and text/JSON exports
  • keep the debug and no-op artifacts aligned and document usage in English and Korean

Compatibility

  • existing DariInterceptor String/JSON methods remain unchanged
  • protobuf support is additive through a new createInterceptor overload
  • raw inspection retains only the first 4 KB of each payload; the original size and truncation state remain available
  • schema 3→4 and 4→5 upgrades preserve existing debug records through explicit Room migrations
  • the project version remains 1.5.1; the feature is intended for the next minor release

Testing

  • ./gradlew clean check :sample:assembleDebug :sample:assembleRelease
  • ./gradlew :dari:assembleRelease
  • cd documentation && npm run build
  • pre-commit detekt and ktlint checks

Closes #80

Summary by CodeRabbit

  • New Features

    • Added optional Protocol Buffers inspection with app-provided decoding.
    • Captures and displays protobuf requests and responses with decode status, original sizes, and raw Hex/Base64 previews.
    • Supports protobuf payloads across supported message directions and handler callbacks.
    • Preserves payload metadata in message details and exports.
  • Documentation

    • Added configuration, decoding behavior, error handling, truncation, and payload format guidance.

기존 String/JSON 경로를 유지하면서 앱 주입 decoder, 메타데이터 저장, UI·export 표시를 추가한다.
@coderabbitai

coderabbitai Bot commented Aug 4, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds runtime-agnostic Protocol Buffers interception. It decodes byte-array payloads through an app-provided decoder, stores decode metadata and original sizes, and exposes the data in persistence, UI, exports, tests, and documentation.

Changes

Protocol Buffers inspection

Layer / File(s) Summary
Public contracts and interceptor creation
dari-core/src/main/kotlin/com/easyhooon/dari/..., dari/src/main/kotlin/com/easyhooon/dari/Dari.kt, dari-noop/src/main/kotlin/com/easyhooon/dari/Dari.kt, README.md
Adds protobuf metadata types, decoder context, interceptor callbacks, and runtime and noop createInterceptor overloads.
Capture and decoding flow
dari/src/main/kotlin/com/easyhooon/dari/interceptor/*, dari-core/src/main/kotlin/com/easyhooon/dari/DariConfig.kt
Renders protobuf requests and responses. Records decode states, display truncation, raw previews, and original byte sizes.
Message sizing and Room persistence
dari-core/src/main/kotlin/com/easyhooon/dari/MessageEntry.kt, dari/src/main/kotlin/com/easyhooon/dari/data/{MessageRepository.kt,local/*}
Stores payload metadata in message entries and Room entities. Adds schema migrations and uses original binary sizes when metadata exists.
UI, export, tests, and integration
dari/src/main/kotlin/com/easyhooon/dari/{export/*,ui/*}, dari/src/test/kotlin/com/easyhooon/dari/*, documentation/content/docs/*, sample/*, gradle/libs.versions.toml
Displays and exports decoded and raw payload views. Adds validation, documentation, and a protobuf bridge sample.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant WebView
  participant DefaultDariInterceptor
  participant ProtobufPayloadRenderer
  participant MessageRepository
  participant DariDetailActivity
  WebView->>DefaultDariInterceptor: Send protobuf request or response bytes
  DefaultDariInterceptor->>ProtobufPayloadRenderer: Decode and create metadata
  ProtobufPayloadRenderer-->>DefaultDariInterceptor: Return rendered text and raw preview
  DefaultDariInterceptor->>MessageRepository: Insert or update message metadata
  MessageRepository-->>DariDetailActivity: Provide stored message entry
  DariDetailActivity-->>WebView: Display decoded or raw payload view
Loading

Possibly related PRs

  • easyhoon/dari#7: Updates the Room persistence paths extended by protobuf metadata.
  • easyhoon/dari#28: Updates the export paths extended with protobuf metadata and raw previews.
  • easyhoon/dari#60: Relates to interceptor request and fireAndForget handling extended for protobuf callbacks.

Suggested labels: enhancement

Poem

A rabbit sends bytes through the bridge,
The decoder renders clear text.
Raw previews keep the wire data.
Room records each message.
Exports show both views.
“Hop,” says the rabbit, “done!”

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: Protocol Buffers payload inspection.
Linked Issues check ✅ Passed The changes satisfy issue #80 with binary APIs, decoder handling, metadata, persistence, UI, exports, compatibility, tests, and documentation.
Out of Scope Changes check ✅ Passed The sample, documentation, dependency, UI refactor, persistence, and test changes directly support Protocol Buffers inspection.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-80-protobuf-support

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@dari/src/main/kotlin/com/easyhooon/dari/data/local/DariDatabase.kt`:
- Line 11: Add a Room Migration(3, 4) for DariDatabase that alters the existing
messages table to add the new nullable metadata columns, and register it with
the database builder. Preserve existing rows and avoid relying solely on
fallbackToDestructiveMigration(dropAllTables = true) for schema-3 upgrades.

In
`@dari/src/main/kotlin/com/easyhooon/dari/interceptor/DefaultDariInterceptor.kt`:
- Around line 202-204: Update DefaultDariInterceptor’s protobuf rendering path,
especially renderProtobuf, to handle a null protobufDecoder without throwing.
Return an unavailable rendered payload using
PayloadDecodeStatus.DECODER_UNAVAILABLE while preserving the existing
placeholder text and metadata; keep normal decoding unchanged when the decoder
is present.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cb7c395f-d897-4e97-b4a2-9ffa26952091

📥 Commits

Reviewing files that changed from the base of the PR and between 801b012 and fa93af7.

📒 Files selected for processing (25)
  • README.md
  • dari-core/src/main/kotlin/com/easyhooon/dari/DariConfig.kt
  • dari-core/src/main/kotlin/com/easyhooon/dari/MessageEntry.kt
  • dari-core/src/main/kotlin/com/easyhooon/dari/MessagePayloadMetadata.kt
  • dari-core/src/main/kotlin/com/easyhooon/dari/interceptor/ProtobufDariInterceptor.kt
  • dari-noop/src/main/kotlin/com/easyhooon/dari/Dari.kt
  • dari/src/main/kotlin/com/easyhooon/dari/Dari.kt
  • dari/src/main/kotlin/com/easyhooon/dari/data/MessageRepository.kt
  • dari/src/main/kotlin/com/easyhooon/dari/data/local/Converters.kt
  • dari/src/main/kotlin/com/easyhooon/dari/data/local/DariDatabase.kt
  • dari/src/main/kotlin/com/easyhooon/dari/data/local/MessageDao.kt
  • dari/src/main/kotlin/com/easyhooon/dari/data/local/MessageEntity.kt
  • dari/src/main/kotlin/com/easyhooon/dari/export/DariExporter.kt
  • dari/src/main/kotlin/com/easyhooon/dari/export/ExportableMessage.kt
  • dari/src/main/kotlin/com/easyhooon/dari/interceptor/DefaultDariInterceptor.kt
  • dari/src/main/kotlin/com/easyhooon/dari/interceptor/ProtobufPayloadRenderer.kt
  • dari/src/main/kotlin/com/easyhooon/dari/ui/DariDetailActivity.kt
  • dari/src/test/kotlin/com/easyhooon/dari/MessageEntryTest.kt
  • dari/src/test/kotlin/com/easyhooon/dari/data/local/MessageEntityTest.kt
  • dari/src/test/kotlin/com/easyhooon/dari/export/ExportableMessageTest.kt
  • dari/src/test/kotlin/com/easyhooon/dari/interceptor/ProtobufPayloadRendererTest.kt
  • documentation/content/docs/index.mdx
  • documentation/content/docs/interceptor.mdx
  • documentation/content/docs/ko/index.mdx
  • documentation/content/docs/ko/interceptor.mdx

Comment thread dari/src/main/kotlin/com/easyhooon/dari/data/local/DariDatabase.kt Outdated
Comment thread dari/src/main/kotlin/com/easyhooon/dari/interceptor/DefaultDariInterceptor.kt Outdated
@easyhooon

Copy link
Copy Markdown
Owner Author

🤖 CodeRabbit Review Resolution

Total unresolved: 2 | Applied: 2 | Declined: 0

✅ Applied

Severity File Comment Change Commit
🟠 DariDatabase.kt Missing non-destructive 3→4 migration (link) Added and registered a migration that preserves existing rows 8adf2a8
🟠 DefaultDariInterceptor.kt Missing decoder crashes protobuf capture (link) Records the unavailable placeholder and metadata without throwing c323fa6

❌ Declined

None.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@sample/src/main/java/com/easyhooon/dari/sample/MainActivity.kt`:
- Around line 141-167: Wrap the Base64.decode call in onProtobufBridgeRequest
with the existing runCatching flow so decoding failures are handled before
protobuf parsing. On any decode failure, produce a generic unsuccessful protobuf
response and ensure both onWebToAppProtobufResponse and callProtobufJs are still
invoked with success=false; preserve the current parsed-response behavior for
valid decoded data.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bd926b1d-b74f-4a50-aba9-7150b0010f4a

📥 Commits

Reviewing files that changed from the base of the PR and between fa93af7 and 10c238c.

📒 Files selected for processing (24)
  • README.md
  • dari-core/src/main/kotlin/com/easyhooon/dari/MessagePayloadMetadata.kt
  • dari/src/main/kotlin/com/easyhooon/dari/RawPayloadFormatter.kt
  • dari/src/main/kotlin/com/easyhooon/dari/data/MessageRepository.kt
  • dari/src/main/kotlin/com/easyhooon/dari/data/local/DariDatabase.kt
  • dari/src/main/kotlin/com/easyhooon/dari/data/local/MessageDao.kt
  • dari/src/main/kotlin/com/easyhooon/dari/data/local/MessageEntity.kt
  • dari/src/main/kotlin/com/easyhooon/dari/export/DariExporter.kt
  • dari/src/main/kotlin/com/easyhooon/dari/export/ExportableMessage.kt
  • dari/src/main/kotlin/com/easyhooon/dari/interceptor/DefaultDariInterceptor.kt
  • dari/src/main/kotlin/com/easyhooon/dari/interceptor/ProtobufPayloadRenderer.kt
  • dari/src/main/kotlin/com/easyhooon/dari/ui/DariDetailActivity.kt
  • dari/src/main/kotlin/com/easyhooon/dari/ui/components/JsonViewer.kt
  • dari/src/test/kotlin/com/easyhooon/dari/RawPayloadFormatterTest.kt
  • dari/src/test/kotlin/com/easyhooon/dari/data/local/MessageEntityTest.kt
  • dari/src/test/kotlin/com/easyhooon/dari/export/DariExporterTest.kt
  • dari/src/test/kotlin/com/easyhooon/dari/export/ExportableMessageTest.kt
  • dari/src/test/kotlin/com/easyhooon/dari/interceptor/ProtobufPayloadRendererTest.kt
  • documentation/content/docs/interceptor.mdx
  • documentation/content/docs/ko/interceptor.mdx
  • gradle/libs.versions.toml
  • sample/build.gradle.kts
  • sample/src/main/assets/sample.html
  • sample/src/main/java/com/easyhooon/dari/sample/MainActivity.kt
🚧 Files skipped from review as they are similar to previous changes (10)
  • dari/src/main/kotlin/com/easyhooon/dari/data/MessageRepository.kt
  • documentation/content/docs/ko/interceptor.mdx
  • dari/src/test/kotlin/com/easyhooon/dari/export/ExportableMessageTest.kt
  • dari/src/test/kotlin/com/easyhooon/dari/data/local/MessageEntityTest.kt
  • README.md
  • dari/src/main/kotlin/com/easyhooon/dari/interceptor/ProtobufPayloadRenderer.kt
  • dari/src/main/kotlin/com/easyhooon/dari/data/local/MessageDao.kt
  • dari/src/main/kotlin/com/easyhooon/dari/data/local/MessageEntity.kt
  • dari/src/main/kotlin/com/easyhooon/dari/interceptor/DefaultDariInterceptor.kt
  • documentation/content/docs/interceptor.mdx

Comment on lines +141 to +167
@JavascriptInterface
fun onProtobufBridgeRequest(requestId: String, base64Data: String) {
val requestData = Base64.decode(base64Data, Base64.NO_WRAP)
interceptor?.onWebToAppProtobufRequest(PROTOBUF_HANDLER, requestId, requestData)

val result = runCatching {
val request = StringValue.parseFrom(requestData)
StringValue.newBuilder()
.setValue("Android received: ${request.value}")
.build()
}
val response = result.getOrElse { error ->
StringValue.newBuilder()
.setValue("Invalid protobuf: ${error.message}")
.build()
}
val success = result.isSuccess
val responseData = response.toByteArray()

interceptor?.onWebToAppProtobufResponse(
PROTOBUF_HANDLER,
requestId,
responseData,
success,
)
callProtobufJs(requestId, success, responseData)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Handle Base64 decoding failures before capture.

At Line 143, Base64.decode runs before runCatching. If base64Data has invalid padding, it throws IllegalArgumentException, exits the JavaScript interface method, and does not send onProtobufBridgeResponse. Catch this failure, create a generic protobuf failure response, and call callProtobufJs. (developer.android.com)

This conflicts with the malformed-payload handling objective.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sample/src/main/java/com/easyhooon/dari/sample/MainActivity.kt` around lines
141 - 167, Wrap the Base64.decode call in onProtobufBridgeRequest with the
existing runCatching flow so decoding failures are handled before protobuf
parsing. On any decode failure, produce a generic unsuccessful protobuf response
and ensure both onWebToAppProtobufResponse and callProtobufJs are still invoked
with success=false; preserve the current parsed-response behavior for valid
decoded data.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 176-177: Add concise, descriptive alt attributes to both img
elements for protobuf_decoded.png and protobuf_raw.png, while preserving their
existing sources and dimensions.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6b252728-5f7e-41b0-9c9f-52a936a1dbb5

📥 Commits

Reviewing files that changed from the base of the PR and between 10c238c and e1f6199.

⛔ Files ignored due to path filters (2)
  • screenshots/protobuf_decoded.png is excluded by !**/*.png
  • screenshots/protobuf_raw.png is excluded by !**/*.png
📒 Files selected for processing (1)
  • README.md

Comment thread README.md
Comment on lines +176 to +177
<td><img src="screenshots/protobuf_decoded.png" width="320" /></td>
<td><img src="screenshots/protobuf_raw.png" width="320" /></td>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add alternative text to both screenshots.

The <img> elements on Lines 176 and 177 have no alt attributes. Add concise descriptions for screen-reader users.

Proposed fix
-    <td><img src="screenshots/protobuf_decoded.png" width="320" /></td>
-    <td><img src="screenshots/protobuf_raw.png" width="320" /></td>
+    <td><img src="screenshots/protobuf_decoded.png" alt="Protobuf decoded payload view" width="320" /></td>
+    <td><img src="screenshots/protobuf_raw.png" alt="Protobuf raw bytes view" width="320" /></td>
📝 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
<td><img src="screenshots/protobuf_decoded.png" width="320" /></td>
<td><img src="screenshots/protobuf_raw.png" width="320" /></td>
<td><img src="screenshots/protobuf_decoded.png" alt="Protobuf decoded payload view" width="320" /></td>
<td><img src="screenshots/protobuf_raw.png" alt="Protobuf raw bytes view" width="320" /></td>
🧰 Tools
🪛 markdownlint-cli2 (0.23.1)

[warning] 176-176: Images should have alternate text (alt text)

(MD045, no-alt-text)


[warning] 177-177: Images should have alternate text (alt text)

(MD045, no-alt-text)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 176 - 177, Add concise, descriptive alt attributes to
both img elements for protobuf_decoded.png and protobuf_raw.png, while
preserving their existing sources and dimensions.

Source: Linters/SAST tools

@easyhooon
easyhooon merged commit eabfdd6 into main Aug 4, 2026
3 checks passed
@easyhooon
easyhooon deleted the codex/issue-80-protobuf-support branch August 4, 2026 03:58
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.

feat: support Protocol Buffers payloads in bridge inspection

1 participant