├── .gitignore
├── README.MD
├── dumphrun
├── 20190521234042_intercept.log
├── __init__.py
├── casefactory.py
├── casetmp.py
├── filetools.py
├── hrun_case.json
├── hrun_case_back.json
├── proxyserver.py
├── reports
│ ├── 1558442162.html
│ ├── 1558442233.html
│ ├── 1558448260.html
│ ├── 1558448626.html
│ ├── 1558448818.html
│ ├── 1558449341.html
│ ├── 1558449652.html
│ ├── 1558449699.html
│ ├── 1558449741.html
│ ├── 1558451350.html
│ ├── 1558451916.html
│ ├── 1558452980.html
│ └── 1558453682.html
└── test.py
├── mitm.png
├── proxy.png
├── proxy
├── 20190521225436_intercept.log
├── __init__.py
├── backups.py
├── constant.py
├── filetools.py
├── genhtml.py
├── logger.py
├── mathrandom.py
├── parserjson.py
├── proxyrule.py
├── proxyserver.py
├── run.py
├── script.py
└── templates
│ └── template.html
├── run.sh
├── 报告1.jpg
└── 报告2.jpg
/.gitignore:
--------------------------------------------------------------------------------
1 | tutorial-env
2 | proxy/reports/*
3 | *.pyc
4 | .idea
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | # 介绍
2 |
3 | 使用mitproxy代理工具做自动化Mock数据测试,来验证移动端app对数据的容错性.
4 |
5 |
6 | # 环境搭建
7 |
8 | ## 创建虚拟环境(python 3.7)
9 | ```angularjs
10 | python3.7 -m venv tutorial-env
11 |
12 | source tutorial-env/bin/activate (创建虚拟环境)
13 |
14 | deactivate (退出虚拟环境)
15 | ```
16 |
17 | ## 安装依赖
18 | ```angular2html
19 | pip3 install mitmproxy
20 |
21 | pip3 install jsonpath-rw
22 |
23 | pip3 install colorama
24 |
25 | pip3 install colorlog
26 | ```
27 |
28 |
29 | # 规则
30 | ```
31 | 随机对请求数据做随机拦截篡改,支持事件如下:
32 | 1.随机对返回value做修改/删除
33 | 2.随机对返回list做删除 (可能会引起客户端崩溃,慎用)
34 | 3.随机对返回接口状态码修改
35 | 4.随机对返回接口时间做延迟修改
36 | ```
37 |
38 |
39 | ## 使用
40 |
41 | ### 手机连接代理
42 | 移动设备和电脑保存在一个wifi网络下,在移动设备在网络代理填写电脑ip+8080(端口)
43 |
44 | 
45 |
46 | ### mitproxy https证书安装
47 | ```
48 | 在浏览器输入:mitm.it,选择Android证书下载并安装
49 | ```
50 | 
51 |
52 |
53 | ### 执行mock数据
54 | ```angularjs
55 | mitmdump -s proxyserver.py
56 | ```
57 |
58 | ### 生成报告
59 | ```angularjs
60 | 参数1:需要保存的报告地址
61 | 参数2:保存到本地篡改数据地址
62 | python genhtml.py ~/PycharmProjects/mitmproxytest/proxy ~/PycharmProjects/mitmproxytest/proxy/20190521143711_intercept.log
63 | ```
64 |
65 | # 展示
66 |
67 | 
68 |
69 | 
70 |
71 |
72 | # 参考
73 | mitmproxy的github
74 | https://github.com/mitmproxy/mitmproxy.git
--------------------------------------------------------------------------------
/dumphrun/20190521234042_intercept.log:
--------------------------------------------------------------------------------
1 | http://entree.dev.igetget.com/kaleidoscope/homepage/new_structure|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '8742eb6af715b8e2c9c726a42ce8b48c', 'X-Hitdot': '', 'G-Auth-Sign': 'NTMyYzc1YjVlMWUzOTFiNzU4NDRlNGEzNmRjMDJlN2Q=', 'G-Auth-Nonce': '2d4810c940f22e5ac8793de5bcf75ebf', 'G-Auth-Ts': '1558453246', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTc4OTMsImlhdCI6MTU1ODQ1MzA5MywiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMwOTMsInN1YiI6Ijg0ODQ2Mjc0In0.bXQPMyrUyCZ5r6UvYXVpmENh9wXvunZA8ckdAPoHnVYyx4vxdqUyCke1NehM7IFiM5pW9ZfyTYO4BWrV9PTVmA', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '363', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'page_type': '{ "page_type": "A", "list": [ ] }', 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453246', 's': 'db578eef9d289db9', 'seid': '8742eb6af715b8e2c9c726a42ce8b48c'}}
2 | http://dedao.dev.igetget.com/v3/adv/homepage?sign=2e53d78792ce6406510a5dca6db3d600|POST|{'Cache-Control': 'no-cache', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '309', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453246', 's': 'db578eef9d289db9', 'seid': '8742eb6af715b8e2c9c726a42ce8b48c'}}
3 | http://dedao.dev.igetget.com/v3/igettv/structuredata?sign=847fae0f5aaba7f777b0f7fd3f05fc2f|POST|{'Cache-Control': 'no-cache', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '327', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'struct_id': 25490, 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453247', 's': 'db578eef9d289db9', 'seid': '8742eb6af715b8e2c9c726a42ce8b48c'}}
4 | http://dedao.dev.igetget.com/v3/hotfix/getHotFix?sign=56b1b5c590776d65881f2e31252a30e5|POST|{'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 6.0; Samsung Galaxy S6 Build/MRA58K)', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'Content-Length': '324'}|{'h': {'u': '84846274', 's': 'db578eef9d289db9', 'os': 'ANDROID', 'av': '6.2.0', 'v': '2', 'd': 'ae244834553d4eda', 't': 'json', 'ts': '1558451044', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'dv': 'Samsung Galaxy S6', 'chil': '0', 'scr': '0', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'adv': '1'}, 'type': 'android', 'version': '6.2.0.SNAPSHOT'}
5 | http://dedao.dev.igetget.com/v3/hotfix/getHotFix?sign=56b1b5c590776d65881f2e31252a30e5|POST|{'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 6.0; Samsung Galaxy S6 Build/MRA58K)', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'Content-Length': '324'}|{'h': {'u': '84846274', 's': 'db578eef9d289db9', 'os': 'ANDROID', 'av': '6.2.0', 'v': '2', 'd': 'ae244834553d4eda', 't': 'json', 'ts': '1558451044', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'dv': 'Samsung Galaxy S6', 'chil': '0', 'scr': '0', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'adv': '1'}, 'type': 'android', 'version': '6.2.0.SNAPSHOT'}
6 | http://dedao.dev.igetget.com/v3/user/recordtoken?sign=1bb033a2fcf15413fbac0b1648b0dc15|POST|{'Cache-Control': 'no-cache', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '457', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453265', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}, 'rom': 'sys_name:unknow|sys_version:6.0', 'token': '3hDaKamogI8GYBfigOoy2mXCbM8syOMV4Se4l0uLl/+8G4XMLdJc98vMLrBwm4N/', 'type': 'XIAOMI', 'device': 'ANDROID'}
7 | http://dedao.dev.igetget.com/v3/appmanage/getnewversion?sign=b8f05b54e4a381b4b30966a44bfe6cf3|POST|{'Cache-Control': 'no-cache', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '382', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'ANDROID', 'os': '6.0', 'version': '6.2.0', 'token': 'ae244834553d4eda', 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453291', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
8 | http://entree.dev.igetget.com/kaleidoscope/v1/recommend/home|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'ZGIwOTFiOTU2ZWIxZTk3NjRiOWFiYTAxNWIzZmVkZjU=', 'G-Auth-Nonce': '2c8af9a057bb6bab32df3ed0f403da9d', 'G-Auth-Ts': '1558453353', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '596', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'page_id': 1, 'page_size': 20, 'is_login': 1, 'ext': [{'count': 0, 'data': {}, 'has_title': 2, 'page_type': 124, 'position': 4, 'struct_id': 25484, 'type': 'RecommendGoods'}, {'count': 0, 'data': {}, 'has_title': 2, 'page_type': 125, 'position': 5, 'struct_id': 25485, 'type': 'RecommendFeedBanner'}], 'is_label_select': 0, 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453352', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
9 | http://dedao.dev.igetget.com/v3/columnnote/userLineation?sign=94f892cd3dc6497130df52ea8f98748e|POST|{'Cache-Control': 'no-cache', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '369', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'aid': '1000047', 'type': 22, 'audio_id': 'kMXatYiKopG0DQVjWDee', 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453356', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
10 | http://dedao.dev.igetget.com/v3/columnnote/userLineation?sign=853000a7e9e2c804dd748fe4dc022952|POST|{'Cache-Control': 'no-cache', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '366', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'aid': '3809', 'type': 13, 'audio_id': 'vAkdmo4jroFNvu263tkH', 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453391', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
11 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'ODQ2YmZjOGIxMDk3Y2EwZDYwZjAxYmZhMjRjNWY3MTY=', 'G-Auth-Nonce': '10d49a960f18f4f1f444cacbc4b569cb', 'G-Auth-Ts': '1558453395', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '449', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'start', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 0.0, 'time': 1558453395, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453395', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
12 | http://dedao.dev.igetget.com/v3/shzf/homepage?sign=11d6a00a99d5e1431450679406b2d091|POST|{'Cache-Control': 'no-cache', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '327', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'struct_id': 25484, 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453409', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
13 | http://dedao.dev.igetget.com/v3/shzf/homepage?sign=c628931ca844332f17d8df896b3f8002|POST|{'Cache-Control': 'no-cache', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '327', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'struct_id': 25484, 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453410', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
14 | http://dedao.dev.igetget.com/v3/columnnote/userLineation?sign=a6af795ab0620fc235c0ead94c18c8fe|POST|{'Cache-Control': 'no-cache', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '366', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'aid': '3809', 'type': 13, 'audio_id': 'vAkdmo4jroFNvu263tkH', 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453417', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
15 | http://dedao.dev.igetget.com/v3/columnnote/userLineation?sign=b88f8e467b62a74c5b35514bef06fa94|POST|{'Cache-Control': 'no-cache', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '366', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'aid': '3809', 'type': 13, 'audio_id': 'vAkdmo4jroFNvu263tkH', 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453429', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
16 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'ZDgwM2QxMmJiNzA4M2ZmNDBkZWVmODBlNzE3OTY3NWE=', 'G-Auth-Nonce': '6e6b9cbe366f2d6db0a4e84982848200', 'G-Auth-Ts': '1558453434', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '462', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'pause', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 2.34, 'reason': '', 'time': 1558453434, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453434', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
17 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'MGJlMDZmMzg3NTg3NWMzMzJmNjBhNzhhYmMwNjc3OWI=', 'G-Auth-Nonce': '494bfc76adbb174c2b800d328671132b', 'G-Auth-Ts': '1558453434', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '578', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'pause', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 2.34, 'reason': '', 'time': 1558453434, 'type': 'audio', 'uid': 84846274}, {'action': 'goon', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 2.34, 'time': 1558453434, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453434', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
18 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'NmZjYTUxNTFiYzkyM2NlZWY0MjUyODY0MGZmYTM5YzU=', 'G-Auth-Nonce': '09fa4a84cfe0e793db7c496f13d6c8e3', 'G-Auth-Ts': '1558453445', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '462', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'pause', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 2.99, 'reason': '', 'time': 1558453445, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453445', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
19 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'NGY0OTcyMjAxYjk3OGEwYThmZGQ0YTJjMTY0NWE4OGY=', 'G-Auth-Nonce': 'f5ee4f5fc26b980cc37767f777621d64', 'G-Auth-Ts': '1558453446', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '462', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'pause', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 2.99, 'reason': '', 'time': 1558453446, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453446', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
20 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'YjhjNTJkYmExNTMyODhjYjhhZTcxOGU0MTA1NmU3NzM=', 'G-Auth-Nonce': '411b57892b891b6548d71851700ffbc1', 'G-Auth-Ts': '1558453447', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '449', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'goon', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 2.99, 'time': 1558453446, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453446', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
21 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'MjljYzgzY2ZkODZlMDZiMmJkZjM0ZTFkMjkyZjYzZjM=', 'G-Auth-Nonce': 'd43fc3b8f646308233b7fc36eb0cdb10', 'G-Auth-Ts': '1558453452', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '462', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'pause', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 3.18, 'reason': '', 'time': 1558453451, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453451', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
22 | http://dedao.dev.igetget.com/v3/columnnote/userLineation?sign=e25310c6b941fccc86298c34234cbc1d|POST|{'Cache-Control': 'no-cache', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '366', 'Host': 'dedao.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'aid': '3809', 'type': 13, 'audio_id': 'vAkdmo4jroFNvu263tkH', 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453459', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
23 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'MjQxNTM0MDJmM2FlM2U3ZjY3MjFiZjQ1MDM3YjJjYzA=', 'G-Auth-Nonce': 'fb7739bc960d6ac933b03e088abc8033', 'G-Auth-Ts': '1558453477', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '451', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'resume', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 3.18, 'time': 1558453477, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453477', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
24 | http://entree.dev.igetget.com/odob/v2/audio/detail|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'MTI0NjU0MGRmZjJjMmY3YzhlNWMwMmE2OTZkNzkyNjA=', 'G-Auth-Nonce': '81eba977ec71d2da6ace6fa4b200d34a', 'G-Auth-Ts': '1558453497', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '325', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'topic_id': 3809, 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453497', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
25 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'MzA5YjhmZTUxNWNiZmNmOWIxNDYyOWFmMDk5NzJiYjY=', 'G-Auth-Nonce': 'ab15de0e7422d050a6d572ab967660e7', 'G-Auth-Ts': '1558453498', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '480', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'pause', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 4.55, 'reason': 'MediaSession-pause', 'time': 1558453497, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453497', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
26 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'YmZlZjU2M2FjNmJhNGI1OTdmNjNmNGQwZmY1ZjM5NzQ=', 'G-Auth-Nonce': '9b38283bfcd93249632ff9b56f10e180', 'G-Auth-Ts': '1558453498', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '449', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'goon', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 4.48, 'time': 1558453498, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453498', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
27 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'NDJiMWYyODYwY2NhNTRlNWU3MDRjYTRlODIyMDkwMTU=', 'G-Auth-Nonce': '863d94df3c3ecaa4ee00ead46c34b35f', 'G-Auth-Ts': '1558453523', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '462', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'pause', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 5.98, 'reason': '', 'time': 1558453523, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453523', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
28 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'MDlmNjAxNTRmOTNhYjViODA5NWYwNDVlOTRhZmRlM2Y=', 'G-Auth-Nonce': '5ee3147409383c03108874c5ceb3a2fa', 'G-Auth-Ts': '1558453542', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '451', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'resume', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 5.98, 'time': 1558453542, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453542', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
29 | http://entree.dev.igetget.com/odob/v2/audio/detail|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'MDgyMmQ2MDAzNGVkZThhMjk2YmM0ZGUxZTJkODk5OGI=', 'G-Auth-Nonce': 'b08f1224e1ca49fec5bde0fa4dbd50ef', 'G-Auth-Ts': '1558453549', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '325', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'topic_id': 3809, 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453549', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
30 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'MDU1N2U2OWY2ZDQyNTdiOTk4ZDg4ZDU2NWMwNjg5ZDQ=', 'G-Auth-Nonce': '321edb94f45dcc52d73949c64ef25244', 'G-Auth-Ts': '1558453550', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '461', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'pause', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 6.5, 'reason': '', 'time': 1558453550, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453550', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
31 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'NjUzMWY3YjJkYTk0YjgwNTc3MGY1ODU0MGJjZjhjZTM=', 'G-Auth-Nonce': '25f608945bc0ecc47fdd2cd9b0230c3e', 'G-Auth-Ts': '1558453550', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '449', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'goon', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 6.43, 'time': 1558453550, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453550', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
32 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'ZWVhMDY2ZDcyZDJiZjgwM2U2ODViYTNjZTZhNmNkMGI=', 'G-Auth-Nonce': '86b4ba5cc31978c3c4fc0686dace640a', 'G-Auth-Ts': '1558453555', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '462', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'pause', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 6.69, 'reason': '', 'time': 1558453555, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453555', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
33 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'ODk5ODk2NGFjMmQwM2U5OTgwZmFkYTRmNWZhMTBlNTM=', 'G-Auth-Nonce': '7321602ea9df8c693bdf8ffe49e56cc9', 'G-Auth-Ts': '1558453557', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '451', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'resume', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 6.69, 'time': 1558453557, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453557', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
34 | http://entree.dev.igetget.com/odob/v2/audio/detail|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'YjIzYzA3MGU4OTA1MDU4OGVkMWJlODU3MDc0MDM2NmQ=', 'G-Auth-Nonce': 'f467a2ec959855da3afefc3923c3ef09', 'G-Auth-Ts': '1558453623', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '325', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'topic_id': 3809, 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453623', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
35 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'YjNlMmRhODQxMzAwY2E4ZTE0MDI0NWI2YzRmMDRiMTQ=', 'G-Auth-Nonce': 'f7e37d661c01209ae1544094f3fd3dc8', 'G-Auth-Ts': '1558453624', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '463', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'pause', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 10.98, 'reason': '', 'time': 1558453624, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453624', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
36 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'MTA3YTBjMTI2NDgwMjhkNzRlZjUzNGRkNjE3MmFjMWQ=', 'G-Auth-Nonce': 'dcaa5fb21dfd66f08d9805179c86d61e', 'G-Auth-Ts': '1558453626', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '450', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'goon', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 10.92, 'time': 1558453626, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453626', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
37 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'OWE5YjFkZTIxN2UxNDU5NzhkNTE4NDNlZGZjYWNjYjY=', 'G-Auth-Nonce': '69702b2fd14d6a0006c3d8b6259a68fd', 'G-Auth-Ts': '1558453632', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '450', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'goon', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 11.11, 'time': 1558453632, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453632', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
38 | http://entree.dev.igetget.com/centerproducer/v1/audio/actionpost|POST|{'X-App-Key': 'android-6.2.0', 'X-Uid': '84846274', 'X-Thumb': 'l', 'X-Dt': 'phone', 'X-Ov': '6.0', 'X-Net': 'WIFI', 'X-Os': 'ANDROID', 'X-D': 'ae244834553d4eda', 'X-Dv': 'Samsung Galaxy S6', 'X-T': 'json', 'X-Chil': '0', 'X-V': '2', 'X-Av': '6.2.0', 'X-Scr': '2.0', 'X-Adv': '1', 'X-Seid': '22eb3b6b029be45d7cd5c7e00c14f3a4', 'X-Hitdot': '', 'G-Auth-Sign': 'ZGVkMzlmYTQ3NmZjNjljYzBhMTljZjU3MGUwNDRlYWM=', 'G-Auth-Nonce': '0aff699f73941686bf82e8807b386bfe', 'G-Auth-Ts': '1558453643', 'G-Auth-Appid': '5a27d122ee4638163f594393', 'G-Auth-Token': 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsdW9qaWxhYi5jb20iLCJleHAiOjE1NTkwNTgwNjUsImlhdCI6MTU1ODQ1MzI2NSwiaXNzIjoiRWFzZUdhdGV3YXkgSldUQXV0aCBQbHVnaW4iLCJuYmYiOjE1NTg0NTMyNjUsInN1YiI6Ijg0ODQ2Mjc0In0.J_xlp1L4eCwiUfo8DVjKTRIcbNPIgtoUUJ2iDs3gB2EJDFo_qYcG8l1ZunlvXyYIpLMAEkA4ZyyxvtK1i6S-eQ', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '463', 'Host': 'entree.dev.igetget.com', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip', 'User-Agent': 'okhttp/3.11.0'}|{'type': 'audio', 'data': [{'action': 'pause', 'alias_id': 'vAkdmo4jroFNvu263tkH', 'progress': 39.05, 'reason': '', 'time': 1558453643, 'type': 'audio', 'uid': 84846274}], 'h': {'u': '84846274', 'thumb': 'l', 'dt': 'phone', 'ov': '6.0', 'net': 'WIFI', 'os': 'ANDROID', 'd': 'ae244834553d4eda', 'dv': 'Samsung Galaxy S6', 't': 'json', 'chil': '0', 'v': '2', 'av': '6.2.0', 'scr': '2.0', 'adv': '1', 'X-Dv': 'Samsung Galaxy S6', 'ts': '1558453643', 's': 'db578eef9d289db9', 'seid': '22eb3b6b029be45d7cd5c7e00c14f3a4'}}
39 |
--------------------------------------------------------------------------------
/dumphrun/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xinxi1990/mitmfuzz/807f105788620b5322e1c59db3c46b816a59c24a/dumphrun/__init__.py
--------------------------------------------------------------------------------
/dumphrun/casefactory.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | 批量生成httprunner
6 | """
7 |
8 | import json
9 | import urllib.parse
10 | from casetmp import *
11 |
12 | class CaseFactory():
13 |
14 |
15 | @staticmethod
16 | def gen_case(file_path):
17 | '''
18 | 组装数据
19 | :return:
20 | '''
21 | records = []
22 | with open(file_path) as f_r:
23 | for line in f_r.readlines():
24 | item = line.split('|')
25 | url = item[0]
26 | method = item[1]
27 | header = CaseFactory.gen_header(item[2])[0]
28 | content_type = CaseFactory.gen_header(item[2])[1]
29 | data = CaseFactory.gen_data(item[3])
30 | if method == "GET":
31 | # print(url)
32 | # print(method)
33 | # print(header)
34 | # print(content_type)
35 | # print(data)
36 | get_tmp['test']['request']['url'] = url
37 | get_tmp['test']['request']['headers'] = header
38 | test_case_tmp.append(get_tmp)
39 | elif method == "POST":
40 | post_tmp['test']['request']['url'] = url
41 | post_tmp['test']['request']['headers'] = header
42 | post_tmp['test']['request']['json'] = data
43 | test_case_tmp.append(post_tmp)
44 |
45 | with open('hrun_case.json', 'w') as f_w:
46 | f_w.write(json.dumps(test_case_tmp, indent=4))
47 |
48 |
49 |
50 | # @staticmethod
51 | # def gen_header(headers):
52 | # content_type = ""
53 | # itmes = str((headers.replace('Headers[','')).replace(']','')).split(',')
54 | # key_list = []
55 | # value_list = []
56 | # for item in itmes[::2]:
57 | # # print(item)
58 | # key_list.append(item.replace("('","").replace(")'","").replace("(b","").replace("'","").replace("'","").strip())
59 | # for item in itmes[1::2]:
60 | # # print(item)
61 | # value_list.append(item.replace("('","").replace(")'","").replace("(b","").replace("'","").strip())
62 | # dictionary = dict(zip(key_list, value_list))
63 | # if ('Content-Type' in dictionary):
64 | # content_type = (dictionary["Content-Type"])
65 | # return dictionary,content_type
66 |
67 | # @staticmethod
68 | # def gen_data(data):
69 | # print(data)
70 | # s_data = urllib.parse.unquote(data).replace("b'", '').replace("'", '').replace("\n", "")
71 | # key_list = []
72 | # value_list = []
73 | # for s in s_data.split("&"):
74 | # if "=" in s:
75 | # key_list.append(s.split("=")[0])
76 | # value_list.append(s.split("=")[1])
77 | # dictionary = dict(zip(key_list, value_list))
78 | # return dictionary
79 |
80 |
81 | @staticmethod
82 | def gen_header(headers):
83 | content_type = ""
84 | dictionary = eval(headers)
85 | if ('Content-Type' in dictionary):
86 | content_type = (dictionary["Content-Type"])
87 | return dictionary, content_type
88 |
89 |
90 | @staticmethod
91 | def gen_data(data):
92 | dictionary = {}
93 | try:
94 | dictionary = eval(data)
95 | except Exception as e:
96 | print(e)
97 | return dictionary
98 |
99 |
100 |
101 | if __name__ == '__main__':
102 | print("==================== start gen ====================")
103 | CaseFactory.gen_case('20190521234042_intercept.log')
104 | print("==================== end gen ====================")
--------------------------------------------------------------------------------
/dumphrun/casetmp.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | 生成httprunner测试用例模版
6 | """
7 |
8 | import json
9 |
10 | #
11 | # get_tmp = \
12 | # [
13 | # {
14 | # "config": {
15 | # "name": "testcase description",
16 | # "variables": {}
17 | # }
18 | # },
19 | # {
20 | # "test": {
21 | # "name": "casname",
22 | # "request": {
23 | # "url": "",
24 | # "method": "GET",
25 | # "headers": {
26 | # },
27 | # },
28 | # "validate": [
29 | # {"eq": ["status_code", 200]}
30 | # ]
31 | # }
32 | # }
33 | # ]
34 | #
35 | #
36 | #
37 | # post_tmp = \
38 | # [
39 | # {
40 | # "config": {
41 | # "name": "testcase description",
42 | # "variables": {}
43 | # }
44 | # },
45 | # {
46 | # "test": {
47 | # "name": "casname",
48 | # "request": {
49 | # "url": "",
50 | # "method": "POST",
51 | # "headers": {
52 | # },
53 | # "json": {
54 | # }
55 | # },
56 | # "validate": [
57 | # {"eq": ["status_code", 200]}
58 | # ]
59 | # }
60 | # }
61 | # ]
62 | #
63 | #
64 | #
65 | #
66 | # get_tmp = \
67 | # [
68 | # {
69 | # "config": {
70 | # "name": "testcase description",
71 | # "variables": {}
72 | # }
73 | # },
74 | # {
75 | # "test": {
76 | # "name": "casname",
77 | # "request": {
78 | # "url": "",
79 | # "method": "GET",
80 | # "headers": {
81 | # },
82 | # },
83 | # "validate": [
84 | # {"eq": ["status_code", 200]}
85 | # ]
86 | # }
87 | # }
88 | # ]
89 |
90 |
91 | test_case_tmp = [{
92 | "config": {
93 | "name": "testcase description",
94 | "variables": {}
95 | }
96 | }
97 | ]
98 |
99 |
100 |
101 |
102 | post_tmp = \
103 | {
104 | "test": {
105 | "name": "casname",
106 | "request": {
107 | "url": "",
108 | "method": "POST",
109 | "headers": {
110 | },
111 | "json": {
112 | }
113 | },
114 | "validate": [
115 | {"eq": ["status_code", 200]}
116 | ]
117 | }
118 | }
119 |
120 | get_tmp = \
121 | {
122 | "test": {
123 | "name": "casname",
124 | "request": {
125 | "url": "",
126 | "method": "GET",
127 | "headers": {
128 | },
129 | },
130 | "validate": [
131 | {"eq": ["status_code", 200]}
132 | ]
133 | }
134 | }
135 |
136 |
137 |
138 | # get_tmp[1]['test']['request']['headers'] = headers
139 | # get_tmp[1]['test']['request']['url'] = url
140 |
141 |
142 | # print(json.dumps(get_tmp,indent=4))
143 | #
144 | # with open('hrun_case.json','w') as f_w:
145 | # f_w.write(json.dumps(get_tmp,indent=4))
--------------------------------------------------------------------------------
/dumphrun/filetools.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 |
5 | """
6 | @Author : xinxi
7 | @Time : 2018/12/5 18:34
8 | @describe: 常用操作类
9 | """
10 |
11 | import os,re,time,subprocess,sys
12 | sys.path.append('..')
13 |
14 |
15 |
16 | def write_file(filename,content,is_cover=False):
17 | '''
18 | 写入文件 覆盖写入
19 | :param filename:
20 | :param content:
21 | :param is_cover:是否覆盖写入
22 | :return:
23 | '''
24 | try:
25 | newstr = ""
26 | if isinstance(content,list or tuple):
27 | for str in content:
28 | newstr = newstr + str + "\n"
29 | else:
30 | newstr = content + "\n"
31 | if is_cover == True:
32 | file_mode = "w"
33 | else:
34 | file_mode = "a"
35 | with open(filename,file_mode) as f_w:
36 | f_w.write(newstr)
37 | print('写{}文件完成'.format(filename))
38 | except Exception as e:
39 | print('{}写入异常!{}'.format(filename,e))
40 |
41 |
42 | def del_files(filename):
43 | '''
44 | 删除文件
45 | :param filename:
46 | :return:
47 | '''
48 | try:
49 | if os.path.exists(filename):
50 | subprocess.call("rm -rf {}".format(filename), shell=True)
51 | print('删除{}完成!'.format(filename))
52 | except Exception as e:
53 | print('删除{}异常!{}'.format(filename,e))
54 |
55 |
56 | def mk_dir(foldername):
57 | '''
58 | 创建文件目录
59 | :return:
60 | '''
61 | try:
62 | if not os.path.exists(foldername):
63 | subprocess.call("mkdir {}".format(foldername), shell=True)
64 | print('创建{}完成!'.format(foldername))
65 | except Exception as e:
66 | print('创建{}异常!'.format(foldername,e))
67 |
68 |
69 | def read_file(filename):
70 | '''
71 | 读取文件
72 | :return:
73 | '''
74 | result = ''
75 | try:
76 | with open(filename,"r") as f_r:
77 | result = f_r.readlines()
78 | except Exception as e:
79 | print('{}读取异常!{}'.format(filename,e))
80 | finally:
81 | if isinstance(result,list) and len(result) == 1:
82 | return result[0]
83 | else:
84 | return result
85 |
86 |
87 |
88 | if __name__ == '__main__':
89 | write_file("test.log", "111111", is_cover=False)
90 |
--------------------------------------------------------------------------------
/dumphrun/hrun_case_back.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "config": {
4 | "name": "testcase description",
5 | "variables": {}
6 | }
7 | },
8 | {
9 | "test": {
10 | "name": "casname",
11 | "request": {
12 | "url": "http://dedao.dev.igetget.com/v3/igettv/structuredata?sign=4056bd5301cff045d4c0c2d8856322ea",
13 | "method": "POST",
14 | "headers": {
15 | "Cache-Control": "no-cache",
16 | "Content-Type": "application/json; charset=UTF-8",
17 | "Content-Length": "327",
18 | "Host": "dedao.dev.igetget.com",
19 | "Connection": "Keep-Alive",
20 | "Accept-Encoding": "gzip",
21 | "User-Agent": "okhttp/3.11.0"
22 | },
23 | "json": {
24 | "struct_id": 25490,
25 | "h": {
26 | "u": "84846274",
27 | "thumb": "l",
28 | "dt": "phone",
29 | "ov": "6.0",
30 | "net": "WIFI",
31 | "os": "ANDROID",
32 | "d": "ae244834553d4eda",
33 | "dv": "Samsung Galaxy S6",
34 | "t": "json",
35 | "chil": "0",
36 | "v": "2",
37 | "av": "6.2.0",
38 | "scr": "2.0",
39 | "adv": "1",
40 | "X-Dv": "Samsung Galaxy S6",
41 | "ts": "1558452493",
42 | "s": "db578eef9d289db9",
43 | "seid": "1fdab2a5fa99e1edda214151eefc27d2"
44 | }
45 | }
46 | },
47 | "validate": [
48 | {
49 | "eq": [
50 | "status_code",
51 | 200
52 | ]
53 | }
54 | ]
55 | }
56 | },
57 | {
58 | "test": {
59 | "name": "casname",
60 | "request": {
61 | "url": "http://dedao.dev.igetget.com/v3/igettv/structuredata?sign=4056bd5301cff045d4c0c2d8856322ea",
62 | "method": "POST",
63 | "headers": {
64 | "Cache-Control": "no-cache",
65 | "Content-Type": "application/json; charset=UTF-8",
66 | "Content-Length": "327",
67 | "Host": "dedao.dev.igetget.com",
68 | "Connection": "Keep-Alive",
69 | "Accept-Encoding": "gzip",
70 | "User-Agent": "okhttp/3.11.0"
71 | },
72 | "json": {
73 | "struct_id": 25490,
74 | "h": {
75 | "u": "84846274",
76 | "thumb": "l",
77 | "dt": "phone",
78 | "ov": "6.0",
79 | "net": "WIFI",
80 | "os": "ANDROID",
81 | "d": "ae244834553d4eda",
82 | "dv": "Samsung Galaxy S6",
83 | "t": "json",
84 | "chil": "0",
85 | "v": "2",
86 | "av": "6.2.0",
87 | "scr": "2.0",
88 | "adv": "1",
89 | "X-Dv": "Samsung Galaxy S6",
90 | "ts": "1558452493",
91 | "s": "db578eef9d289db9",
92 | "seid": "1fdab2a5fa99e1edda214151eefc27d2"
93 | }
94 | }
95 | },
96 | "validate": [
97 | {
98 | "eq": [
99 | "status_code",
100 | 200
101 | ]
102 | }
103 | ]
104 | }
105 | },
106 | {
107 | "test": {
108 | "name": "casname",
109 | "request": {
110 | "url": "http://dedao.dev.igetget.com/v3/igettv/structuredata?sign=4056bd5301cff045d4c0c2d8856322ea",
111 | "method": "POST",
112 | "headers": {
113 | "Cache-Control": "no-cache",
114 | "Content-Type": "application/json; charset=UTF-8",
115 | "Content-Length": "327",
116 | "Host": "dedao.dev.igetget.com",
117 | "Connection": "Keep-Alive",
118 | "Accept-Encoding": "gzip",
119 | "User-Agent": "okhttp/3.11.0"
120 | },
121 | "json": {
122 | "struct_id": 25490,
123 | "h": {
124 | "u": "84846274",
125 | "thumb": "l",
126 | "dt": "phone",
127 | "ov": "6.0",
128 | "net": "WIFI",
129 | "os": "ANDROID",
130 | "d": "ae244834553d4eda",
131 | "dv": "Samsung Galaxy S6",
132 | "t": "json",
133 | "chil": "0",
134 | "v": "2",
135 | "av": "6.2.0",
136 | "scr": "2.0",
137 | "adv": "1",
138 | "X-Dv": "Samsung Galaxy S6",
139 | "ts": "1558452493",
140 | "s": "db578eef9d289db9",
141 | "seid": "1fdab2a5fa99e1edda214151eefc27d2"
142 | }
143 | }
144 | },
145 | "validate": [
146 | {
147 | "eq": [
148 | "status_code",
149 | 200
150 | ]
151 | }
152 | ]
153 | }
154 | },
155 | {
156 | "test": {
157 | "name": "casname",
158 | "request": {
159 | "url": "http://dedao.dev.igetget.com/v3/igettv/structuredata?sign=4056bd5301cff045d4c0c2d8856322ea",
160 | "method": "POST",
161 | "headers": {
162 | "Cache-Control": "no-cache",
163 | "Content-Type": "application/json; charset=UTF-8",
164 | "Content-Length": "327",
165 | "Host": "dedao.dev.igetget.com",
166 | "Connection": "Keep-Alive",
167 | "Accept-Encoding": "gzip",
168 | "User-Agent": "okhttp/3.11.0"
169 | },
170 | "json": {
171 | "struct_id": 25490,
172 | "h": {
173 | "u": "84846274",
174 | "thumb": "l",
175 | "dt": "phone",
176 | "ov": "6.0",
177 | "net": "WIFI",
178 | "os": "ANDROID",
179 | "d": "ae244834553d4eda",
180 | "dv": "Samsung Galaxy S6",
181 | "t": "json",
182 | "chil": "0",
183 | "v": "2",
184 | "av": "6.2.0",
185 | "scr": "2.0",
186 | "adv": "1",
187 | "X-Dv": "Samsung Galaxy S6",
188 | "ts": "1558452493",
189 | "s": "db578eef9d289db9",
190 | "seid": "1fdab2a5fa99e1edda214151eefc27d2"
191 | }
192 | }
193 | },
194 | "validate": [
195 | {
196 | "eq": [
197 | "status_code",
198 | 200
199 | ]
200 | }
201 | ]
202 | }
203 | },
204 | {
205 | "test": {
206 | "name": "casname",
207 | "request": {
208 | "url": "http://dedao.dev.igetget.com/v3/igettv/structuredata?sign=4056bd5301cff045d4c0c2d8856322ea",
209 | "method": "POST",
210 | "headers": {
211 | "Cache-Control": "no-cache",
212 | "Content-Type": "application/json; charset=UTF-8",
213 | "Content-Length": "327",
214 | "Host": "dedao.dev.igetget.com",
215 | "Connection": "Keep-Alive",
216 | "Accept-Encoding": "gzip",
217 | "User-Agent": "okhttp/3.11.0"
218 | },
219 | "json": {
220 | "struct_id": 25490,
221 | "h": {
222 | "u": "84846274",
223 | "thumb": "l",
224 | "dt": "phone",
225 | "ov": "6.0",
226 | "net": "WIFI",
227 | "os": "ANDROID",
228 | "d": "ae244834553d4eda",
229 | "dv": "Samsung Galaxy S6",
230 | "t": "json",
231 | "chil": "0",
232 | "v": "2",
233 | "av": "6.2.0",
234 | "scr": "2.0",
235 | "adv": "1",
236 | "X-Dv": "Samsung Galaxy S6",
237 | "ts": "1558452493",
238 | "s": "db578eef9d289db9",
239 | "seid": "1fdab2a5fa99e1edda214151eefc27d2"
240 | }
241 | }
242 | },
243 | "validate": [
244 | {
245 | "eq": [
246 | "status_code",
247 | 200
248 | ]
249 | }
250 | ]
251 | }
252 | },
253 | {
254 | "test": {
255 | "name": "casname",
256 | "request": {
257 | "url": "http://dedao.dev.igetget.com/v3/igettv/structuredata?sign=4056bd5301cff045d4c0c2d8856322ea",
258 | "method": "POST",
259 | "headers": {
260 | "Cache-Control": "no-cache",
261 | "Content-Type": "application/json; charset=UTF-8",
262 | "Content-Length": "327",
263 | "Host": "dedao.dev.igetget.com",
264 | "Connection": "Keep-Alive",
265 | "Accept-Encoding": "gzip",
266 | "User-Agent": "okhttp/3.11.0"
267 | },
268 | "json": {
269 | "struct_id": 25490,
270 | "h": {
271 | "u": "84846274",
272 | "thumb": "l",
273 | "dt": "phone",
274 | "ov": "6.0",
275 | "net": "WIFI",
276 | "os": "ANDROID",
277 | "d": "ae244834553d4eda",
278 | "dv": "Samsung Galaxy S6",
279 | "t": "json",
280 | "chil": "0",
281 | "v": "2",
282 | "av": "6.2.0",
283 | "scr": "2.0",
284 | "adv": "1",
285 | "X-Dv": "Samsung Galaxy S6",
286 | "ts": "1558452493",
287 | "s": "db578eef9d289db9",
288 | "seid": "1fdab2a5fa99e1edda214151eefc27d2"
289 | }
290 | }
291 | },
292 | "validate": [
293 | {
294 | "eq": [
295 | "status_code",
296 | 200
297 | ]
298 | }
299 | ]
300 | }
301 | },
302 | {
303 | "test": {
304 | "name": "casname",
305 | "request": {
306 | "url": "http://dedao.dev.igetget.com/v3/igettv/structuredata?sign=4056bd5301cff045d4c0c2d8856322ea",
307 | "method": "POST",
308 | "headers": {
309 | "Cache-Control": "no-cache",
310 | "Content-Type": "application/json; charset=UTF-8",
311 | "Content-Length": "327",
312 | "Host": "dedao.dev.igetget.com",
313 | "Connection": "Keep-Alive",
314 | "Accept-Encoding": "gzip",
315 | "User-Agent": "okhttp/3.11.0"
316 | },
317 | "json": {
318 | "struct_id": 25490,
319 | "h": {
320 | "u": "84846274",
321 | "thumb": "l",
322 | "dt": "phone",
323 | "ov": "6.0",
324 | "net": "WIFI",
325 | "os": "ANDROID",
326 | "d": "ae244834553d4eda",
327 | "dv": "Samsung Galaxy S6",
328 | "t": "json",
329 | "chil": "0",
330 | "v": "2",
331 | "av": "6.2.0",
332 | "scr": "2.0",
333 | "adv": "1",
334 | "X-Dv": "Samsung Galaxy S6",
335 | "ts": "1558452493",
336 | "s": "db578eef9d289db9",
337 | "seid": "1fdab2a5fa99e1edda214151eefc27d2"
338 | }
339 | }
340 | },
341 | "validate": [
342 | {
343 | "eq": [
344 | "status_code",
345 | 200
346 | ]
347 | }
348 | ]
349 | }
350 | },
351 | {
352 | "test": {
353 | "name": "casname",
354 | "request": {
355 | "url": "http://dedao.dev.igetget.com/v3/igettv/structuredata?sign=4056bd5301cff045d4c0c2d8856322ea",
356 | "method": "POST",
357 | "headers": {
358 | "Cache-Control": "no-cache",
359 | "Content-Type": "application/json; charset=UTF-8",
360 | "Content-Length": "327",
361 | "Host": "dedao.dev.igetget.com",
362 | "Connection": "Keep-Alive",
363 | "Accept-Encoding": "gzip",
364 | "User-Agent": "okhttp/3.11.0"
365 | },
366 | "json": {
367 | "struct_id": 25490,
368 | "h": {
369 | "u": "84846274",
370 | "thumb": "l",
371 | "dt": "phone",
372 | "ov": "6.0",
373 | "net": "WIFI",
374 | "os": "ANDROID",
375 | "d": "ae244834553d4eda",
376 | "dv": "Samsung Galaxy S6",
377 | "t": "json",
378 | "chil": "0",
379 | "v": "2",
380 | "av": "6.2.0",
381 | "scr": "2.0",
382 | "adv": "1",
383 | "X-Dv": "Samsung Galaxy S6",
384 | "ts": "1558452493",
385 | "s": "db578eef9d289db9",
386 | "seid": "1fdab2a5fa99e1edda214151eefc27d2"
387 | }
388 | }
389 | },
390 | "validate": [
391 | {
392 | "eq": [
393 | "status_code",
394 | 200
395 | ]
396 | }
397 | ]
398 | }
399 | },
400 | {
401 | "test": {
402 | "name": "casname",
403 | "request": {
404 | "url": "http://dedao.dev.igetget.com/v3/igettv/structuredata?sign=4056bd5301cff045d4c0c2d8856322ea",
405 | "method": "POST",
406 | "headers": {
407 | "Cache-Control": "no-cache",
408 | "Content-Type": "application/json; charset=UTF-8",
409 | "Content-Length": "327",
410 | "Host": "dedao.dev.igetget.com",
411 | "Connection": "Keep-Alive",
412 | "Accept-Encoding": "gzip",
413 | "User-Agent": "okhttp/3.11.0"
414 | },
415 | "json": {
416 | "struct_id": 25490,
417 | "h": {
418 | "u": "84846274",
419 | "thumb": "l",
420 | "dt": "phone",
421 | "ov": "6.0",
422 | "net": "WIFI",
423 | "os": "ANDROID",
424 | "d": "ae244834553d4eda",
425 | "dv": "Samsung Galaxy S6",
426 | "t": "json",
427 | "chil": "0",
428 | "v": "2",
429 | "av": "6.2.0",
430 | "scr": "2.0",
431 | "adv": "1",
432 | "X-Dv": "Samsung Galaxy S6",
433 | "ts": "1558452493",
434 | "s": "db578eef9d289db9",
435 | "seid": "1fdab2a5fa99e1edda214151eefc27d2"
436 | }
437 | }
438 | },
439 | "validate": [
440 | {
441 | "eq": [
442 | "status_code",
443 | 200
444 | ]
445 | }
446 | ]
447 | }
448 | },
449 | {
450 | "test": {
451 | "name": "casname",
452 | "request": {
453 | "url": "http://dedao.dev.igetget.com/v3/igettv/structuredata?sign=4056bd5301cff045d4c0c2d8856322ea",
454 | "method": "POST",
455 | "headers": {
456 | "Cache-Control": "no-cache",
457 | "Content-Type": "application/json; charset=UTF-8",
458 | "Content-Length": "327",
459 | "Host": "dedao.dev.igetget.com",
460 | "Connection": "Keep-Alive",
461 | "Accept-Encoding": "gzip",
462 | "User-Agent": "okhttp/3.11.0"
463 | },
464 | "json": {
465 | "struct_id": 25490,
466 | "h": {
467 | "u": "84846274",
468 | "thumb": "l",
469 | "dt": "phone",
470 | "ov": "6.0",
471 | "net": "WIFI",
472 | "os": "ANDROID",
473 | "d": "ae244834553d4eda",
474 | "dv": "Samsung Galaxy S6",
475 | "t": "json",
476 | "chil": "0",
477 | "v": "2",
478 | "av": "6.2.0",
479 | "scr": "2.0",
480 | "adv": "1",
481 | "X-Dv": "Samsung Galaxy S6",
482 | "ts": "1558452493",
483 | "s": "db578eef9d289db9",
484 | "seid": "1fdab2a5fa99e1edda214151eefc27d2"
485 | }
486 | }
487 | },
488 | "validate": [
489 | {
490 | "eq": [
491 | "status_code",
492 | 200
493 | ]
494 | }
495 | ]
496 | }
497 | }
498 | ]
--------------------------------------------------------------------------------
/dumphrun/proxyserver.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 |
5 | """
6 | 使用mitmproxy录制测试用例
7 | """
8 |
9 | import mitmproxy.http
10 | from mitmproxy import ctx
11 | import json,time,os
12 | from filetools import *
13 |
14 |
15 | project_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
16 | now = time.strftime("%Y%m%d%H%M%S", time.localtime()) + "_intercept.log"
17 | save_log_file = os.path.join(project_path, now)
18 |
19 | def request(flow: mitmproxy.http.HTTPFlow):
20 | request = flow.request
21 | ctx.log.info("========================== intercept request start ==========================")
22 | ctx.log.info("========================== intercept request start ==========================")
23 | ctx.log.info("========================== host is:{} ========================== ".format(request.host))
24 | ctx.log.info("========================== url is:{} ========================== ".format(request.pretty_url))
25 | ctx.log.info("========================== method is:{} ========================== ".format(request.method))
26 | ctx.log.info("========================== body is:{} ========================== ".format(request.get_text()))
27 | ctx.log.info("========================== intercept request end ==========================")
28 |
29 |
30 | def response(flow: mitmproxy.http.HTTPFlow):
31 | '''
32 | 篡改response返回数据
33 | :param flow:
34 | :return:
35 | '''
36 | is_mock = True
37 |
38 | black_list = ["png", "jpg", "js", "css", "html",'img','cdn']
39 |
40 | for balck_str in black_list:
41 | if balck_str in flow.request.url:
42 | ctx.log.info("========================== not intercept response ==========================")
43 | is_mock = False
44 | break
45 |
46 | if int(flow.response.status_code) == 200 and is_mock == True:
47 | original_data = (flow.response.text)
48 | if original_data.startswith("{") and original_data.endswith("}"):
49 | ctx.log.info("========================== intercept response end ==========================")
50 | spend_time = int((flow.response.timestamp_end - flow.request.timestamp_start) * 1000)
51 | key_list = []
52 | values_list = []
53 | for key, values in flow.request.headers.items():
54 | key_list.append(key)
55 | values_list.append(values)
56 | headers = dict(zip(key_list, values_list))
57 | key_list = []
58 | values_list = []
59 | for key, values in eval(flow.request.data.content).items():
60 | key_list.append(key)
61 | values_list.append(values)
62 | data = dict(zip(key_list, values_list))
63 | content = str(flow.request.url) + '|' + str(flow.request.method) + '|' + str(headers) + '|' \
64 | + str(data)
65 | write_file(save_log_file,content,is_cover=False)
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/dumphrun/reports/1558442162.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - TestReport
5 |
149 |
150 |
151 |
152 | Test Report:
153 |
154 | Summary
155 |
156 |
157 | START AT |
158 | 2019-05-21 20:36:02 |
159 |
160 |
161 | DURATION |
162 | 0.111 seconds |
163 |
164 |
165 | PLATFORM |
166 | HttpRunner 2.0.6 |
167 | CPython 2.7.15 |
168 | Darwin-17.7.0-x86_64-i386-64bit |
169 |
170 |
171 | STAT |
172 | TESTCASES (success/fail) |
173 | TESTSTEPS (success/fail/error/skip) |
174 |
175 |
176 | total (details) => |
177 | 1 (0/1) |
178 | 1 (0/1/0/0) |
179 |
180 |
181 |
182 | Details
183 |
184 |
185 |
186 | testcase description
187 |
188 |
189 | TOTAL: 1 |
190 | SUCCESS: 0 |
191 | FAILED: 1 |
192 | ERROR: 0 |
193 | SKIPPED: 0 |
194 |
195 |
196 | Status |
197 | Name |
198 | Response Time |
199 | Detail |
200 |
201 |
202 |
203 |
204 |
205 |
206 | failure |
207 | casname |
208 | 28.43 ms |
209 |
210 |
211 |
212 |
213 | log-1
214 |
471 |
472 |
473 |
474 | traceback
475 |
487 |
488 |
489 | |
490 |
491 |
492 |
493 |
494 |
--------------------------------------------------------------------------------
/dumphrun/reports/1558442233.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - TestReport
5 |
149 |
150 |
151 |
152 | Test Report:
153 |
154 | Summary
155 |
156 |
157 | START AT |
158 | 2019-05-21 20:37:13 |
159 |
160 |
161 | DURATION |
162 | 0.089 seconds |
163 |
164 |
165 | PLATFORM |
166 | HttpRunner 2.0.6 |
167 | CPython 2.7.15 |
168 | Darwin-17.7.0-x86_64-i386-64bit |
169 |
170 |
171 | STAT |
172 | TESTCASES (success/fail) |
173 | TESTSTEPS (success/fail/error/skip) |
174 |
175 |
176 | total (details) => |
177 | 1 (1/0) |
178 | 1 (1/0/0/0) |
179 |
180 |
181 |
182 | Details
183 |
184 |
185 |
186 | testcase description
187 |
188 |
189 | TOTAL: 1 |
190 | SUCCESS: 1 |
191 | FAILED: 0 |
192 | ERROR: 0 |
193 | SKIPPED: 0 |
194 |
195 |
196 | Status |
197 | Name |
198 | Response Time |
199 | Detail |
200 |
201 |
202 |
203 |
204 |
205 |
206 | success |
207 | casname |
208 | 32.60 ms |
209 |
210 |
211 |
212 |
213 | log-1
214 |
467 |
468 |
469 |
470 |
471 | |
472 |
473 |
474 |
475 |
476 |
--------------------------------------------------------------------------------
/dumphrun/reports/1558448260.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - TestReport
5 |
149 |
150 |
151 |
152 | Test Report:
153 |
154 | Summary
155 |
156 |
157 | START AT |
158 | 2019-05-21 22:17:40 |
159 |
160 |
161 | DURATION |
162 | 0.343 seconds |
163 |
164 |
165 | PLATFORM |
166 | HttpRunner 2.0.6 |
167 | CPython 2.7.15 |
168 | Darwin-17.7.0-x86_64-i386-64bit |
169 |
170 |
171 | STAT |
172 | TESTCASES (success/fail) |
173 | TESTSTEPS (success/fail/error/skip) |
174 |
175 |
176 | total (details) => |
177 | 1 (1/0) |
178 | 1 (1/0/0/0) |
179 |
180 |
181 |
182 | Details
183 |
184 |
185 |
186 | testcase description
187 |
188 |
189 | TOTAL: 1 |
190 | SUCCESS: 1 |
191 | FAILED: 0 |
192 | ERROR: 0 |
193 | SKIPPED: 0 |
194 |
195 |
196 | Status |
197 | Name |
198 | Response Time |
199 | Detail |
200 |
201 |
202 |
203 |
204 |
205 |
206 | success |
207 | casname |
208 | 280.73 ms |
209 |
210 |
211 |
212 |
213 | log-1
214 |
526 |
527 |
528 |
529 |
530 | |
531 |
532 |
533 |
534 |
535 |
--------------------------------------------------------------------------------
/dumphrun/reports/1558448626.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - TestReport
5 |
149 |
150 |
151 |
152 | Test Report:
153 |
154 | Summary
155 |
156 |
157 | START AT |
158 | 2019-05-21 22:23:46 |
159 |
160 |
161 | DURATION |
162 | 0.144 seconds |
163 |
164 |
165 | PLATFORM |
166 | HttpRunner 2.0.6 |
167 | CPython 2.7.15 |
168 | Darwin-17.7.0-x86_64-i386-64bit |
169 |
170 |
171 | STAT |
172 | TESTCASES (success/fail) |
173 | TESTSTEPS (success/fail/error/skip) |
174 |
175 |
176 | total (details) => |
177 | 1 (1/0) |
178 | 1 (1/0/0/0) |
179 |
180 |
181 |
182 | Details
183 |
184 |
185 |
186 | testcase description
187 |
188 |
189 | TOTAL: 1 |
190 | SUCCESS: 1 |
191 | FAILED: 0 |
192 | ERROR: 0 |
193 | SKIPPED: 0 |
194 |
195 |
196 | Status |
197 | Name |
198 | Response Time |
199 | Detail |
200 |
201 |
202 |
203 |
204 |
205 |
206 | success |
207 | casname |
208 | 84.05 ms |
209 |
210 |
211 |
212 |
213 | log-1
214 |
526 |
527 |
528 |
529 |
530 | |
531 |
532 |
533 |
534 |
535 |
--------------------------------------------------------------------------------
/dumphrun/test.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import json
4 |
5 | headers = {}
6 | headers["User-Agent"] = "111"
7 |
8 | print(str(headers))
9 | print(json.dumps(headers))
10 | print(type())
--------------------------------------------------------------------------------
/mitm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xinxi1990/mitmfuzz/807f105788620b5322e1c59db3c46b816a59c24a/mitm.png
--------------------------------------------------------------------------------
/proxy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xinxi1990/mitmfuzz/807f105788620b5322e1c59db3c46b816a59c24a/proxy.png
--------------------------------------------------------------------------------
/proxy/20190521225436_intercept.log:
--------------------------------------------------------------------------------
1 | http://entree.dev.igetget.com/odob/v2/agency/list|POST|200|103|{"h":{"c":0,"e":"","s":1558450481,"t":42},"c":{"list":[{"id":16,"name":"韩焱","intro":"韩焱,资深出版人,著名图书出版品牌“湛庐文化”创始人、董事长,在得到App“每天听本书”栏目解读了众多湛庐文化出版的优质图书。\r\n\r\n湛庐文化自2005年创办至今,出版图书上千种,涵盖科技趋势、金融投资、经济管理、心理学等众多领域,如《影响力》《牛奶可乐经济学》《大数据时代》《千面英雄》等。\r\n\r\n2017年,湛庐文化基于上千种图书和2000万读者的积累,创办了自有知识服务平台“湛庐阅读”。\r\n\r\n“让我们与最聪明的人共同进化。”","qcg_id":243,"qcg_member_name":"韩焱","qcg_member_avatar":"http://piccdn.igetget.com/img/201804/17/201804171909028650884783.jpg","book_count":26,"uv":0,"status":1,"share_title":"听书解读人:韩焱","share_summary":"韩焱,资深出版人,著名图书出版品牌“湛庐文化”创始人、董事长,在得到App“每天听本书”栏目解读了众多湛庐文化出版的优质图书。\r\n\r\n湛庐文化自2005年创办至今,出版图书上千种,涵盖科技趋势、金融投资、经济管理、心理学等众多领域,如《影响力》《牛奶可乐经济学》《大数据时代》《千面英雄》等。\r\n\r\n2017年,湛庐文化基于上千种图书和2000万读者的积累,创办了自有知识服务平台“湛庐阅读”。\r\n\r\n“让我们与最聪明的人共同进化。”","share_img":"http://piccdn.igetget.com/img/201804/17/201804171909028650884783.jpg","share_url":"http://m.dev.igetget.com/share/agency/id/16","created_at":1521719737,"updated_at":1556264585,"rank_pos":1,"log_id":"16","log_type":"agency"},{"id":15,"name":"张凯","intro":"张凯,自由撰稿人,得到App精品课《怎样成为快速阅读的高手》主讲人,少年得到App《十倍速阅读法》主讲人,得到App“每天听本书”栏目资深撰稿人。\r\n\r\n解读代表作有《光荣与梦想》《伯罗奔尼撒战争》《魔鬼经济学》《文明之光》《超预测》等,涉及管理学、心理学、经济学、社会学等多个领域。\r\n\r\n擅长用简洁的语言,讲述陌生领域的新知识。","qcg_id":142,"qcg_member_name":"张凯","qcg_member_avatar":"http://piccdn.igetget.com/img/201803/22/201803221923519969331605.jpg","book_count":61,"uv":0,"status":1,"share_title":"听书解读人:张凯","share_summary":"张凯,自由撰稿人,得到App精品课《怎样成为快速阅读的高手》主讲人,少年得到App《十倍速阅读法》主讲人,得到App“每天听本书”栏目资深撰稿人。\r\n\r\n解读代表作有《光荣与梦想》《伯罗奔尼撒战争》《魔鬼经济学》《文明之光》《超预测》等,涉及管理学、心理学、经济学、社会学等多个领域。\r\n\r\n擅长用简洁的语言,讲述陌生领域的新知识。","share_img":"http://piccdn.igetget.com/img/201803/22/201803221923519969331605.jpg","share_url":"http://m.dev.igetget.com/share/agency/id/15","created_at":1521718025,"updated_at":1548301144,"rank_pos":2,"log_id":"15","log_type":"agency"},{"id":7,"name":"刘玮","intro":"刘玮,中国人民大学哲学院副教授。他是北京大学哲学学士,清华大学哲学硕士,香港中文大学哲学博士,美国加州大学伯克利分校、德国慕尼黑大学访问学者。\r\n\r\n主要研究古希腊哲学、西方哲学史。\r\n\r\n他是得到App“每天听本书”栏目西方哲学经典系列解读人。这个系列希望带你领略哲学家探索人类知识边界的一次次伟大努力,用平实的语言展示伟大哲学著作的深刻与魅力。","qcg_id":77,"qcg_member_name":"刘玮","qcg_member_avatar":"http://piccdn.igetget.com/img/201708/25/201708251126368588659193.jpg","book_count":13,"uv":0,"status":1,"share_title":"听书解读人:刘玮","share_summary":"刘玮,中国人民大学哲学院副教授。他是北京大学哲学学士,清华大学哲学硕士,香港中文大学哲学博士,美国加州大学伯克利分校、德国慕尼黑大学访问学者。\r\n\r\n主要研究古希腊哲学、西方哲学史。\r\n\r\n他是得到App“每天听本书”栏目西方哲学经典系列解读人。这个系列希望带你领略哲学家探索人类知识边界的一次次伟大努力,用平实的语言展示伟大哲学著作的深刻与魅力。","share_img":"http://piccdn.igetget.com/img/201708/25/201708251126368588659193.jpg","share_url":"http://m.dev.igetget.com/share/agency/id/7","created_at":1521524985,"updated_at":1548301243,"rank_pos":3,"log_id":"7","log_type":"agency"},{"id":12,"name":"柴知道","intro":"专注于知识传播的自媒体团队。2016年开始制作知识短视频和读书节目,目前全网视频播放量超过5亿次,全平台粉丝数超过1000万。\r\n\r\n擅长解读科普经典著作、知识型书籍。","qcg_id":296,"qcg_member_name":"柴知道","qcg_member_avatar":"http://piccdn.igetget.com/img/201803/20/201803201106400361846914.jpg","book_count":17,"uv":0,"status":1,"share_title":"听书解读人:柴知道","share_summary":"专注于知识传播的自媒体团队。2016年开始制作知识短视频和读书节目,目前全网视频播放量超过5亿次,全平台粉丝数超过1000万。\r\n\r\n擅长解读科普经典著作、知识型书籍。","share_img":"http://piccdn.igetget.com/img/201803/20/201803201106400361846914.jpg","share_url":"http://m.dev.igetget.com/share/agency/id/12","created_at":1521529920,"updated_at":1550746618,"rank_pos":4,"log_id":"12","log_type":"agency"}]}}|{"h": {"c": 0, "e": "", "s": 1558450481, "t": 42}, "c": {"list": [{"id": 16, "name": "\u97e9\u7131", "intro": "\u97e9\u7131\uff0c\u8d44\u6df1\u51fa\u7248\u4eba\uff0c\u8457\u540d\u56fe\u4e66\u51fa\u7248\u54c1\u724c\u201c\u6e5b\u5e90\u6587\u5316\u201d\u521b\u59cb\u4eba\u3001\u8463\u4e8b\u957f\uff0c\u5728\u5f97\u5230App\u201c\u6bcf\u5929\u542c\u672c\u4e66\u201d\u680f\u76ee\u89e3\u8bfb\u4e86\u4f17\u591a\u6e5b\u5e90\u6587\u5316\u51fa\u7248\u7684\u4f18\u8d28\u56fe\u4e66\u3002\r\n\r\n\u6e5b\u5e90\u6587\u5316\u81ea2005\u5e74\u521b\u529e\u81f3\u4eca\uff0c\u51fa\u7248\u56fe\u4e66\u4e0a\u5343\u79cd\uff0c\u6db5\u76d6\u79d1\u6280\u8d8b\u52bf\u3001\u91d1\u878d\u6295\u8d44\u3001\u7ecf\u6d4e\u7ba1\u7406\u3001\u5fc3\u7406\u5b66\u7b49\u4f17\u591a\u9886\u57df\uff0c\u5982\u300a\u5f71\u54cd\u529b\u300b\u300a\u725b\u5976\u53ef\u4e50\u7ecf\u6d4e\u5b66\u300b\u300a\u5927\u6570\u636e\u65f6\u4ee3\u300b\u300a\u5343\u9762\u82f1\u96c4\u300b\u7b49\u3002\r\n\r\n2017\u5e74\uff0c\u6e5b\u5e90\u6587\u5316\u57fa\u4e8e\u4e0a\u5343\u79cd\u56fe\u4e66\u548c2000\u4e07\u8bfb\u8005\u7684\u79ef\u7d2f\uff0c\u521b\u529e\u4e86\u81ea\u6709\u77e5\u8bc6\u670d\u52a1\u5e73\u53f0\u201c\u6e5b\u5e90\u9605\u8bfb\u201d\u3002\r\n\r\n\u201c\u8ba9\u6211\u4eec\u4e0e\u6700\u806a\u660e\u7684\u4eba\u5171\u540c\u8fdb\u5316\u3002\u201d", "qcg_id": 243, "qcg_member_name": "\u97e9\u7131", "qcg_member_avatar": "http://piccdn.igetget.com/img/201804/17/201804171909028650884783.jpg", "book_count": 26, "uv": 0, "status": 1, "share_title": "\u542c\u4e66\u89e3\u8bfb\u4eba:\u97e9\u7131", "share_summary": "\u97e9\u7131\uff0c\u8d44\u6df1\u51fa\u7248\u4eba\uff0c\u8457\u540d\u56fe\u4e66\u51fa\u7248\u54c1\u724c\u201c\u6e5b\u5e90\u6587\u5316\u201d\u521b\u59cb\u4eba\u3001\u8463\u4e8b\u957f\uff0c\u5728\u5f97\u5230App\u201c\u6bcf\u5929\u542c\u672c\u4e66\u201d\u680f\u76ee\u89e3\u8bfb\u4e86\u4f17\u591a\u6e5b\u5e90\u6587\u5316\u51fa\u7248\u7684\u4f18\u8d28\u56fe\u4e66\u3002\r\n\r\n\u6e5b\u5e90\u6587\u5316\u81ea2005\u5e74\u521b\u529e\u81f3\u4eca\uff0c\u51fa\u7248\u56fe\u4e66\u4e0a\u5343\u79cd\uff0c\u6db5\u76d6\u79d1\u6280\u8d8b\u52bf\u3001\u91d1\u878d\u6295\u8d44\u3001\u7ecf\u6d4e\u7ba1\u7406\u3001\u5fc3\u7406\u5b66\u7b49\u4f17\u591a\u9886\u57df\uff0c\u5982\u300a\u5f71\u54cd\u529b\u300b\u300a\u725b\u5976\u53ef\u4e50\u7ecf\u6d4e\u5b66\u300b\u300a\u5927\u6570\u636e\u65f6\u4ee3\u300b\u300a\u5343\u9762\u82f1\u96c4\u300b\u7b49\u3002\r\n\r\n2017\u5e74\uff0c\u6e5b\u5e90\u6587\u5316\u57fa\u4e8e\u4e0a\u5343\u79cd\u56fe\u4e66\u548c2000\u4e07\u8bfb\u8005\u7684\u79ef\u7d2f\uff0c\u521b\u529e\u4e86\u81ea\u6709\u77e5\u8bc6\u670d\u52a1\u5e73\u53f0\u201c\u6e5b\u5e90\u9605\u8bfb\u201d\u3002\r\n\r\n\u201c\u8ba9\u6211\u4eec\u4e0e\u6700\u806a\u660e\u7684\u4eba\u5171\u540c\u8fdb\u5316\u3002\u201d", "share_img": "http://piccdn.igetget.com/img/201804/17/201804171909028650884783.jpg", "share_url": "http://m.dev.igetget.com/share/agency/id/16", "created_at": 1521719737, "updated_at": 1556264585, "rank_pos": 1, "log_id": "16", "log_type": "agency"}, {"id": 15, "intro": "\u5f20\u51ef\uff0c\u81ea\u7531\u64b0\u7a3f\u4eba\uff0c\u5f97\u5230App\u7cbe\u54c1\u8bfe\u300a\u600e\u6837\u6210\u4e3a\u5feb\u901f\u9605\u8bfb\u7684\u9ad8\u624b\u300b\u4e3b\u8bb2\u4eba\uff0c\u5c11\u5e74\u5f97\u5230App\u300a\u5341\u500d\u901f\u9605\u8bfb\u6cd5\u300b\u4e3b\u8bb2\u4eba\uff0c\u5f97\u5230App\u201c\u6bcf\u5929\u542c\u672c\u4e66\u201d\u680f\u76ee\u8d44\u6df1\u64b0\u7a3f\u4eba\u3002\r\n\r\n\u89e3\u8bfb\u4ee3\u8868\u4f5c\u6709\u300a\u5149\u8363\u4e0e\u68a6\u60f3\u300b\u300a\u4f2f\u7f57\u5954\u5c3c\u6492\u6218\u4e89\u300b\u300a\u9b54\u9b3c\u7ecf\u6d4e\u5b66\u300b\u300a\u6587\u660e\u4e4b\u5149\u300b\u300a\u8d85\u9884\u6d4b\u300b\u7b49\uff0c\u6d89\u53ca\u7ba1\u7406\u5b66\u3001\u5fc3\u7406\u5b66\u3001\u7ecf\u6d4e\u5b66\u3001\u793e\u4f1a\u5b66\u7b49\u591a\u4e2a\u9886\u57df\u3002\r\n\r\n\u64c5\u957f\u7528\u7b80\u6d01\u7684\u8bed\u8a00\uff0c\u8bb2\u8ff0\u964c\u751f\u9886\u57df\u7684\u65b0\u77e5\u8bc6\u3002", "qcg_id": 142, "qcg_member_name": "\u5f20\u51ef", "qcg_member_avatar": "http://piccdn.igetget.com/img/201803/22/201803221923519969331605.jpg", "book_count": 61, "uv": 0, "status": 1, "share_title": "XN~qvHc6Kr", "share_summary": "\u5f20\u51ef\uff0c\u81ea\u7531\u64b0\u7a3f\u4eba\uff0c\u5f97\u5230App\u7cbe\u54c1\u8bfe\u300a\u600e\u6837\u6210\u4e3a\u5feb\u901f\u9605\u8bfb\u7684\u9ad8\u624b\u300b\u4e3b\u8bb2\u4eba\uff0c\u5c11\u5e74\u5f97\u5230App\u300a\u5341\u500d\u901f\u9605\u8bfb\u6cd5\u300b\u4e3b\u8bb2\u4eba\uff0c\u5f97\u5230App\u201c\u6bcf\u5929\u542c\u672c\u4e66\u201d\u680f\u76ee\u8d44\u6df1\u64b0\u7a3f\u4eba\u3002\r\n\r\n\u89e3\u8bfb\u4ee3\u8868\u4f5c\u6709\u300a\u5149\u8363\u4e0e\u68a6\u60f3\u300b\u300a\u4f2f\u7f57\u5954\u5c3c\u6492\u6218\u4e89\u300b\u300a\u9b54\u9b3c\u7ecf\u6d4e\u5b66\u300b\u300a\u6587\u660e\u4e4b\u5149\u300b\u300a\u8d85\u9884\u6d4b\u300b\u7b49\uff0c\u6d89\u53ca\u7ba1\u7406\u5b66\u3001\u5fc3\u7406\u5b66\u3001\u7ecf\u6d4e\u5b66\u3001\u793e\u4f1a\u5b66\u7b49\u591a\u4e2a\u9886\u57df\u3002\r\n\r\n\u64c5\u957f\u7528\u7b80\u6d01\u7684\u8bed\u8a00\uff0c\u8bb2\u8ff0\u964c\u751f\u9886\u57df\u7684\u65b0\u77e5\u8bc6\u3002", "share_img": "http://piccdn.igetget.com/img/201803/22/201803221923519969331605.jpg", "share_url": "http://m.dev.igetget.com/share/agency/id/15", "created_at": 1521718025, "updated_at": 1548301144, "rank_pos": 2, "log_id": "15", "log_type": "agency"}, {"id": 7, "name": "\u5218\u73ae", "intro": "\u5218\u73ae\uff0c\u4e2d\u56fd\u4eba\u6c11\u5927\u5b66\u54f2\u5b66\u9662\u526f\u6559\u6388\u3002\u4ed6\u662f\u5317\u4eac\u5927\u5b66\u54f2\u5b66\u5b66\u58eb\uff0c\u6e05\u534e\u5927\u5b66\u54f2\u5b66\u7855\u58eb\uff0c\u9999\u6e2f\u4e2d\u6587\u5927\u5b66\u54f2\u5b66\u535a\u58eb\uff0c\u7f8e\u56fd\u52a0\u5dde\u5927\u5b66\u4f2f\u514b\u5229\u5206\u6821\u3001\u5fb7\u56fd\u6155\u5c3c\u9ed1\u5927\u5b66\u8bbf\u95ee\u5b66\u8005\u3002\r\n\r\n\u4e3b\u8981\u7814\u7a76\u53e4\u5e0c\u814a\u54f2\u5b66\u3001\u897f\u65b9\u54f2\u5b66\u53f2\u3002\r\n\r\n\u4ed6\u662f\u5f97\u5230App\u201c\u6bcf\u5929\u542c\u672c\u4e66\u201d\u680f\u76ee\u897f\u65b9\u54f2\u5b66\u7ecf\u5178\u7cfb\u5217\u89e3\u8bfb\u4eba\u3002\u8fd9\u4e2a\u7cfb\u5217\u5e0c\u671b\u5e26\u4f60\u9886\u7565\u54f2\u5b66\u5bb6\u63a2\u7d22\u4eba\u7c7b\u77e5\u8bc6\u8fb9\u754c\u7684\u4e00\u6b21\u6b21\u4f1f\u5927\u52aa\u529b\uff0c\u7528\u5e73\u5b9e\u7684\u8bed\u8a00\u5c55\u793a\u4f1f\u5927\u54f2\u5b66\u8457\u4f5c\u7684\u6df1\u523b\u4e0e\u9b45\u529b\u3002", "qcg_id": 77, "qcg_member_name": "\u5218\u73ae", "qcg_member_avatar": "http://piccdn.igetget.com/img/201708/25/201708251126368588659193.jpg", "book_count": 13, "uv": 0, "status": 1, "share_title": "\u542c\u4e66\u89e3\u8bfb\u4eba:\u5218\u73ae", "share_summary": "\u5218\u73ae\uff0c\u4e2d\u56fd\u4eba\u6c11\u5927\u5b66\u54f2\u5b66\u9662\u526f\u6559\u6388\u3002\u4ed6\u662f\u5317\u4eac\u5927\u5b66\u54f2\u5b66\u5b66\u58eb\uff0c\u6e05\u534e\u5927\u5b66\u54f2\u5b66\u7855\u58eb\uff0c\u9999\u6e2f\u4e2d\u6587\u5927\u5b66\u54f2\u5b66\u535a\u58eb\uff0c\u7f8e\u56fd\u52a0\u5dde\u5927\u5b66\u4f2f\u514b\u5229\u5206\u6821\u3001\u5fb7\u56fd\u6155\u5c3c\u9ed1\u5927\u5b66\u8bbf\u95ee\u5b66\u8005\u3002\r\n\r\n\u4e3b\u8981\u7814\u7a76\u53e4\u5e0c\u814a\u54f2\u5b66\u3001\u897f\u65b9\u54f2\u5b66\u53f2\u3002\r\n\r\n\u4ed6\u662f\u5f97\u5230App\u201c\u6bcf\u5929\u542c\u672c\u4e66\u201d\u680f\u76ee\u897f\u65b9\u54f2\u5b66\u7ecf\u5178\u7cfb\u5217\u89e3\u8bfb\u4eba\u3002\u8fd9\u4e2a\u7cfb\u5217\u5e0c\u671b\u5e26\u4f60\u9886\u7565\u54f2\u5b66\u5bb6\u63a2\u7d22\u4eba\u7c7b\u77e5\u8bc6\u8fb9\u754c\u7684\u4e00\u6b21\u6b21\u4f1f\u5927\u52aa\u529b\uff0c\u7528\u5e73\u5b9e\u7684\u8bed\u8a00\u5c55\u793a\u4f1f\u5927\u54f2\u5b66\u8457\u4f5c\u7684\u6df1\u523b\u4e0e\u9b45\u529b\u3002", "share_img": "http://piccdn.igetget.com/img/201708/25/201708251126368588659193.jpg", "share_url": "http://m.dev.igetget.com/share/agency/id/7", "created_at": 1521524985, "updated_at": 1548301243, "rank_pos": 3, "log_id": "7", "log_type": "agency"}, {"id": 12, "name": "\u67f4\u77e5\u9053", "intro": "\u4e13\u6ce8\u4e8e\u77e5\u8bc6\u4f20\u64ad\u7684\u81ea\u5a92\u4f53\u56e2\u961f\u30022016\u5e74\u5f00\u59cb\u5236\u4f5c\u77e5\u8bc6\u77ed\u89c6\u9891\u548c\u8bfb\u4e66\u8282\u76ee\uff0c\u76ee\u524d\u5168\u7f51\u89c6\u9891\u64ad\u653e\u91cf\u8d85\u8fc75\u4ebf\u6b21\uff0c\u5168\u5e73\u53f0\u7c89\u4e1d\u6570\u8d85\u8fc71000\u4e07\u3002\r\n\r\n\u64c5\u957f\u89e3\u8bfb\u79d1\u666e\u7ecf\u5178\u8457\u4f5c\u3001\u77e5\u8bc6\u578b\u4e66\u7c4d\u3002", "qcg_id": 296, "qcg_member_name": "\u67f4\u77e5\u9053", "qcg_member_avatar": "http://piccdn.igetget.com/img/201803/20/201803201106400361846914.jpg", "book_count": 17, "uv": 0, "status": 1, "share_title": "\u542c\u4e66\u89e3\u8bfb\u4eba:\u67f4\u77e5\u9053", "share_summary": "\u4e13\u6ce8\u4e8e\u77e5\u8bc6\u4f20\u64ad\u7684\u81ea\u5a92\u4f53\u56e2\u961f\u30022016\u5e74\u5f00\u59cb\u5236\u4f5c\u77e5\u8bc6\u77ed\u89c6\u9891\u548c\u8bfb\u4e66\u8282\u76ee\uff0c\u76ee\u524d\u5168\u7f51\u89c6\u9891\u64ad\u653e\u91cf\u8d85\u8fc75\u4ebf\u6b21\uff0c\u5168\u5e73\u53f0\u7c89\u4e1d\u6570\u8d85\u8fc71000\u4e07\u3002\r\n\r\n\u64c5\u957f\u89e3\u8bfb\u79d1\u666e\u7ecf\u5178\u8457\u4f5c\u3001\u77e5\u8bc6\u578b\u4e66\u7c4d\u3002", "share_img": "http://piccdn.igetget.com/img/201803/20/201803201106400361846914.jpg", "share_url": "http://m.dev.igetget.com/share/agency/id/12", "created_at": 1521529920, "updated_at": 1550746618, "rank_pos": 4, "log_id": "12", "log_type": "agency"}]}}
2 | http://entree.dev.igetget.com/kaleidoscope/homepage/new_structure|POST|200|95|{"h":{"c":0,"e":"","s":1558450482,"t":2},"c":{"home_bucket_id":"A","ios_column_switch":0,"now":"2019-05-21","structure":[{"count":5,"data":{},"has_title":2,"page_type":112,"position":20,"struct_id":25487,"type":"NewCategory"},{"count":1,"data":{},"has_title":2,"page_type":113,"position":40,"struct_id":25489,"type":"HomepageOperationAssortment"},{"count":1,"data":{},"has_title":2,"page_type":10,"position":50,"struct_id":25490,"type":"live"},{"count":0,"data":{},"has_title":1,"page_type":3,"position":60,"struct_id":25491,"type":"freeAudio"},{"count":0,"data":{},"has_title":2,"page_type":2,"position":70,"struct_id":25494,"type":"column"},{"count":0,"data":{},"has_title":2,"page_type":36,"position":80,"struct_id":25493,"type":"master"},{"count":0,"data":{},"has_title":2,"page_type":22,"position":90,"struct_id":25492,"type":"course"},{"count":1,"data":{},"has_title":2,"page_type":131,"position":100,"struct_id":25495,"type":"HomepageLastUpdateStory"},{"count":1,"data":{},"has_title":2,"page_type":130,"position":110,"struct_id":25496,"type":"HomepageLastUpdateEbook"},{"count":1,"data":{},"has_title":2,"page_type":132,"position":120,"struct_id":25497,"type":"NewHomepageLastUpdateClass"},{"count":1,"data":{},"has_title":2,"page_type":90,"position":130,"struct_id":25498,"type":"NewHomepageOperationContentModule"},{"count":3,"data":{},"has_title":2,"page_type":127,"position":150,"struct_id":25500,"type":"HomepageRankList"},{"count":0,"data":{"list":[{"count":0,"data":{},"has_title":2,"page_type":124,"position":4,"struct_id":25484,"type":"RecommendGoods"},{"count":0,"data":{},"has_title":2,"page_type":125,"position":5,"struct_id":25485,"type":"RecommendFeedBanner"}]},"has_title":2,"page_type":129,"position":270,"struct_id":25512,"type":"NewGuessYouLike"}]}}|{"h": {"c": 0, "e": "", "s": 1558450482, "t": 2}, "c": {"home_bucket_id": "A", "ios_column_switch": 0, "now": "2019-05-21", "structure": [{"count": 5, "data": {}, "has_title": 2, "page_type": 112, "position": "", "struct_id": 25487, "type": "NewCategory"}, {"count": 1, "data": {}, "has_title": 2, "page_type": 113, "position": 40, "struct_id": 25489, "type": "HomepageOperationAssortment"}, {"count": 1, "data": {}, "has_title": 2, "page_type": 10, "position": 50, "struct_id": 25490, "type": "live"}, {"count": 0, "data": {}, "has_title": 1, "page_type": 3, "position": 60, "struct_id": 25491, "type": "freeAudio"}, {"count": 0, "data": {}, "has_title": 2, "page_type": 2, "position": 70, "struct_id": 25494, "type": "column"}, {"count": 0, "data": {}, "has_title": 2, "page_type": 36, "position": 80, "struct_id": 25493, "type": "master"}, {"count": 0, "data": {}, "has_title": 2, "page_type": 22, "position": 90, "struct_id": 25492, "type": "course"}, {"count": 1, "data": {}, "has_title": 2, "page_type": 131, "position": 100, "struct_id": 25495, "type": "HomepageLastUpdateStory"}, {"count": 1, "data": {}, "has_title": 2, "page_type": 130, "position": 110, "struct_id": 25496, "type": "HomepageLastUpdateEbook"}, {"count": 1, "data": {}, "has_title": 2, "page_type": 132, "position": 120, "struct_id": 25497, "type": "NewHomepageLastUpdateClass"}, {"count": 1, "data": {}, "has_title": 2, "page_type": 90, "position": 130, "struct_id": 25498, "type": "NewHomepageOperationContentModule"}, {"count": 3, "data": {}, "has_title": 2, "page_type": 127, "position": 150, "struct_id": 25500, "type": "HomepageRankList"}, {"count": 0, "data": {"list": [{"count": 0, "data": {}, "has_title": 2, "page_type": 124, "position": 4, "struct_id": 25484, "type": "RecommendGoods"}, {"count": 0, "data": {}, "has_title": 2, "page_type": 125, "position": 5, "struct_id": 25485, "type": "RecommendFeedBanner"}]}, "has_title": 2, "page_type": 129, "position": 270, "struct_id": 25512, "type": "NewGuessYouLike"}]}}
3 | http://entree.dev.igetget.com/ddph/createToken|POST|200|72|{"c":{"token":"e45d7f444c59a9afe26e4224324a4e3e"},"h":{"c":0,"e":"","t":0,"s":1558450493}}|{"c": {"token": "\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32\u8d85\u957f\u5b57\u7b26\u4e32"}, "h": {"c": 0, "e": "", "t": 0, "s": 1558450493}}
4 |
--------------------------------------------------------------------------------
/proxy/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xinxi1990/mitmfuzz/807f105788620b5322e1c59db3c46b816a59c24a/proxy/__init__.py
--------------------------------------------------------------------------------
/proxy/backups.py:
--------------------------------------------------------------------------------
1 | # -*- encoding:utf-8 -*-
2 |
3 |
4 | # author:授客
5 |
6 |
7 | import re
8 |
9 |
10 | def parse_sub_expr(sub_expr):
11 | '''
12 |
13 | 解析字表达式-元素路径的组成部分
14 |
15 | :param sub_expr:
16 |
17 | :return:
18 |
19 | '''
20 |
21 | RIGHT_INDEX_DEFAULT = '200000000' # 右侧索引的默认值 未指定右侧索引时使用,形如 key[2:]、key[:]
22 |
23 | result = re.findall('\[.+\]', sub_expr)
24 |
25 | if result: # 如果子表达式为数组,形如 [1]、key[1]、 key[1:2]、 key[2:]、 key[:3]、key[:]
26 |
27 | array_part = result[0]
28 |
29 | array_part = array_part.lstrip('[').rstrip(']')
30 |
31 | key_part = sub_expr[:sub_expr.index('[')]
32 |
33 | if key_part == '$': # 如果key为 $ ,为根,替换为数据变量 json_data
34 |
35 | key_part = JSON_DATA_VARNAME
36 |
37 | elif key_part == '*':
38 |
39 | key_part == '\[.+\]' # 如果key为 * ,替换为 \[\.+\] 以便匹配 ["key1"]、["key2"]、……
40 |
41 | else:
42 |
43 | key_part = '\["%s"\]' % key_part
44 |
45 | if array_part == '*': # 如果数组索引为 * ,替换为 \[\d+\] 以便匹配 [0]、[1]、……
46 |
47 | array_part = '\[\d+\]'
48 |
49 | else:
50 |
51 | array_part_list = array_part.replace(' ', '').split(':')
52 |
53 | left_index = array_part_list[0:1]
54 |
55 | right_index = array_part_list[1:]
56 |
57 | if left_index:
58 |
59 | left_index = left_index[0]
60 |
61 | if not (left_index or left_index.isdigit()): # 为空字符串、非数字
62 |
63 | left_index = '0'
64 |
65 | else:
66 |
67 | left_index = '0'
68 |
69 | if right_index:
70 |
71 | right_index = right_index[0]
72 |
73 | if not (right_index or right_index.isdigit()):
74 | right_index = RIGHT_INDEX_DEFAULT # 一个比较大的值,
75 |
76 | array_part = left_index + '-' + right_index
77 |
78 | else:
79 |
80 | array_part = left_index
81 |
82 | array_part = '\[[%s]\]' % array_part # 数组索引设置为 \[[n-m]\],以便匹配[n],[n+1], ……,[m-1]
83 |
84 | return key_part + array_part
85 |
86 | elif sub_expr == '*':
87 |
88 | sub_expr = '\[.+\]'
89 |
90 | elif sub_expr == '$':
91 |
92 | sub_expr = JSON_DATA_VARNAME
93 |
94 | else:
95 |
96 | sub_expr = '\["%s"\]' % sub_expr
97 |
98 | return sub_expr
99 |
100 |
101 | def parse_json(json_data, data_struct_link):
102 | '''
103 |
104 | 递归解析json数据结构,存储元素的路径
105 |
106 | :param json_data:
107 |
108 | :param data_struct_link:
109 |
110 | :return:
111 |
112 | '''
113 |
114 | if type(json_data) == type({}): # 字典类型
115 |
116 | keys_list = json_data.keys()
117 |
118 | for key in keys_list:
119 |
120 | temp_data_struct_link = data_struct_link + '["%s"]' % key
121 |
122 | if type(json_data[key]) not in [type({}), type([])]: # key对应的value值既不是数组,也不是字典
123 |
124 | data_struct_list.append(temp_data_struct_link)
125 |
126 | else:
127 |
128 | parse_json(json_data[key], temp_data_struct_link)
129 |
130 | elif type(json_data) == type([]): # 数组类型
131 |
132 | array_length = len(json_data)
133 |
134 | for index in range(0, array_length):
135 |
136 | temp_json_data = json_data[index]
137 |
138 | keys_list = temp_json_data.keys()
139 |
140 | for key in keys_list:
141 |
142 | temp_data_struct_link = data_struct_link + '[%s]["%s"]' % (str(index), key)
143 |
144 | if type(temp_json_data[key]) not in [type({}), type([])]: # key对应的value值既不是数组,也不是字典
145 |
146 | data_struct_list.append(temp_data_struct_link)
147 |
148 | else:
149 |
150 | parse_json(temp_json_data[key], temp_data_struct_link)
151 |
152 |
153 | if __name__ == '__main__':
154 |
155 | json_data = [{"data": [{
156 |
157 | "admin": "string|集群负责人|||",
158 |
159 | "components": [
160 |
161 | {
162 |
163 | "clusterId": "integer|组件所属的集群 id|||",
164 |
165 | "createTime": "string|组件创建时间|||",
166 |
167 | "description": "string|组件描述|||",
168 |
169 | "enabled": "boolean|组件是否开启||false|",
170 |
171 | },
172 |
173 | {
174 |
175 | "clusterId": "integer|组件所属的集群 id|||",
176 |
177 | "createTime": "string|组件创建时间|||",
178 |
179 | "description": "string|组件描述|||",
180 |
181 | "enabled": "boolean|组件是否开启||false|",
182 |
183 | }
184 |
185 | ],
186 |
187 | "createTime": "string|集群创建时间|||",
188 |
189 | "description": "string|集群描述|||",
190 |
191 | "enabled": "boolean|集群是否开启||false|",
192 |
193 | "id": "integer|集群 id|||",
194 |
195 | "modifyTime": "string|集群修改时间|||",
196 |
197 | "name": "string|集群名|||"
198 |
199 | }],
200 |
201 | "errMsg": "string||||",
202 |
203 | "ok": "boolean||||",
204 |
205 | "status": "integer||||"
206 |
207 | }]
208 |
209 | JSON_DATA_VARNAME = 'json_data' # 存在json数据的变量名称
210 |
211 | data_struct_list = [] # 用于存放所有 json 元素路径,形如 json_data[0]["data"][0]["components"][0]["enabled"]
212 |
213 | data_struct_link = 'json_data' # 用于临时存放单条json 元素路径(的一部分)
214 |
215 | parse_json(json_data, data_struct_link)
216 |
217 | print('获取的json元素路径,元素值如下:')
218 |
219 | for item in data_struct_list:
220 | print(item, '\t', eval(item))
221 |
222 | # 测试用表达式
223 |
224 | # expr = '$.data[*].components[0]' # json数据为字典 形如 {……}
225 |
226 | # expr = '$[*].data[0:1].components[*]' # json数据为数组 形如 [{……}]
227 |
228 | expr = 'data[0:1].components[*]'
229 |
230 | # expr = 'data[0:1].components'
231 |
232 | # 解析表达式为正则表达式
233 |
234 | re_pattern = ''
235 |
236 | for sub_expr in expr.split('.'):
237 | re_pattern += parse_sub_expr(sub_expr)
238 |
239 | print('\n元素路径jsonpath表达式为:%s' % expr)
240 |
241 | print('元素路径正则表达式re pattern为:%s' % re_pattern)
242 |
243 | print('\njsonpath 匹配结果如下:')
244 |
245 | re_pattern = re.compile(re_pattern)
246 |
247 | target_set = set() # 匹配结果会有重复值,所以采用集合
248 |
249 | for item in data_struct_list:
250 |
251 | results = re.findall(re_pattern, item)
252 |
253 | for result in results:
254 | print('匹配的元素路径jsonpath为:%s' % item)
255 |
256 | print('正则匹配结果为:%s' % result)
257 |
258 | target = item[0:item.index(result) + len(result)]
259 |
260 | print('供提取数据使用的jsonpath为:%s' % target)
261 |
262 | print('提取的结果值为:%s \n' % eval(target))
263 |
264 | target_set.add(target)
265 |
266 | # 通过匹配提取的目标结果,操作json串
267 |
268 | for item in target_set:
269 | print("target item:" + item)
270 | target = eval(item)
271 | print("target value:{}".format(target))
272 | print("target type:{}".format(type(target)))
273 |
274 | if type(target) == type({}): # 如果为字典
275 |
276 | # 更改键的值
277 | print("更改键的值")
278 | target['clusterId'] = 10
279 |
280 | # 新增键值对
281 |
282 | target['new_key'] = 'key_value'
283 |
284 | # 更改键的名称,可以考虑先复制旧的键值,赋值给新的键,然后删除旧的键
285 |
286 | target['description_new'] = target['description']
287 |
288 | # 删除键值对
289 |
290 | del target['description']
291 |
292 |
293 |
294 | elif type(target) == type([]):
295 |
296 | # 暂不实现
297 |
298 | pass
299 |
300 | print(json_data)
--------------------------------------------------------------------------------
/proxy/constant.py:
--------------------------------------------------------------------------------
1 | # *_*coding:utf-8 *_*
2 |
3 | split_joint='+'
--------------------------------------------------------------------------------
/proxy/filetools.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 |
5 | """
6 | @Author : xinxi
7 | @Time : 2018/12/5 18:34
8 | @describe: 常用操作类
9 | """
10 |
11 | import os,re,time,subprocess,sys
12 | sys.path.append('..')
13 |
14 |
15 |
16 | def write_file(filename,content,is_cover=False):
17 | '''
18 | 写入文件 覆盖写入
19 | :param filename:
20 | :param content:
21 | :param is_cover:是否覆盖写入
22 | :return:
23 | '''
24 | try:
25 | newstr = ""
26 | if isinstance(content,list or tuple):
27 | for str in content:
28 | newstr = newstr + str + "\n"
29 | else:
30 | newstr = content + "\n"
31 | if is_cover == True:
32 | file_mode = "w"
33 | else:
34 | file_mode = "a"
35 | with open(filename,file_mode,encoding='utf-8') as f_w:
36 | f_w.write(newstr)
37 | print('写{}文件完成'.format(filename))
38 | except Exception as e:
39 | print('{}写入异常!{}'.format(filename,e))
40 |
41 |
42 | def del_files(filename):
43 | '''
44 | 删除文件
45 | :param filename:
46 | :return:
47 | '''
48 | try:
49 | if os.path.exists(filename):
50 | subprocess.call("rm -rf {}".format(filename), shell=True)
51 | print('删除{}完成!'.format(filename))
52 | except Exception as e:
53 | print('删除{}异常!{}'.format(filename,e))
54 |
55 |
56 | def mk_dir(foldername):
57 | '''
58 | 创建文件目录
59 | :return:
60 | '''
61 | try:
62 | if not os.path.exists(foldername):
63 | subprocess.call("mkdir {}".format(foldername), shell=True)
64 | print('创建{}完成!'.format(foldername))
65 | except Exception as e:
66 | print('创建{}异常!'.format(foldername,e))
67 |
68 |
69 | def read_file(filename):
70 | '''
71 | 读取文件
72 | :return:
73 | '''
74 | result = ''
75 | try:
76 | with open(filename,"r") as f_r:
77 | result = f_r.readlines()
78 | except Exception as e:
79 | print('{}读取异常!{}'.format(filename,e))
80 | finally:
81 | if isinstance(result,list) and len(result) == 1:
82 | return result[0]
83 | else:
84 | return result
85 |
86 |
87 |
88 | if __name__ == '__main__':
89 | write_file("test.log", "111111", is_cover=False)
90 |
--------------------------------------------------------------------------------
/proxy/genhtml.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | @Author : xinxi
6 | @Time : 2018/12/5 18:34
7 | @describe: 创建报告
8 | """
9 |
10 | import os, time, sys, json
11 | sys.path.append('..')
12 | from jinja2 import Environment, PackageLoader
13 | from deepdiff import DeepDiff
14 |
15 |
16 | class Create():
17 |
18 | def __init__(self, report_path, log_path):
19 | self.report_path = report_path
20 | self.log_path = log_path
21 |
22 | def create_html(self):
23 | '''
24 | 生成html报告
25 | '''
26 | report_folder = os.path.join(self.report_path, 'reports')
27 | if not os.path.exists(report_folder):
28 | os.makedirs(report_folder)
29 | print("创建报告存储文件夹:{}".format(report_folder))
30 | report_path = os.path.join(report_folder, "report_{}.html".format(time.strftime("%Y%m%d%H%M%S")))
31 | try:
32 | env = Environment(loader=PackageLoader('proxy', 'templates'))
33 | template = env.get_template("template.html")
34 | records = Create.gen_data(self.log_path)
35 | html_content = template.render(html_report_name="测试报告", records=records)
36 | with open(report_path, "wb") as f:
37 | f.write(html_content.encode("utf-8"))
38 | print('报告地址:\n{}'.format(report_path))
39 | except Exception as e:
40 | print('生成报告异常!{}'.format(e))
41 | finally:
42 | return report_path
43 |
44 | @staticmethod
45 | def gen_data(file_path):
46 | '''
47 | 组装数据
48 | :return:
49 | '''
50 | records = []
51 | with open(file_path, encoding='utf-8') as f_r:
52 | i=0
53 | for line in f_r.readlines():
54 | i=i+1
55 | print('line:',line)
56 | print('line[0]:',line[0])
57 | if line[0]!='{':
58 | line_json = eval(line[1:]) #第一行第一个可能有个特殊字符
59 | else:
60 | line_json = eval(line)
61 | param_len = line_json['param_len']
62 | item = line_json['param_value']
63 | data = {}
64 | data['name'] = item[0:param_len[0]]
65 | data['method'] = item[param_len[0] + 1:param_len[0] + 1 + param_len[1]]
66 | data['status'] = item[param_len[0] + param_len[1] + 2:param_len[0] + param_len[1] + param_len[2] + 2]
67 | data['response_time_ms'] = item[
68 | param_len[0] + param_len[1] + param_len[2] + 3:param_len[0] + param_len[1] +
69 | param_len[2] + param_len[
70 | 3] + 3]
71 | data_original_str = str(item[
72 | param_len[0] + param_len[1] + param_len[2] + param_len[3] + 4:param_len[0] +
73 | param_len[1] +
74 | param_len[2] +
75 | param_len[3] +
76 | param_len[4] + 4])
77 | data_intercept_str = str(item[
78 | param_len[0] + param_len[1] + param_len[2] + param_len[3] + param_len[4] + 5:
79 | param_len[0] + param_len[1] + param_len[2] + param_len[3] + param_len[4] +
80 | param_len[5] + 5])
81 | data['original'] = json.dumps(eval(data_original_str), indent=4)
82 | data['intercept'] = json.dumps(eval(data_intercept_str), indent=4)
83 | # diff_data = diff(eval(item[2]),eval(item[3]))
84 | diff_data = DeepDiff(eval(data_original_str), eval(data_intercept_str), ignore_order=True)
85 | data['diff'] = diff_data
86 | records.append(data)
87 | return records
88 |
89 |
90 | if __name__ == '__main__':
91 | save_path = sys.argv[1]
92 | request_log_path = sys.argv[2]
93 | Create(save_path, request_log_path).create_html()
94 |
--------------------------------------------------------------------------------
/proxy/logger.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 |
5 | '''
6 | 日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET
7 | 使用规则:
8 | 1.正常输出使用INFO
9 | 2.捕获异常使用ERROR
10 | 3.调试代码使用DEBUG
11 | 4.setLevel可以通过外部参数修改
12 | @author:xinxi
13 | '''
14 |
15 | import logging
16 | import sys
17 | import time
18 | from colorama import Back, Fore, Style, init
19 | from colorlog import ColoredFormatter
20 |
21 |
22 |
23 | init(autoreset=True)
24 |
25 | log_colors_config = {
26 | 'DEBUG': 'cyan',
27 | 'INFO': 'green',
28 | 'WARNING': 'yellow',
29 | 'ERROR': 'red',
30 | 'CRITICAL': 'red',
31 | }
32 |
33 |
34 | def setup_logger(log_level):
35 | """setup root logger with ColoredFormatter."""
36 | level = getattr(logging, log_level.upper(), None)
37 | if not level:
38 | color_print("Invalid log level: %s" % log_level, "RED")
39 | sys.exit(1)
40 |
41 | # hide traceback when log level is INFO/WARNING/ERROR/CRITICAL
42 | if level >= logging.INFO:
43 | sys.tracebacklimit = 0
44 |
45 | formatter = ColoredFormatter(
46 | u"%(log_color)s%(bg_white)s%(levelname)-8s%(reset)s%(message)s",
47 | datefmt=None,
48 | reset=True,
49 | log_colors=log_colors_config
50 | )
51 |
52 | handler = logging.StreamHandler()
53 | handler.setFormatter(formatter)
54 | logging.root.addHandler(handler)
55 | logging.root.setLevel(level)
56 |
57 |
58 | def coloring(dt,text, color="WHITE"):
59 | fore_color = getattr(Fore, color.upper())
60 |
61 | if isinstance(text,tuple or list):
62 | text = str(text)
63 |
64 | return fore_color + ' - ' + dt + ' - ' + text
65 |
66 | def color_print(msg, color="WHITE"):
67 | fore_color = getattr(Fore, color.upper())
68 | print(fore_color + msg)
69 |
70 | def log_with_color(level):
71 | """ log with color by different level
72 | """
73 | def wrapper(text):
74 | dt = time.strftime("%Y-%m-%d %H:%M:%S")
75 | color = log_colors_config[level.upper()]
76 | getattr(logging, level.lower())(coloring(dt,text, color))
77 |
78 | return wrapper
79 |
80 | log_debug = log_with_color("debug")
81 | log_info = log_with_color("info")
82 | log_warning = log_with_color("warning")
83 | log_error = log_with_color("error")
84 | log_critical = log_with_color("critical")
85 |
--------------------------------------------------------------------------------
/proxy/mathrandom.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 |
5 | """
6 | 随机数类
7 | """
8 | import random
9 |
10 |
11 | """ generated source for module MathRandomBACK """
12 | class MathRandom(object):
13 | """ generated source for class MathRandomBACK """
14 | NOT_REPLACE = 0.35
15 | REPLACE_RESPONSE_JSON = 0.25
16 | REPLACE_RESPONSE_STR = 0.1
17 | REPLACE_RESPONSE_LIST = 0.05
18 | DELAY_RESPONES_TIME = 0.30
19 | REPLACE_STATUS_CODE = 0.04
20 |
21 | def PercentageRandom(self):
22 | """ generated source for method PercentageRandom """
23 | randomNumber = float()
24 | randomNumber = random.random()
25 | if randomNumber >= 0 and randomNumber <= self.NOT_REPLACE:
26 | return 0
27 | elif randomNumber >= self.NOT_REPLACE / 100 and randomNumber <= self.NOT_REPLACE + self.REPLACE_RESPONSE_JSON:
28 | return 1
29 | elif randomNumber >= self.NOT_REPLACE + self.REPLACE_RESPONSE_JSON and randomNumber <= self.NOT_REPLACE + self.REPLACE_RESPONSE_JSON + self.REPLACE_RESPONSE_STR:
30 | return 2
31 | elif randomNumber >= self.NOT_REPLACE + self.REPLACE_RESPONSE_JSON + self.REPLACE_RESPONSE_STR and randomNumber <= self.NOT_REPLACE + self.REPLACE_RESPONSE_JSON + self.REPLACE_RESPONSE_STR + self.REPLACE_RESPONSE_LIST:
32 | return 3
33 | elif randomNumber >= self.NOT_REPLACE + self.REPLACE_RESPONSE_JSON + self.REPLACE_RESPONSE_STR + self.REPLACE_RESPONSE_LIST and randomNumber <= self.NOT_REPLACE + self.REPLACE_RESPONSE_JSON + self.REPLACE_RESPONSE_STR + self.REPLACE_RESPONSE_LIST + self.DELAY_RESPONES_TIME:
34 | return 4
35 | elif randomNumber >= self.NOT_REPLACE + self.REPLACE_RESPONSE_JSON + self.REPLACE_RESPONSE_STR + self.REPLACE_RESPONSE_LIST + self.DELAY_RESPONES_TIME and randomNumber <= self.NOT_REPLACE + self.REPLACE_RESPONSE_JSON + self.REPLACE_RESPONSE_STR + self.REPLACE_RESPONSE_LIST + self.DELAY_RESPONES_TIME + self.REPLACE_STATUS_CODE:
36 | return 5
37 | elif randomNumber >= self.NOT_REPLACE + self.REPLACE_RESPONSE_JSON + self.REPLACE_RESPONSE_STR + self.REPLACE_RESPONSE_LIST + self.DELAY_RESPONES_TIME + self.REPLACE_STATUS_CODE and randomNumber <= self.NOT_REPLACE + self.REPLACE_RESPONSE_JSON + self.REPLACE_RESPONSE_STR + self.REPLACE_RESPONSE_LIST + self.DELAY_RESPONES_TIME + self.REPLACE_STATUS_CODE:
38 | return 6
39 | return -1
40 |
41 | @classmethod
42 | def main(cls, args):
43 | """ generated source for method main """
44 | from collections import Counter
45 | a_list = []
46 | for line in range(100):
47 | a_list.append(MathRandom().PercentageRandom())
48 | result = Counter(a_list)
49 | print(result)
50 |
51 |
52 |
53 | def get_random_list(self,list):
54 | '''
55 | 列表中随机返回一个
56 | :param list:
57 | :return:
58 | '''
59 | return random.choice(list)
60 |
61 |
62 |
63 |
64 | if __name__ == '__main__':
65 | import sys
66 | MathRandom.main(sys.argv)
67 |
68 |
69 |
--------------------------------------------------------------------------------
/proxy/parserjson.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | 解析json数据
6 | """
7 |
8 | from __future__ import print_function
9 | from mathrandom import MathRandom
10 | from jsonpath_rw import jsonpath, parse
11 | import json,re
12 | import logger
13 | logger.setup_logger('DEBUG')
14 |
15 | JSON_DATA_VARNAME = 'json_data' # 存在json数据的变量名称
16 | data_struct_list = [] # 用于存放所有 json 元素路径,形如 json_data[0]["data"][0]["components"][0]["enabled"]
17 | data_struct_link = 'json_data' # 用于临时存放单条json 元素路径(的一部分)
18 |
19 | def modify_deep_dict(new_value, json_path, json_dict):
20 | if "." in json_path:
21 | json_path_list = []
22 | for path in str(json_path).split("."):
23 | if "[" and "]" in path:
24 | value_1 = path.split('[')[0]
25 | value_2 = path.split('[')[1].replace(']', '')
26 | json_path_list.append(value_1)
27 | json_path_list.append(int(value_2))
28 | else:
29 | json_path_list.append(path)
30 | for path_str in json_path_list:
31 | get_dict(path_str, json_dict)
32 | else:
33 | json_dict[json_path] = new_value
34 | dict(json_dict).update()
35 | return json_dict
36 |
37 |
38 | def get_dict_value(new_value, json_path_list, json_dict):
39 | for path_str in json_path_list:
40 | if type(json_dict) == dict or type(json_dict) == list:
41 | new_dict = json_dict[path_str]
42 | print(new_dict)
43 | if type(new_dict) == dict or type(new_dict) == list:
44 | json_path_list.remove(path_str)
45 | print("current list size:{}".format(json_path_list.__len__()))
46 | print("current list :{}".format(json_path_list))
47 | if json_path_list.__len__() > 0:
48 | get_dict_value(new_value, json_path_list, new_dict)
49 | else:
50 | break
51 | else:
52 | print(json_dict)
53 | json_dict = new_value
54 | dict(json_dict).update()
55 | break
56 |
57 |
58 | def dict_generator(indict, pre=None):
59 | '''
60 | 递归生成所有的jsonpath路径
61 | :param indict:
62 | :param pre:
63 | :return:
64 | '''
65 | pre = pre[:] if pre else []
66 | if isinstance(indict, dict):
67 | for key, value in indict.items():
68 | if isinstance(value, dict):
69 | if len(value) == 0:
70 | yield pre + [key, '{}']
71 | else:
72 | for d in dict_generator(value, pre + [key]):
73 | yield d
74 | elif isinstance(value, list):
75 | if len(value) == 0:
76 | yield pre + [key, '[]']
77 | else:
78 | for index,v in enumerate(value):
79 | for d in dict_generator(v, pre + [key + "[{}]".format(index)]):
80 | yield d
81 | elif isinstance(value, tuple):
82 | if len(value) == 0:
83 | yield pre + [key, '()']
84 | else:
85 | for v in value:
86 | for d in dict_generator(v, pre + [key]):
87 | yield d
88 | else:
89 | yield pre + [key, value]
90 | else:
91 | yield indict
92 |
93 |
94 |
95 | def get_jsonpath_list(sJOSN):
96 | '''
97 | 生成递归jsonpath列表
98 | :return:
99 | '''
100 | jsonpath_list = []
101 | sValue = json.dumps(sJOSN)
102 | for i in dict_generator(sJOSN):
103 | get_json_path = '.'.join(i[0:-1])
104 | json_path_value = i[-1]
105 | logger.log_debug("get json path is:{}".format(get_json_path))
106 | logger.log_debug("get json path value:{}".format(json_path_value))
107 | jsonpath_list.append(get_json_path)
108 | return jsonpath_list
109 |
110 |
111 |
112 |
113 | def parse_sub_expr(sub_expr):
114 | '''
115 | 解析字表达式-元素路径的组成部分
116 | :param sub_expr:
117 | :return:
118 | '''
119 | RIGHT_INDEX_DEFAULT = '200000000' # 右侧索引的默认值 未指定右侧索引时使用,形如 key[2:]、key[:]
120 | result = re.findall('\[.+\]', sub_expr)
121 | if result: # 如果子表达式为数组,形如 [1]、key[1]、 key[1:2]、 key[2:]、 key[:3]、key[:]
122 | array_part = result[0]
123 | array_part = array_part.lstrip('[').rstrip(']')
124 | key_part = sub_expr[:sub_expr.index('[')]
125 | if key_part == '$': # 如果key为 $ ,为根,替换为数据变量 json_data
126 | key_part = JSON_DATA_VARNAME
127 | elif key_part == '*':
128 | key_part == '\[.+\]' # 如果key为 * ,替换为 \[\.+\] 以便匹配 ["key1"]、["key2"]、……
129 | else:
130 | key_part = '\["%s"\]' % key_part
131 | if array_part == '*': # 如果数组索引为 * ,替换为 \[\d+\] 以便匹配 [0]、[1]、……
132 | array_part = '\[\d+\]'
133 | else:
134 | array_part_list = array_part.replace(' ', '').split(':')
135 | left_index = array_part_list[0:1]
136 | right_index = array_part_list[1:]
137 | if left_index:
138 | left_index = left_index[0]
139 | if not (left_index or left_index.isdigit()): # 为空字符串、非数字
140 | left_index = '0'
141 | else:
142 | left_index = '0'
143 | if right_index:
144 | right_index = right_index[0]
145 | if not (right_index or right_index.isdigit()):
146 | right_index = RIGHT_INDEX_DEFAULT # 一个比较大的值,
147 | array_part = left_index + '-' + right_index
148 | else:
149 | array_part = left_index
150 | array_part = '\[[%s]\]' % array_part # 数组索引设置为 \[[n-m]\],以便匹配[n],[n+1], ……,[m-1]
151 | return key_part + array_part
152 | elif sub_expr == '*':
153 | sub_expr = '\[.+\]'
154 | elif sub_expr == '$':
155 | sub_expr = JSON_DATA_VARNAME
156 | else:
157 | sub_expr = '\["%s"\]' % sub_expr
158 | return sub_expr
159 |
160 |
161 |
162 |
163 | def parse_json(json_data, data_struct_link):
164 | '''
165 | 递归解析json数据结构,存储元素的路径
166 | :param json_data:
167 | :param data_struct_link:
168 | :return:
169 | '''
170 | if type(json_data) == type({}): # 字典类型
171 | keys_list = json_data.keys()
172 | for key in keys_list:
173 | temp_data_struct_link = data_struct_link + '["%s"]' % key
174 | if type(json_data[key]) not in [type({}), type([])]: # key对应的value值既不是数组,也不是字典
175 | data_struct_list.append(temp_data_struct_link)
176 | else:
177 | parse_json(json_data[key], temp_data_struct_link)
178 | elif type(json_data) == type([]): # 数组类型
179 | array_length = len(json_data)
180 | for index in range(0, array_length):
181 | temp_json_data = json_data[index]
182 | keys_list = temp_json_data.keys()
183 | for key in keys_list:
184 | temp_data_struct_link = data_struct_link + '[%s]["%s"]' % (str(index), key)
185 | if type(temp_json_data[key]) not in [type({}), type([])]: # key对应的value值既不是数组,也不是字典
186 | data_struct_list.append(temp_data_struct_link)
187 | else:
188 | parse_json(temp_json_data[key], temp_data_struct_link)
189 |
190 |
191 |
192 | def edit_dict(expr,new_value,json_data):
193 | '''
194 | 修改更改键的值
195 | :return:
196 | '''
197 | expr_path = expr.split(".")
198 | edit_key = expr_path[-1]
199 | expr = expr.replace("." + edit_key,'')
200 | # 解析表达式为正则表达式
201 | parse_json(json_data, data_struct_link)
202 | re_pattern = ''
203 |
204 | for sub_expr in expr.split('.'):
205 | re_pattern += parse_sub_expr(sub_expr)
206 | logger.log_debug('\n元素路径jsonpath表达式为:%s' % expr)
207 | logger.log_debug('元素路径正则表达式re pattern为:%s' % re_pattern)
208 | logger.log_debug('\njsonpath 匹配结果如下:')
209 | re_pattern = re.compile(re_pattern)
210 | target_set = set() # 匹配结果会有重复值,所以采用集合
211 | for item in data_struct_list:
212 | results = re.findall(re_pattern, item)
213 | for result in results:
214 | target = item[0:item.index(result) + len(result)]
215 | target_set.add(target)
216 |
217 | # 通过匹配提取的目标结果,操作json串
218 | for item in target_set:
219 | target = eval(item)
220 | if type(target) == type({}): # 如果为字典
221 | # 更改键的值
222 | logger.log_debug("更改键:" + edit_key)
223 | target[edit_key] = new_value
224 | elif type(target) == type([]):
225 | # 暂不实现
226 | pass
227 | logger.log_debug('重新生成的新json数据:\n{}'.format(json_data))
228 | return json_data
229 |
230 |
231 |
232 | def del_dict(expr,json_data):
233 | '''
234 | 删除键的值
235 | :return:
236 | '''
237 | expr_path = expr.split(".")
238 | del_key = expr_path[-1]
239 | expr = expr.replace("." + del_key,'')
240 | # 解析表达式为正则表达式
241 | parse_json(json_data, data_struct_link)
242 | re_pattern = ''
243 | for sub_expr in expr.split('.'):
244 | re_pattern += parse_sub_expr(sub_expr)
245 | logger.log_debug('\n元素路径jsonpath表达式为:%s' % expr)
246 | logger.log_debug('元素路径正则表达式re pattern为:%s' % re_pattern)
247 | logger.log_debug('\njsonpath 匹配结果如下:')
248 | re_pattern = re.compile(re_pattern)
249 | target_set = set() # 匹配结果会有重复值,所以采用集合
250 | for item in data_struct_list:
251 | results = re.findall(re_pattern, item)
252 | for result in results:
253 | target = item[0:item.index(result) + len(result)]
254 | target_set.add(target)
255 | # 通过匹配提取的目标结果,操作json串
256 | for item in target_set:
257 | target = eval(item)
258 | if type(target) == type({}): # 如果为字典
259 | logger.log_debug("删除键:" + del_key)
260 | del target[del_key]
261 | elif type(target) == type([]):
262 | # 暂不实现
263 | pass
264 | logger.log_debug('重新生成的新json数据:\n{}'.format(json_data))
265 | return json_data
266 |
267 |
268 |
269 |
270 | def drop_list(expr,json_data):
271 | '''
272 | 改成空列表
273 | :return:
274 | '''
275 | # 解析表达式为正则表达式
276 | expr_path = expr.split(".")
277 | del_key = expr_path[-1]
278 | expr = expr.replace("." + del_key, '')
279 | parse_json(json_data, data_struct_link)
280 | re_pattern = ''
281 | for sub_expr in expr.split('.'):
282 | re_pattern += parse_sub_expr(sub_expr)
283 | logger.log_debug('\n元素路径jsonpath表达式为:%s' % expr)
284 | logger.log_debug('元素路径正则表达式re pattern为:%s' % re_pattern)
285 | logger.log_debug('\njsonpath 匹配结果如下:')
286 | re_pattern = re.compile(re_pattern)
287 | target_set = set() # 匹配结果会有重复值,所以采用集合
288 | for item in data_struct_list:
289 | results = re.findall(re_pattern, item)
290 | for result in results:
291 | target = item[0:item.index(result) + len(result)]
292 | target_set.add(target)
293 | # 通过匹配提取的目标结果,操作json串
294 | for item in target_set:
295 | target = eval(item)
296 | print(target)
297 | if type(target) == type({}): # 如果为字典
298 | if '[*]' in del_key:
299 | target[del_key.replace('[*]','')] = []
300 | else:
301 | target[del_key] = []
302 | elif type(target) == type([]):
303 | # 暂不实现
304 | pass
305 | logger.log_debug('重新生成的新json数据:\n{}'.format(json_data))
306 | return json_data
307 |
308 |
309 |
310 |
311 |
312 | if __name__ == "__main__":
313 | json_data = {
314 | "base_config":{
315 | "enforce":{
316 | "value":"0",
317 | "inherit":"0",
318 | "global":"0"
319 | },
320 | "modify":{
321 | "value":"0",
322 | "inherit":"0",
323 | "global":"0"
324 | }
325 | },
326 | "safe_control_list":{
327 | "list":[
328 | {
329 | "gid":"0",
330 | "gname":"全网计算机",
331 | "isactive":"1",
332 | "rule_id":"0",
333 | "rule_name":"请选择规则",
334 | "time_range":"所有时间",
335 | "time_range_id":"1",
336 | "policy_tpl":"33",
337 | "policy_tpl_id":"17",
338 | "isonline":"3",
339 | "priority":"88888"
340 | },
341 | {
342 | "gid": "1",
343 | "gname": "全网计算机",
344 | "isactive": "1",
345 | "rule_id": "0",
346 | "rule_name": "请选择规则",
347 | "time_range": "所有时间",
348 | "time_range_id": "1",
349 | "policy_tpl": "33",
350 | "policy_tpl_id": "17",
351 | "isonline": "3",
352 | "priority": "99999"
353 | }
354 | ]
355 | }
356 | }
357 | # drop } _list(expr=expr, json_data=self.rep_json)
358 | # ]
359 | # }
360 | #
361 | # expr = 'safe_control_list.list[*]'
362 | # new_data = drop_list(expr=expr,json_data=json_data)
363 | #
364 | # print(new_data)
365 |
366 |
367 |
368 |
369 | # del_dict(expr=expr,json_data=json_data)
370 |
371 | # for index in range(1):
372 | # json_path_list = get_jsonpath_list(json_data)
373 | # expr = (MathRandom().get_random_list(json_path_list))
374 | # print(expr)
375 | # print(edit_dict(expr=expr,new_value="555555555555",json_data=json_data))
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
--------------------------------------------------------------------------------
/proxy/proxyrule.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 |
5 | """
6 | 使用mitmproxy的rule的规则
7 | @author:xinxi
8 | """
9 |
10 | import json,time
11 | from mathrandom import MathRandom
12 | from parserjson import *
13 | import random
14 | import logger
15 | logger.setup_logger('INFO')
16 |
17 | class ProxyRule():
18 |
19 | def __init__(self,rep_json):
20 | self.rep_json = eval(rep_json)
21 |
22 |
23 |
24 | def get_defult_data(self):
25 | return '{"h":{"c":0,"e":"","t":0.004232388,"s":1558015779},"c":{"data":{"status":1,"online_num":0,"reservation_num":0,"title":"直播测试22222","room_id":205,"intro":"test","starttime":1554972060,"starttime_desc":"周四16:41","duration":110,"endtime":1554978660,"id":205,"type":0,"log_id":205,"log_type":"igettv"}}}'
26 |
27 |
28 | def get_edit_str(self):
29 | '''
30 | 修改后的字典
31 | :return:
32 | '''
33 | json_path_list = get_jsonpath_list(self.rep_json)
34 | logger.log_debug("{}".format(json_path_list))
35 | expr = MathRandom().get_random_list(json_path_list)
36 | logger.log_debug("{}".format(expr))
37 | new_json_data = edit_dict(expr=expr, new_value=self.get_random_string(), json_data=self.rep_json)
38 | logger.log_debug("{}".format(new_json_data))
39 | return json.dumps(new_json_data)
40 |
41 |
42 | def get_del_str(self):
43 | '''
44 | 删除后的字典
45 | :return:
46 | '''
47 | json_path_list = get_jsonpath_list(self.rep_json)
48 | logger.log_debug("{}".format(json_path_list))
49 | expr = MathRandom().get_random_list(json_path_list)
50 | logger.log_debug("{}".format(expr))
51 | new_json_data = del_dict(expr=expr, json_data=self.rep_json)
52 | logger.log_debug("{}".format(new_json_data))
53 | return json.dumps(new_json_data)
54 |
55 |
56 |
57 | def not_intercept(self):
58 | '''
59 | 不篡改响应,直接返回结果
60 | :return:
61 | '''
62 | logger.log_info("not_intercept")
63 | return json.dumps(self.rep_json)
64 |
65 |
66 | def intercept_respones_json(self):
67 | '''
68 | 对返回的json数据做随机做增删操作
69 | :return:
70 | '''
71 | logger.log_info("intercept_respones_json")
72 | return json.dumps(self.rep_json)
73 |
74 |
75 |
76 | def intercept_respones_str(self):
77 | '''
78 | 对返回结果中的某个字段所增删改操作
79 | :return:
80 | '''
81 | logger.log_info("intercept_respones_str")
82 | event_list = [self.get_edit_str(), self.get_del_str()]
83 | event = MathRandom().get_random_list(event_list)
84 | return event
85 |
86 |
87 | def intercept_respones_list(self):
88 | '''
89 | 多返回结果中的数组做增删改操作
90 | :return:
91 | '''
92 | path_list = []
93 | logger.log_debug("replace_respones_list")
94 | json_path_list = get_jsonpath_list(self.rep_json)
95 | logger.log_debug("{}".format(json_path_list))
96 | for line in json_path_list:
97 | if "[" and "]" in str(line):
98 | #logger.log_info("intercept line is:{}".format(line))
99 | path_list.append(line)
100 | if path_list.__len__() != 0:
101 | expr = MathRandom().get_random_list(path_list)
102 | expr = str(expr).split('[')[0]
103 | logger.log_debug("{}".format(expr))
104 | new_json_data = drop_list(expr=expr, json_data=self.rep_json)
105 | logger.log_debug("{}".format(new_json_data))
106 | return json.dumps(new_json_data)
107 | else:
108 | return json.dumps(self.rep_json)
109 |
110 |
111 |
112 |
113 |
114 | def delay_respones_time(self):
115 | '''
116 | 对返回数据做延迟返回
117 | :return:
118 | '''
119 | random_time = random.randint(100,1000)
120 | time.sleep(random_time/1000)
121 | logger.log_info("delay_respones_time:{}ms".format(random_time))
122 | return json.dumps(self.rep_json)
123 |
124 |
125 |
126 | @staticmethod
127 | def intercept_status_code():
128 | '''
129 | 对返回的状态码做随机修改
130 | :return:
131 | '''
132 | code_list = [404,500,503,302,301]
133 | random_code = MathRandom().get_random_list(code_list)
134 | logger.log_info("replace_status_code:{}".format(random_code))
135 | return random_code
136 |
137 |
138 | def get_random_string(self):
139 | '''
140 | 获取随机字符串
141 | :return:
142 | '''
143 | string_list = ['','超长字符串' * 100, self.special_string()]
144 | string = MathRandom().get_random_list(string_list)
145 | return string
146 |
147 |
148 | def special_string(self):
149 | '''
150 | 随机10位特殊字符
151 | :return:
152 | '''
153 | list = [chr(i) for i in range(65, 91)] + [chr(i) for i in range(97, 123)] + [str(i) for i in range(10)] + ['.','-','~','_']
154 | # 大写字母+小写字母+数字 +特殊字符.-_~
155 | num = random.sample(list, 10)
156 | str1 = ''
157 | value = str1.join(num)
158 | logger.log_info("special_string is:{}".format(value))
159 | return value
160 |
161 |
162 |
163 | def get_random_event(self):
164 | '''
165 | 获取随机事件
166 | :param num:
167 | :return:
168 | '''
169 | num = MathRandom().PercentageRandom()
170 | for case in switch(num):
171 | if case(0):
172 | self.not_intercept()
173 | break
174 | if case(1):
175 | self.intercept_respones_json()
176 | break
177 | if case(2):
178 | self.intercept_respones_str()
179 | break
180 | if case(3):
181 | self.intercept_respones_list()
182 | break
183 | if case(4):
184 | self.delay_respones_time()
185 | break
186 | if case(4):
187 | self.intercept_status_code()
188 | break
189 | if case():
190 | self.not_intercept()
191 |
192 |
193 |
194 | class switch(object):
195 | def __init__(self, value):
196 | self.value = value
197 | self.fall = False
198 |
199 | def __iter__(self):
200 | """Return the match method once, then stop"""
201 | yield self.match
202 | raise StopIteration
203 |
204 | def match(self, *args):
205 | """Indicate whether or not to enter a case suite"""
206 | if self.fall or not args:
207 | return True
208 | elif self.value in args: # changed for v1.5, see below
209 | self.fall = True
210 | return True
211 | else:
212 | return False
213 |
214 |
215 |
--------------------------------------------------------------------------------
/proxy/proxyserver.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 |
5 | """
6 | 使用mitmproxy代理工具篡改请求
7 | """
8 |
9 | import mitmproxy.http
10 | from mitmproxy import ctx
11 | import json, time, os
12 |
13 | from constant import split_joint
14 | from proxyrule import ProxyRule
15 | from mathrandom import MathRandom
16 | from filetools import *
17 |
18 | project_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
19 | now = time.strftime("%Y%m%d%H%M%S", time.localtime()) + "_intercept.log"
20 | save_log_file = os.path.join(project_path, now)
21 |
22 |
23 | def request(flow: mitmproxy.http.HTTPFlow):
24 | request = flow.request
25 | ctx.log.info("========================== intercept request start ==========================")
26 | ctx.log.info("========================== host is:{} ========================== ".format(request.host))
27 | ctx.log.info("========================== url is:{} ========================== ".format(request.pretty_url))
28 | ctx.log.info("========================== method is:{} ========================== ".format(request.method))
29 | ctx.log.info("========================== body is:{} ========================== ".format(request.get_text()))
30 | ctx.log.info("========================== intercept request end ==========================")
31 |
32 |
33 | def response(flow: mitmproxy.http.HTTPFlow):
34 | '''
35 | 篡改response返回数据
36 | :param flow:
37 | :return:
38 | '''
39 | is_mock = True
40 |
41 | black_list = ["png", "jpg", "js", "css", "html", 'img', 'cdn']
42 |
43 | for black_str in black_list:
44 | if black_str in flow.request.url:
45 | ctx.log.info("========================== not necessary intercept response ==========================")
46 | is_mock = False
47 | break
48 |
49 | if int(flow.response.status_code) == 200 and is_mock == True:
50 |
51 | original_data = (flow.response.text)
52 |
53 | if original_data.startswith("{") and original_data.endswith("}"):
54 | # get_mock_data = ProxyRule(original_data).get_random_event()
55 | get_mock_data = ProxyRule(original_data).intercept_respones_str()
56 | ctx.log.info("========================== intercept response start ==========================")
57 | # ctx.log.info("========================== mock after data:{} ==========================".format(original_data))
58 | # ctx.log.info("========================== mock before data:{} ==========================".format(get_mock_data))
59 | flow.response.set_text(get_mock_data)
60 | ctx.log.info(flow.response.text)
61 | ctx.log.info("========================== intercept response end ==========================")
62 | spend_time = int((flow.response.timestamp_end - flow.request.timestamp_start) * 1000)
63 | req_url = str(flow.request.url)
64 |
65 | req_method = str(flow.request.method)
66 | resp_status_code = str(flow.response.status_code)
67 | spend_time_str = str(spend_time)
68 | original_data_str = str(original_data)
69 | get_mock_data_str = str(get_mock_data)
70 | content={"param_len":" ","param_value":" "}
71 | param_value = req_url + split_joint + req_method + split_joint + resp_status_code + split_joint \
72 | + spend_time_str + split_joint + original_data_str + split_joint + get_mock_data_str
73 | req_url_len = len(req_url)
74 | req_method_len = len(req_method)
75 | resp_status_code_len = len(resp_status_code)
76 | spend_time_str_len = len(spend_time_str)
77 | original_data_str_len = len(original_data_str)
78 | get_mock_data_str_len = len(get_mock_data_str)
79 | content["param_len"] = [req_url_len, req_method_len, resp_status_code_len, spend_time_str_len,
80 | original_data_str_len, get_mock_data_str_len]
81 | content["param_value"]=param_value
82 |
83 | ctx.log.info("========================== write data to file==========================")
84 |
85 | write_file(save_log_file, str(content), is_cover=False)
86 |
--------------------------------------------------------------------------------
/proxy/run.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 |
5 | """
6 | 运行入口
7 | """
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/proxy/script.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 |
5 |
6 | def request(flow):
7 | flow.request.headers['User-Agent'] = 'MitmProxy'
8 | print(flow.request.headers)
--------------------------------------------------------------------------------
/proxy/templates/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | TestReport
5 |
129 |
130 |
131 | Test Report: {{html_report_name}}
132 |
133 | Details
134 |
135 |
136 | Name |
137 | Status |
138 | Response Time |
139 | Detail |
140 |
141 | {% for record in records %}
142 |
143 | {{record.name}}
144 | | {{record.status}} |
145 | {{ '%0.1f'| format(record.response_time_ms|float) }} ms |
146 |
147 | data
148 |
159 |
160 |
161 | |
162 |
163 | {% endfor %}
164 |
165 |
166 |
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 |
2 |
3 | source tutorial-env/bin/activate
4 |
5 | cd dumphrun
6 |
7 | mitmweb -s proxyserver.py
--------------------------------------------------------------------------------
/报告1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xinxi1990/mitmfuzz/807f105788620b5322e1c59db3c46b816a59c24a/报告1.jpg
--------------------------------------------------------------------------------
/报告2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xinxi1990/mitmfuzz/807f105788620b5322e1c59db3c46b816a59c24a/报告2.jpg
--------------------------------------------------------------------------------