{"id":13583971,"url":"https://github.com/ButterCam/Mediator","last_synced_at":"2025-04-06T21:33:49.142Z","repository":{"id":42391492,"uuid":"365499735","full_name":"ButterCam/Mediator","owner":"ButterCam","description":"Cross-platform GUI gRPC debugging proxy","archived":false,"fork":false,"pushed_at":"2023-10-27T06:45:59.000Z","size":3494,"stargazers_count":147,"open_issues_count":9,"forks_count":8,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-08-02T15:54:14.594Z","etag":null,"topics":["debugging","debugging-tool","grpc","proxy"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ButterCam.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-05-08T11:42:15.000Z","updated_at":"2024-07-29T12:40:56.000Z","dependencies_parsed_at":"2023-01-20T00:01:07.100Z","dependency_job_id":"8ae40487-cd26-4369-af39-69ca06d5dd1b","html_url":"https://github.com/ButterCam/Mediator","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ButterCam%2FMediator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ButterCam%2FMediator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ButterCam%2FMediator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ButterCam%2FMediator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ButterCam","download_url":"https://codeload.github.com/ButterCam/Mediator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223265059,"owners_count":17116281,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["debugging","debugging-tool","grpc","proxy"],"created_at":"2024-08-01T15:03:55.988Z","updated_at":"2024-11-06T00:31:11.879Z","avatar_url":"https://github.com/ButterCam.png","language":"Kotlin","funding_links":[],"categories":["Kotlin","Tools"],"sub_categories":["Testing"],"readme":"\u003ch1 align=\"center\"\u003e\n\u003cp\u003e\n\u003cimg src=\"./docs/MD-Light.svg#gh-light-mode-only\" width=\"500px\" alt=\"Mediator\"/\u003e\n\u003cimg src=\"./docs/MD-Dark.svg#gh-dark-mode-only\" width=\"500px\" alt=\"Mediator\"/\u003e\n\u003c/p\u003e\n\u003cp\u003e\n\u003ca href=\"https://github.com/grpc-ecosystem/awesome-grpc\"\u003e\u003cimg alt=\"Awesome gRPC\" src=\"https://raw.githubusercontent.com/sindresorhus/awesome/main/media/badge.svg\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://www.jetbrains.com/lp/compose/\"\u003e\u003cimg src=\"https://img.shields.io/badge/JetBrains-Compose-ff69b4\" alt=\"JetBrains Compose\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/ButterCam/Mediator/releases\"\u003e\u003cimg alt=\"GitHub release (latest by date)\" src=\"https://img.shields.io/github/v/release/ButterCam/Mediator\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003c/h1\u003e\n\nCross-platform GUI gRPC debugging proxy like [charles](https://www.charlesproxy.com/) but design for gRPC.\n\nBuild with [Netty](https://netty.io/) (proxy protocol), [Compose Desktop](https://www.jetbrains.com/lp/compose/) (GUI), [Sisyphus](https://github.com/ButterCam/sisyphus) (Protobuf Runtime)\n\n![screenshot](docs/screenshot.png)\n\n## Highlight features\n\n✅ **Cross-platform**, works on all your favorite platforms like Windows, macOS, Linux  \n✅ **Jetbrains Style GUI**, easily integrating into your desktop  \n✅ **Host Rewrite**, redirect the request to beta or test server without modifying client code  \n✅ **Protobuf Decode Support**, parsing gRPC request and response message  \n✅ **HTTPS Support**, decode gRPC/HTTPS requests\n\n## Quick Start\n\n### Install\n\nDownload distribution from [release page](https://github.com/ButterCam/Mediator/releases).\n\nMSI for Windows, Dmg for macOS, Dmg(aarch64) for macOS(Apple Silicon), deb for Linux.\n\n### Run\n\nOpen the mediator app, the proxy server will listen 8888 port by default.\n\n### Config Client\n\nConfig the proxy server in your client code.\n\n#### Java Client (Android or Server)\n\nConfig proxy server by `proxyDetector` method of channel builder.\n\n```Kotlin\nManagedChannelBuilder.forAddress(\"foo.barapis.com\", 9000)\n    .usePlaintext()\n    .proxyDetector {\n        HttpConnectProxiedSocketAddress.newBuilder()\n            .setTargetAddress(it as InetSocketAddress)\n            .setProxyAddress(InetSocketAddress(\"\u003cYOUR PC/MAC IP\u003e\", 8888))\n            .build()\n    }\n    .build()\n```\n\n#### Objective C Client (iOS)\n\nSet proxy server to Environment variable in `main` function before your app code.\n\n```objc\nint main(int argc, char * argv[]) {\n    NSString * appDelegateClassName;\n    @autoreleasepool {\n        setenv(\"grpc_proxy\", \"http://\u003cYOUR PC/MAC IP\u003e:8888\", 1);\n        \n        // Setup code that might create autoreleased objects goes here.\n        appDelegateClassName = NSStringFromClass([AppDelegate class]);\n    }\n    return UIApplicationMain(argc, argv, nil, appDelegateClassName);\n}\n```\n\n#### Go Client (Server)\n\nSet proxy server to Environment variable.\n\n```go\npackage main\n\nimport (\n\t\"os\"\n)\n\nfunc main() {\n\tos.Setenv(\"HTTP_PROXY\", \"http://\u003cYOUR PC/MAC IP\u003e:8888\")\n\n\t// Your code here.\n}\n```\n\n### HTTPS Support\n\nMediator will try to decode the gRPC/HTTPS request when server rule matched.\n\nYou need download the Mediator Root Certificate and install it to your client just like charles or fiddler.\n\nThe Mediator Root Certificate will be generated when you launch the Mediator app first-time.\n\nYou can download the Mediator Root Certificate by visit `http://\u003cYOUR PC/MAC IP\u003e:8888/mediatorRoot.cer`.\n\n\u003e Note:  \n\u003e To prevent abuse of the same root certificate, each Mediator installation generates a different root certificate.  \n\u003e You need reinstall the Mediator Root Certificate when you use different Mediator installation.\n\n\u003e Tips:  \n\u003e Mediator provide multi format of Root Certificate, you can choose the format you like.\n\u003e - `/mediatorRoot.cer` - DER format\n\u003e - `/mediatorRoot.crt` - PEM format\n\u003e - `/mediatorRoot.pem` - PEM format\n\n#### Use Mediator Root Certificate for Java\n\nBy changing client code, you can eliminate the need to install certificates into the device.\n\nWith the `Grpc` utility class, you can pass the TrustManager to the Channel.\n\nIn this example, we trust all certificates, ignore all SSL error.\n\n```Kotlin\nval creds = TlsChannelCredentials.newBuilder().trustManager(object : X509TrustManager {\n    override fun getAcceptedIssuers(): Array\u003cX509Certificate\u003e = arrayOf()\n\n    @SuppressLint(\"TrustAllX509TrustManager\")\n    @Throws(CertificateException::class)\n    override fun checkServerTrusted(chain: Array\u003cX509Certificate\u003e, authType: String) = Unit\n\n    @SuppressLint(\"TrustAllX509TrustManager\")\n    @Throws(CertificateException::class)\n    override fun checkClientTrusted(chain: Array\u003cX509Certificate\u003e, authType: String) = Unit\n}).build()\n\n// Do not call `useTransportSecurity()` method, when you create channel with TlsChannelCredentials.\nGrpc.newChannelBuilder(\"$name:$port\", creds)\n```\n\nYou can also pass the specified certificate to the `trustManager` method of the `TlsChannelCredentials.Builder`.\n\n#### Install Mediator Root Certificate for JDK\n\nIf you don't want to change client code, you can install the Mediator Root Certificate to your JDK.\n\nJDK will not trust the Mediator Root Certificate by default even you install it to system.\n\nYou can find the JDK keystore file in `$JAVA_HOME/jre/lib/security/cacerts` or `$JAVA_HOME/lib/security/cacerts`.\n\nThen import the Mediator Root Certificate to JDK cacerts file\nby `keytool -import -keystore $JAVA_HOME/lib/security/cacerts -file mediatorRoot.cer` command.\n\n#### Install Mediator Root Certificate for Android\n\nIf you don't want change your client code, you can install the Mediator Root Certificate to your device.\n\nDownload the Mediator Root Certificate in browser by visit `http://\u003cYOUR PC/MAC IP\u003e:8888/mediatorRoot.cer` on your\nAndroid device.\n\nCheck [this guide](https://support.google.com/pixelphone/answer/2844832?hl=en) to install it to your device.\n\nIn Android 7.0 or later, you need config the networkSecurityConfig in `app/src/main/AndroidManifest.xml` to trust user\ncertificates.\n\n```xml\n\u003capplication\n        android:name=\".ApplicationClass\"\n        android:allowBackup=\"true\"\n        android:hardwareAccelerated=\"false\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:largeHeap=\"true\"\n        android:networkSecurityConfig=\"@xml/network_security_config\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\"\u003e\n```\n\nWith a corresponding `network_security_config.xml` in `app/src/main/res/xml/`:\n\n1. Just trust user certificates in debug mode.\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cnetwork-security-config\u003e\n    \u003cdebug-overrides\u003e\n        \u003ctrust-anchors\u003e\n            \u003ccertificates src=\"user\" /\u003e\n        \u003c/trust-anchors\u003e\n    \u003c/debug-overrides\u003e\n\u003c/network-security-config\u003e\n```\n\n2. Trust user certificates in release mode (Same as Android 6.0 and lower).\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cnetwork-security-config\u003e\n   \u003cbase-config cleartextTrafficPermitted=\"true\"\u003e\n      \u003ctrust-anchors\u003e\n         \u003ccertificates src=\"system\" /\u003e\n         \u003ccertificates src=\"user\" /\u003e\n      \u003c/trust-anchors\u003e\n   \u003c/base-config\u003e\n\u003c/network-security-config\u003e\n```\n\nMore information about\nAndroid's [networkSecurityConfig](https://developer.android.com/training/articles/security-config).\n\n#### Use Mediator Root Certificate for iOS\n\ngRPC ObjectC client will not trust the Mediator Root Certificate by default even you install it to system.\n\nYou need pass the PEM format certificate to the `[GRPCCallOptions setPEMRootCertificates: cert]` method.\n\nDownload the PEM format certificate by `http://\u003cYOUR PC/MAC IP\u003e:8888/mediatorRoot.pem`.\n\n### Resolve messages\n\nMediator can render the binary message into a JSON tree, when you have the API schema.\n\nMediator can accept API schema in many ways.\n\n1. [Server Reflection](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md), when your service supports\n   server reflection, you can parse the binary message directly, and you can add additional request metadata for server\n   reflection in the settings page.\n2. proto Source Code, you can specify multiple proto root paths and Mediator will automatically compile the included\n   proto source code into API schema.\n3. FileDescriptorSet, you can specify multiple binary message files containing the API schema with the FileDescriptorSet\n   structure.\n\n#### Server Reflection\n\nBefore using this Schema source, please make sure your server\nsupports [Server Reflection](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md).\n\n1. Open the `Mediator Settings`, create a server rule for your server.\n2. Enter the Regex in `Host pattern` input field which to match your server.\n3. Choose the `Server reflection` schema source.\n4. **Optional** Add the metadata in `Reflection api metadata` table.\n5. Enable this rule by `Enable server rule` checkbox.\n\n![Server Rule](docs/screenshot-rule-server-reflection.png)\n\n#### Proto roots\n\nMediator uses the protoc command to compile the proto file into a FileDescriptorSet message containing the API schema.\n\n1. Open the `Mediator Settings`, create a server rule for your server.\n2. Enter the Regex in `Host pattern` input field which to match your server.\n3. Choose the `Proto root` schema source.\n4. Add the root path in `Proto file roots` list.\n5. Enable this rule by `Enable server rule` checkbox.\n\n![Server Rule](docs/screenshot-rule-roots.png)\n\n#### FileDescriptorSet\n\nFileDescriptorSet is a protobuf message that contains information about the API schema and proto file structure, which\nMediator uses to dynamically parse the message.\n\nYou can use the protoc command to get the FileDescriptorSet structure by compiling the proto file.\n\n```shell\n\u003e protoc --include_imports --include_source_info -o\u003ctempOut.pb\u003e -I\u003cyour-root\u003e -I\u003cmore-root\u003e \u003cprotofiles.proto\u003e \u003cmore-protofiles.proto\u003e\n```\n\n1. Open the `Mediator Settings`, create a server rule for your server.\n2. Enter the Regex in `Host pattern` input field which to match your server.\n3. Choose the `FileDescriptorSet` schema source.\n4. Add the descriptor files in `File descriptor set` list.\n5. Enable this rule by `Enable server rule` checkbox.\n\n![Server Rule](docs/screenshot-rule-descriptors.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FButterCam%2FMediator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FButterCam%2FMediator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FButterCam%2FMediator/lists"}