{"id":28394971,"url":"https://github.com/ouqiang/mars","last_synced_at":"2025-06-27T01:31:37.484Z","repository":{"id":109496525,"uuid":"164120181","full_name":"ouqiang/mars","owner":"ouqiang","description":"HTTP(S)代理, 用于抓包调试","archived":false,"fork":false,"pushed_at":"2019-01-04T15:25:17.000Z","size":3396,"stargazers_count":184,"open_issues_count":1,"forks_count":57,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-06-01T06:31:58.586Z","etag":null,"topics":["go","httpproxy","mitmproxy"],"latest_commit_sha":null,"homepage":"","language":"Go","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/ouqiang.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-01-04T14:55:50.000Z","updated_at":"2025-02-03T07:37:04.000Z","dependencies_parsed_at":"2023-03-21T05:36:20.437Z","dependency_job_id":null,"html_url":"https://github.com/ouqiang/mars","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/ouqiang/mars","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ouqiang%2Fmars","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ouqiang%2Fmars/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ouqiang%2Fmars/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ouqiang%2Fmars/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ouqiang","download_url":"https://codeload.github.com/ouqiang/mars/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ouqiang%2Fmars/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262172460,"owners_count":23270012,"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":["go","httpproxy","mitmproxy"],"created_at":"2025-05-31T19:09:34.805Z","updated_at":"2025-06-27T01:31:37.472Z","avatar_url":"https://github.com/ouqiang.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mars - HTTP(S)代理, 用于抓包调试\n\n[![license](https://img.shields.io/hexpm/l/plug.svg?maxAge=2592000)](https://github.com/ouqiang/mars/blob/master/LICENSE)\n[![Release](https://img.shields.io/github/release/ouqiang/mars.svg?label=Release)](https://github.com/ouqiang/mars/releases)\n\n\n\n功能特性\n----\n* 作为普通HTTP(S)代理服务器使用\n* 抓包调试, web页面查看流量\n* 流量持久化到`leveldb`中, 可用于后期分析\n* 拦截请求自定义逻辑\n\n\n截图\n---\n\n![列表](https://raw.githubusercontent.com/ouqiang/mars/master/screenshot/list.png)\n![详情](https://raw.githubusercontent.com/ouqiang/mars/master/screenshot/detail.png)\n\n\n\n## 目录\n\n* [下载](#下载)\n* [安装](#安装)\n    * [二进制安装](#二进制安装)\n    * [源码安装](#源码安装)\n* [配置文件](#配置文件)\n* [命令](#命令)\n* [结合其他程序使用](#结合其他程序使用)\n    * [Nginx](#nginx)\n    * [frp](#frp)\n* [开发](#开发)\n    * [服务端](#服务端)\n    * [前端](#前端)\n        * [基于已有代码开发](#基于已有代码开发)\n        * [自定义实现](#自定义实现)\n\n## 下载\n\n[releases](https://github.com/ouqiang/mars/releases)\n\n## 安装\n\n\n### 二进制安装\n1. 解压压缩包\n2. 启动: ./mars server\n3. 访问代理: http://localhost:8888\n4. 查看流量web页: http://localhost:9999, 客户端可扫描二维码下载根证书\n\n\n### docker\n\n```bash\ndocker run --name mars -p 8888:8888 -p 9999:9999 -d ouqg/mars:1.0.0\n```\n\n配置: /app/conf/app.toml\n\n### 源码安装\nGo版本1.11+\n启用go module\n```bash\nexport GO111MODULE=on\n```\n\n启动: `make run`\n\n## 配置文件\n配置支持通过环境变量覆盖, 如`MARS_APP_PROXYPORT=8080`\n\n```toml\n[app]\nhost = \"0.0.0.0\"\n# 代理监听端口\nproxyPort = 8888\n# 查看流量web页监听端口\ninspectorPort = 9999\n\n\n[mitmProxy]\n# 是否开启中间人代理，不开启则盲转发\nenabled = true\n# 是否解密HTTPS, 客户端系统需安装根证书\ndecryptHTTPS = false\n# 证书缓存大小\ncertCacheSize = 1000\n# 数据缓存大小\nleveldbCacheSize = 1000\n```\n\n## 命令\n\n### 查看版本\n```bash\n$ ./mars version\n\n   Version: v1.0.0\nGo Version: go1.11\nGit Commit: 2151a6d\n     Built: 2018-11-18 20:04:17\n   OS/ARCH: darwin/amd64\n```\n\n### 命令行参数\n```bash\n$ ./mars server -h\nrun proxy server\n\nUsage:\n  mars server [flags]\n\nFlags:\n  -c, --configFile string   config file path (default \"conf/app.toml\")\n  -e, --env string          dev | prod (default \"prod\")\n  -h, --help                help for server\n```\n\n\n## 结合其他程序使用\n\n经过`mars`的流量可在web页查看\n\n### Nginx\n请求包含特定header, 则转发给`mars`, 由`mars`访问实际的后端\n\n原配置\n```nginx\nproxy_pass http://172.16.10.103:8080;\n```\n\n使用`mars`后的配置\n```nginx\n set $targetHost $host;\n\n if ($http_x_mars_debug = \"1\") {\n   set $targetHost \"172.16.10.103:8080\";\n }\n\n proxy_set_header X-Mars-Host $host;\n proxy_set_header Host $targetHost;\n if ($http_x_mars_debug = \"1\") {\n   proxy_pass http://127.0.0.1:8888;\n   break;\n }\n```\n\n### frp\n\n原配置\n\n```ini\n[web]\ntype = http\nlocal_ip = 127.0.0.1\nlocal_port = 80\nsubdomain = test\n```\n\n使用`mars`后的配置\n\n```ini\n[web]\ntype = http\nlocal_ip = 127.0.0.1\nlocal_port = 8888\nsubdomain = test\nhost_header_rewrite = 127.0.0.1:80\n```\n\n## 开发\n\n### 服务端\n\n#### 拦截请求\n实现`Interceptor`接口, 参考`interceptor/example.go`\n```go\n// Interceptor 拦截器\ntype Interceptor interface {\n\t// Connect 收到客户端连接, 自定义response返回\n\tConnect(ctx *goproxy.Context, rw http.ResponseWriter)\n\t// BeforeRequest 请求发送前, 修改request\n\tBeforeRequest(ctx *goproxy.Context)\n\t// BeforeResponse 响应发送前, 修改response\n\tBeforeResponse(ctx *goproxy.Context, resp *http.Response, err error)\n}\n```\n\n### 自定义存储\n默认存储为`leveldb`\n\n实现`Storage`接口\n```go\n// Storage 存取transaction接口\ntype Storage interface {\n\tGet(txId string) (*Transaction, error)\n\tPut(*Transaction) error\n}\n```\n\n#### 自定义输出\n内置输出到console、websocket\n实现`Output`接口\n```go\n// Output 输出transaction接口\ntype Output interface {\n\tWrite(*Transaction) error\n}\n```\n\n### make\n\n* `make` 编译\n* `make run` 编译并运行\n* `make package` 生成当前平台的压缩包\n* `make package-all` 生成Windows、Linux、Mac的压缩包\n\n\n## 前端\n\n### 基于已有代码开发\nVue + Element UI\n\n1. 安装Go1.11+, Node.js, Yarn\n2. 安装前端依赖 `make install-vue`\n3. 启动mars: `make run`\n4. 启动node server: `make run-vue`\n5. App.vue中替换websocket连接地址为`http://localhost:9999`\n6. 打包: `make build-vue`\n7. 安装静态文件嵌入工具`go get github.com/rakyll/statik`\n8. 静态文件嵌入`make statik`\n\n### 自定义实现\n基于websocket, 消息序列化协议: `json`\n消息格式, 请求响应相同\n```json\n{\n  \"type\": 3000,\n  \"payload\": {}\n}\n```\n\ntype取值范围\n\n- 1000 \\- 1999 客户端请求\n- 2000 \\- 2999 服务端响应\n- 3000\\+ 服务端主动推送\n\n\n### websocket连接\n```javascript\nvar ws = new WebSocket('http://localhost:9999/ws')\n```\n\n### 发送心跳\n\u003e 心跳超时为30秒，连续两次超时将断开连接\n\n请求\n```json\n{\n  \"type\": 1000,\n  \"payload\": {}\n}\n```\n响应\n```json\n{\n  \"type\": 2000,\n  \"payload\": {}\n}\n```\n\n### 服务端主动推送\n\n只包含transaction基本信息\n```json\n{\n  \"type\": 3000,\n  \"payload\": {\n    \"id\": \"b56cb03d-855c-48a2-81e8-bbf71f285ecf\",\n    \"method\": \"GET\",\n    \"host\": \"api.zhihu.com\",\n    \"path\": \"/user-permission\",\n    \"duration\": 235519397,\n    \"response_status_code\": 200,\n    \"response_err\": \"\",\n    \"response_content_type\": \"application/json\",\n    \"response_len\": 135\n  }\n}\n```\n\n### 获取transaction详情\n\n请求\n```json\n{\n  \"type\": 1002,\n  \"payload\": {\n    \"id\": \"b56cb03d-855c-48a2-81e8-bbf71f285ecf\"\n  }\n}\n```\n\n响应\n```json\n{\n  \"type\": 2002,\n  \"payload\": {\n    \"id\": \"b56cb03d-855c-48a2-81e8-bbf71f285ecf\",\n    \"request\": {\n      \"proto\": \"HTTP/1.1\",\n      \"method\": \"GET\",\n      \"scheme\": \"https\",\n      \"host\": \"api.zhihu.com\",\n      \"path\": \"/user-permission\",\n      \"query_param\": \"\",\n      \"url\": \"https://api.zhihu.com/user-permission\",\n      \"header\": {\n        \"Accept\": [\n          \"*/*\"\n        ],\n        \"Accept-Encoding\": [\n          \"gzip\"\n        ],\n        \"Accept-Language\": [\n          \"zh-Hans-CN;q=1\"\n        ],\n        \"Authorization\": [\n          \"Bearer 1.1bLEjAAAAAAALAAAAYAJVTV24_lu6fCJ9XPT_pE20Kz4dyYRvaGS-ig==\"\n        ],\n        \"Connection\": [\n          \"keep-alive\"\n        ],\n        \"Cookie\": [\n          \"__DAYU_PP=AIzQaiFNaFRiERJrz3j2283b3752faa9; q_c1=51271b5b715943cb88a2f422af28e9c9|1538884401000|1520866854000; tgw_l7_route=b3dca7eade474617fe4df56e6c4934a3; q_c1=51271b5b715943cb88a2f422af28e9c9|1520866854000|1520866854000; q_c0=2|1:0|10:1540828001|4:q_c0|80:MS4xYkxFakFBQUFBQUFMQUFBQVlBSlZUVjI0X2x1NmZDSjlYUFRfcEUyMEt6NGR5WVJ2YUdTLWlnPT0=|8c53af477e6ab8308cceb3dde6fe1d526a61448ee32d75f28ad0f27636bcc31e; _xsrf=RT2pK2qfoxGR1wz3dOglH9qN9uYhQFVK; _zap=2f1250a9-d774-4358-9dde-e23cb7b10c29; z_c0=\\\"2|1:0|10:1540828001|4:z_c0|80:MS4xYkxFakFBQUFBQUFMQUFBQVlBSlZUVjI0X2x1NmZDSjlYUFRfcEUyMEt6NGR5WVJ2YUdTLWlnPT0=|e7557ab66cf63a82219c13a6851422df7ca3c045eb94a5ab346ee3e9a69894c2\\\"; d_c0=ADACbVFThQtLBcMEYw22mGbJ-vZ5Oy5ayzg=|1542635918; zst_82=1.0AOAhgq8kiw4LAAAASwUAADEuMI3B8lsAAAAAiqMViyRX9WuT68jWP347p59s3mQ=\"\n        ],\n        \"User-Agent\": [\n          \"osee2unifiedRelease/4.27.1 (iPad; iOS 12.0; Scale/2.00)\"\n        ],\n        \"X-Ab-Param\": [\n          \"top_gr_model=0;top_hweb=0;ls_new_video=1;se_consulting_switch=off;top_feedre_rtt=41;top_root_web=0;tp_favsku=a;se_ad_index=9;se_wiki_box=1;top_recall_deep_user=1;top_roundtable=1;top_uit=0;tp_sft=a;zr_ans_rec=gbrank;se_gemini_service=content;top_billboard_count=1;top_multi_model=0;top_recall=1;top_root_few_topic=0;top_vd_gender=0;top_manual_tag=1;top_feedre_itemcf=31;se_majorob_style=0;top_vds_alb_pos=0;se_minor_onebox=d;top_root_ac=1;top_new_user_gift=0;top_memberfree=1;top_video_rew=0;top_ad_slot=1;top_recall_tb=4;top_video_fix_position=5;top_follow_reason=0;top_sjre=0;se_merger=1;se_refactored_search_index=0;top_billpic=0;top_local=1;top_user_gift=0;top_tagore_topic=0;top_yc=0;top_hca=0;se_rescore=1;top_newfollow=0;top_recall_follow_user=91;top_recommend_topic_card=0;top_tffrt=0;top_recall_tb_follow=71;top_card=-1;top_gr_topic_reweight=0;top_login_card=1;tp_write_pin_guide=3;top_an=0;top_recall_tb_long=51;top_spec_promo=1;pin_ef=orig;se_consulting_price=n;top_mt=0;top_quality=0;se_cm=1;top_nid=0;top_nmt=0;top_distinction=3;se_billboard=3;top_recall_tb_short=61;top_rerank_reweight=-1;top_wonderful=1;top_billupdate1=3;se_new_market_search=on;se_relevant_query=new;top_mlt_model=4;top_newfollowans=0;top_nuc=0;top_sj=2;top_vdio_rew=3;se_tf=1;top_gif=0;top_rank=0;top_tmt=0;top_lowup=1;top_tagore=1;top_video_score=1;se_correct_ab=1;top_ebook=0;top_rerank_isolation=-1;se_major_onebox=major;top_vd_rt_int=0;top_adpar=0;top_root=1;top_tuner_refactor=-1;top_v_album=1;top_no_weighing=1;top_yhgc=0;se_dl=1;top_deep_promo=0;top_fqai=2;top_rerank_repos=-1;top_tr=0;top_dtmt=2;top_raf=n;top_rerank_breakin=-1;se_product_rank_list=0;top_hqt=9;top_nad=1;top_promo=1;top_universalebook=1;top_f_r_nb=1;se_gi=0;se_ingress=on;se_websearch=0;top_test_4_liguangyi=1;top_topic_feedre=21;top_billread=1;top_billvideo=0;top_ntr=1;top_recall_core_interest=81;tp_discussion_feed_type_android=0;top_new_feed=1;top_ac_merge=0;top_slot_ad_pos=1;top_bill=0;top_feedre=1;top_pfq=5;top_retag=0;top_nszt=0;se_entity=on;se_shopsearch=1;pin_efs=orig;se_daxuechuisou=new;top_followtop=1;ls_is_use_zrec=0;se_ltr=1;top_videos_priority=-1;top_alt=0;tp_ios_topic_write_pin_guide=1;se_filter=0;top_30=0;top_feedre_cpt=101;top_vd_op=1;se_dt=1;top_billab=0;tp_discussion_feed_card_type=0;top_ab_validate=3;top_cc_at=1;top_free_content=-1;top_root_mg=1;top_is_gr=0;top_tag_isolation=0;ls_new_score=0;se_cq=0;top_fqa=0;top_feedtopiccard=0;top_retagg=0;se_engine=0;top_gr_auto_model=0;top_nucc=3;se_auto_syn=0\"\n        ],\n        \"X-Ad-Styles\": [\n          \"brand_card_article_video=4;plutus_card_word_30_download=2;brand_feed_small_image=3;plutus_card_video_8_download=4;plutus_card_multi_images_30_download=2;plutus_card_image_8=1;brand_feed_hot_small_image=1;plutus_card_multi_images=5;plutus_card_window=2;plutus_card_window_8=2;brand_card_normal=3;plutus_card_image_31=2;plutus_card_multi_images_30=3;plutus_card_multi_images_8_download=1;plutus_card_word_8_download=1;plutus_card_image_31_download=2;plutus_card_slide_image_31_download=1;brand_card_question=4;brand_card_article_multi_image=5;brand_feed_active_right_image=6;brand_card_question_multi_image=5;plutus_card_small_image_8_download=1;plutus_card_image_30=2;plutus_card_word=4;plutus_card_image_30_download=2;plutus_card_word_8=1;plutus_card_video=5;plutus_card_video_8=4;plutus_card_image=14;brand_card_multi_image=2;plutus_card_small_image_8=1;plutus_card_video_30_download=2;plutus_card_image_8_download=1;plutus_card_video_30=2;brand_card_article=4;plutus_card_multi_images_8=1;brand_card_question_video=4;plutus_card_small_image=5;brand_card_video=2;plutus_card_slide_image_31=1;plutus_card_word_30=2;\"\n        ],\n        \"X-Api-Version\": [\n          \"3.0.92\"\n        ],\n        \"X-App-Build\": [\n          \"release\"\n        ],\n        \"X-App-Version\": [\n          \"4.27.1\"\n        ],\n        \"X-App-Versioncode\": [\n          \"1132\"\n        ],\n        \"X-App-Za\": [\n          \"OS=iOS\u0026Release=12.0\u0026Model=iPad4,1\u0026VersionName=4.27.1\u0026VersionCode=1132\u0026Width=1536\u0026Height=2048\u0026DeviceType=Pad\u0026Brand=Apple\u0026OperatorType=\"\n        ],\n        \"X-Network-Type\": [\n          \"WiFi\"\n        ],\n        \"X-Suger\": [\n          \"SURGVj1EQkJDMDQ0QS0wNzg2LTQyNTctQTUzNC1FQkJEQjI1QzU3QkM7SURGQT1DODMxQkExMC00QjBBLTRCMDgtQkJBQS02OEY3NzQwRUZCRjA7VURJRD1BREFDYlZGVGhRdExCY01FWXcyMm1HYkotdlo1T3k1YXl6Zz0=\"\n        ],\n        \"X-Udid\": [\n          \"ADACbVFThQtLBcMEYw22mGbJ-vZ5Oy5ayzg=\"\n        ],\n        \"X-Zst-82\": [\n          \"1.0AOAhgq8kiw4LAAAASwUAADEuMI3B8lsAAAAAiqMViyRX9WuT68jWP347p59s3mQ=\"\n        ]\n      },\n      \"body\": {\n        \"is_binary\": true,\n        \"len\": 0,\n        \"content_type\": \"application/octet-stream\",\n        \"content\": \"\"\n      }\n    },\n    \"response\": {\n      \"proto\": \"HTTP/2.0\",\n      \"status\": \"200 OK\",\n      \"status_code\": 200,\n      \"header\": {\n        \"Cache-Control\": [\n          \"private, no-store, max-age=0, no-cache, must-revalidate, post-check=0, pre-check=0\"\n        ],\n        \"Content-Length\": [\n          \"135\"\n        ],\n        \"Content-Type\": [\n          \"application/json\"\n        ],\n        \"Date\": [\n          \"Mon, 19 Nov 2018 14:12:22 GMT\"\n        ],\n        \"Etag\": [\n          \"\\\"557bd35b6d00324ff54d745626c212c8c4fa3d4d\\\"\"\n        ],\n        \"Expires\": [\n          \"Fri, 02 Jan 2000 00:00:00 GMT\"\n        ],\n        \"Pragma\": [\n          \"no-cache\"\n        ],\n        \"Server\": [\n          \"ZWS\"\n        ],\n        \"Vary\": [\n          \"Accept-Encoding\"\n        ],\n        \"X-Backend-Server\": [\n          \"user-credit.user-credit-web.4c1fb8f9---10.70.9.35:31024[10.70.9.35:31024]\"\n        ],\n        \"X-Rsp-Hash\": [\n          \"17a4e2aa9f88c80631a29c9406db5c525598d858d3841f8cea6bb4a6e2f33aa4\"\n        ]\n      },\n      \"body\": {\n        \"is_binary\": false,\n        \"len\": 135,\n        \"content_type\": \"application/json\",\n        \"content\": \"eyJpc19xdWVzdGlvbl9yZWRpcmVjdF9lZGl0YWJsZSI6IGZhbHNlLCAiaXNfcXVlc3Rpb25fdG9waWNfZWRpdGFibGUiOiBmYWxzZSwgImlzX3F1ZXN0aW9uX2VkaXRhYmxlIjogZmFsc2UsICJjb21tZW50X3dpdGhfcGljIjogZmFsc2V9\"\n      },\n      \"err\": \"\"\n    },\n    \"client_ip\": \"172.16.10.104\",\n    \"server_ip\": \"118.89.204.100\",\n    \"start_time\": \"2018-11-19T22:12:22.00511+08:00\",\n    \"duration\": 235519397,\n    \"err\": \"\"\n  }\n}\n```\n\n### 请求重放\n\n请求\n```json\n{\n  \"type\": 1001,\n  \"payload\": {\n    \"id\": \"b56cb03d-855c-48a2-81e8-bbf71f285ecf\"\n  }\n}\n```\n\n响应\n```json\n{\n  \"type\": 2001,\n  \"payload\": {\n    \"err\": \"\"\n  }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fouqiang%2Fmars","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fouqiang%2Fmars","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fouqiang%2Fmars/lists"}