├── .gitignore ├── COPYING.txt ├── FriedRing.egg-info ├── PKG-INFO ├── SOURCES.txt ├── dependency_links.txt ├── entry_points.txt ├── requires.txt ├── top_level.txt └── zip-safe ├── FriedRing ├── Cfg.py ├── Cfg.pyc ├── F2requests.py ├── F2requests.pyc ├── FriedRing.py ├── FriedRing.pyc ├── Img2Base64.py ├── __init__.py ├── alasRun.py └── fr.py ├── MANIFEST.in ├── README.md ├── __init__.py ├── build └── lib │ └── FriedRing │ ├── Cfg.py │ ├── F2requests.py │ ├── FriedRing.py │ ├── __Conf │ ├── __init__.py │ └── test_scripts │ │ ├── __init__.py │ │ ├── script.py │ │ └── v_user.py │ ├── __init__.py │ └── fr.py ├── files.txt ├── requirement.txt └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.nja 2 | *.pyc 3 | _build 4 | build 5 | dist 6 | .tox 7 | -------------------------------------------------------------------------------- /COPYING.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, CrissChan_陈磊 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 21 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /FriedRing.egg-info/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.1 2 | Name: FriedRing 3 | Version: 2.0.6 4 | Summary: this is a FriedRing package for get http request and response. 5 | Home-page: http://blog.csdn.net/crisschan 6 | Author: CrissChan 7 | Author-email: can101208@gmail.com 8 | License: MIT 9 | Description: #FriedRing 10 | ##简介 11 | 通过mitmproxy实现了交互脚本的录制,通过multimechanize实现了并发测试和测试报告(html格式)生产,同时格式化了mitmproxy脚本为requests格式 12 | ##基础 13 | 1、mitmproxy 14 | 15 | 2、multimechanize 16 | 17 | 3、requests 18 | 19 | ##安装mitmproxy和multimechanize 20 | ###Mac or Unbuntu 21 | pip install mitmproxy 22 | pip install -U multi-mechanize 23 | pip install requests 24 | ###Windows 25 | python -m pip install --upgrade pip(最支持版本8.1.2,多次运行可以升级到对应版本) []() 26 | python -m pip install netlib pyopenssl pyasn1 urwid pil lxml flask 27 | python -m pip install pyamf protobuf 28 | python -m pip install pil 29 | python -m pip install nose pathod countershape 30 | python -m pip install matplotlib 31 | python -m pip install mitmproxy 32 | pip install -U multi-mechanize 33 | pip install requests 34 | ##安装FiredRing 35 | 36 | pip install -U FiredRing 37 | 38 | ##使用FriedRing 39 | ####录制脚本 40 | 首先,输入命令 41 | 42 | fr -p 8888 -w scriptsolution 43 | 44 | -p 端口号,-w 测试脚本文件夹 45 | 46 | 其次,在测试浏览器或者测试手机中设置代理(ip为运行主机ip,端口为888) 47 | 按照功能测试流程进行功能测试,在当前文件夹中会产生一个scriptsolition的文件夹,结构如下: 48 | 49 | scriptsolution/config.cfg(multimechan的配置文件) 50 | 51 | scriptsolution/test _ scripts/v_user.py(默认的初始化脚步) 52 | 53 | scriptsolution/test _ scripts/script.py(生成的测试脚步) 54 | 55 | 在录制完成后,需要修改scriptsolution/test _ scripts/script.py文件,去掉不属于本次测试的请求。 56 | 57 | 同时可以通过加入assert等信息做断言(详情可以参考requests包) 58 | 59 | 60 | 61 | ####运行脚本 62 | #####Mac or Unbuntu 63 | 在scriptsolution的父文件夹(也就是fr的workspace),执行 64 | 65 | fr -r s 66 | 67 | fr -r p 68 | 69 | 参数说明: 70 | s - 线性执行当前父文件夹(workspace)下的全部性能测试场景 71 | p - 并发执行执行当前父文件夹(workspace)下的全部性能测试场景 72 | 73 | 测试结果在当前父文件夹(workspace)下的Report文件夹内,分为并发测试报告(Report/Parralle_Result/文件夹下)和线性执行测试报告(Report/Serial_Result/) 74 | 75 | fr -r p后的扩展参数: 76 | 77 | -t is runtime that duration of test (seconds) 78 | -u is rampup that duration of user rampup 79 | -i is resultinterval that time series interval for results analysis (seconds) 80 | -b is progressbar that turn on/off console progress bar during test run default = on 81 | -c is consolelogging that turn on/off logging to stdout default = on 82 | -x is xmlreport that turn on/off xml/jtl report default = off 83 | -v is vusers that number of threads/virtual users for each scenrio default=10 84 | 85 | 86 | #####Windows 87 | 88 | 在scriptsolution的父文件夹,执行 89 | 90 | C:\FriedRing>python c:\Python27\Lib\site-packages\multimechanize\utilities\run.py scriptsolution 91 | 92 | ##查看结果 93 | 结果在scriptsolution文件夹下的results里面,按照时间顺序生产的文件夹,里面有一个result.html,用浏览器打开就可以看到结果信息了。 94 | ## 源代码地址 95 | https://github.com/crisschan/FriedRing 96 | ## config文件 97 | 98 | config文件在脚本的根目录,文件名字config.cfg 99 | 格式如下: 100 | 101 | [global] 102 | run_time = 300 103 | rampup = 300 104 | results_ts_interval = 30 105 | progress_bar = on 106 | console_logging = off 107 | xml_report = off 108 | results_database = sqlite:///my_project/results.db 109 | post_run_script = python my_project/foo.py 110 | 111 | [user_group-1] 112 | threads = 30 113 | script = vu_script1.py 114 | 115 | [user_group-2] 116 | threads = 30 117 | script = vu_script2.py 118 | 119 | 120 | 其中[global]是场景全局配置[user_group-*]是各个脚本的配置 121 | 122 | 123 | Global Options 124 | 125 | 126 | 127 | run_time: 测试时长 (seconds) [required] 128 | rampup: vuser也就是虚拟用户的启动时间(例如100个vusers,rampup要是10秒的话,就是1秒钟启动10个vusers) (seconds) [required] 129 | results_ts_interval: 结果分析采样点时间间隔 (seconds) [required] 130 | progress_bar: 测试过程中console是不是显示执行进度条(on/off) [optional, default = on] 131 | console_logging: 标准输出日志开关on/off [optional, default = off] 132 | xml_report: xml格式报告开关on/off [optional, default = off] 133 | results_database: 数据库连接字符串 [optional] 134 | post_run_script: 测试完成后要调用的脚本[optional] 135 | User Groups 136 | 137 | threads: 并发线程数(vusers) 138 | script: 测试脚本 139 | Keywords: FriedRing python package 140 | Platform: UNKNOWN 141 | Classifier: License :: OSI Approved :: MIT License 142 | Classifier: Development Status :: 5 - Production/Stable 143 | Classifier: Environment :: Console 144 | Classifier: Environment :: Console :: Curses 145 | Classifier: Operating System :: MacOS :: MacOS X 146 | Classifier: Operating System :: POSIX 147 | Classifier: Programming Language :: Python 148 | Classifier: Programming Language :: Python :: 2.7 149 | Classifier: Programming Language :: Python :: Implementation :: CPython 150 | Classifier: Programming Language :: Python :: Implementation :: PyPy 151 | Classifier: Topic :: Internet 152 | Classifier: Topic :: Internet :: WWW/HTTP 153 | Classifier: Topic :: Software Development :: Testing 154 | -------------------------------------------------------------------------------- /FriedRing.egg-info/SOURCES.txt: -------------------------------------------------------------------------------- 1 | MANIFEST.in 2 | README.md 3 | requirement.txt 4 | setup.py 5 | FriedRing/Cfg.py 6 | FriedRing/F2requests.py 7 | FriedRing/FriedRing.py 8 | FriedRing/Img2Base64.py 9 | FriedRing/__init__.py 10 | FriedRing/alasRun.py 11 | FriedRing/fr.py 12 | FriedRing.egg-info/PKG-INFO 13 | FriedRing.egg-info/SOURCES.txt 14 | FriedRing.egg-info/dependency_links.txt 15 | FriedRing.egg-info/entry_points.txt 16 | FriedRing.egg-info/requires.txt 17 | FriedRing.egg-info/top_level.txt 18 | FriedRing.egg-info/zip-safe -------------------------------------------------------------------------------- /FriedRing.egg-info/dependency_links.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /FriedRing.egg-info/entry_points.txt: -------------------------------------------------------------------------------- 1 | [console_scripts] 2 | fr = FriedRing.fr:main 3 | 4 | -------------------------------------------------------------------------------- /FriedRing.egg-info/requires.txt: -------------------------------------------------------------------------------- 1 | argh==0.26.2 2 | backports-abc==0.4 3 | backports.ssl-match-hostname==3.5.0.1 4 | blinker==1.4 5 | certifi==2016.2.28 6 | cffi==1.7.0 7 | click==6.6 8 | ConfigArgParse==0.10.0 9 | construct==2.5.2 10 | cryptography==1.3.4 11 | html2text==2016.4.2 12 | cycler==0.10.0 13 | enum34==1.1.6 14 | Flask==0.10.1 15 | h2==2.3.1 16 | hpack==2.2.0 17 | http-prompt==0.2.0 18 | httpie==0.9.3 19 | hyperframe==3.2.0 20 | idna==2.1 21 | ipaddress==1.0.16 22 | itsdangerous==0.24 23 | Jinja2==2.8 24 | jsonpickle==0.4.0 25 | lxml==3.6.0 26 | MarkupSafe==0.23 27 | matplotlib==1.5.1 28 | mechanize==0.2.5 29 | mitmproxy==0.17 30 | multi-mechanize==1.2.0 31 | numpy==1.11.0 32 | parsimonious==0.6.2 33 | passlib==1.6.5 34 | pathtools==0.1.2 35 | Pillow==3.2.0 36 | plac==0.9.1 37 | poster==0.8.1 38 | prompt-toolkit==1.0.0 39 | pyasn1==0.1.9 40 | pycparser==2.14 41 | Pygments==2.1.3 42 | pyOpenSSL==16.0.0 43 | pyparsing==2.1.4 44 | pyperclip==1.5.27 45 | python-dateutil==2.5.3 46 | pytz==2016.4 47 | PyYAML==3.11 48 | requests==2.9.1 49 | scapy==2.3.2 50 | singledispatch==3.4.0.3 51 | six==1.10.0 52 | tornado==4.3 53 | Unirest==1.1.7 54 | urwid==1.3.1 55 | watchdog==0.8.3 56 | wcwidth==0.1.6 57 | Werkzeug==0.11.10 58 | -------------------------------------------------------------------------------- /FriedRing.egg-info/top_level.txt: -------------------------------------------------------------------------------- 1 | FriedRing 2 | -------------------------------------------------------------------------------- /FriedRing.egg-info/zip-safe: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /FriedRing/Cfg.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | class Cfg(): 5 | def __init__(self, fscriptsolutionpath, curscenrioscript): 6 | self.fscriptsolutionpath = fscriptsolutionpath 7 | self.curscenrioscript = curscenrioscript 8 | self.__Setcfg() 9 | self.__SetVU() 10 | 11 | def __Setcfg(self): 12 | fcfgpath = str(self.fscriptsolutionpath) + '/config.cfg' 13 | fcfg = open(fcfgpath, 'w') 14 | scfglines = '[global]\r\n' \ 15 | 'run_time = 30\r\n' \ 16 | 'rampup = 0\r\n' \ 17 | 'results_ts_interval = 1\r\nprogress_bar = on\r\nconsole_logging = on\r\nxml_report = off\r\n\r\n[user_group - 1]\r\nthreads = 1\r\nscript = ' + self.curscenrioscript + 'v_user.py' 18 | fcfg.write(scfglines) 19 | fcfg.close() 20 | 21 | def __SetVU(self): 22 | fV_UserPath = os.path.join(self.fscriptsolutionpath, 'test_scripts') 23 | if not os.path.isdir(fV_UserPath): 24 | os.makedirs(fV_UserPath) 25 | fV_Userfile = str(fV_UserPath) + '/' + self.curscenrioscript + 'v_user.py' 26 | fV_Userscript = open(fV_Userfile, 'w') 27 | sScript = '#!/usr/bin/env python\r\n#coding=utf-8\r\nimport requests\r\nimport json\r\nimport time\r\nimport ' + self.curscenrioscript + 'script\r\nclass Transaction(object):\r\n def __init__(self):\r\n #self.custom_timers={}\r\n pass\r\n def run(self):\r\n #start_timer = time.time()\r\n ' + self.curscenrioscript + 'script.script()\r\n #latency = time.time() - start_timer\r\n #user\'s transaction \r\n #self.custom_timers[\'Transaction_Custom\']=latency\r\nif __name__ == \'__main__\':\r\n trans = Transaction()\r\n trans.run()\r\n #print trans.custom_timers' 28 | fV_Userscript.write(sScript) 29 | fV_Userscript.close() 30 | -------------------------------------------------------------------------------- /FriedRing/Cfg.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crisschan/FriedRing/dad6594c440c0e37239ff934895d35a7d69826df/FriedRing/Cfg.pyc -------------------------------------------------------------------------------- /FriedRing/F2requests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #coding=utf-8 3 | ''' 4 | author:Crisschan 5 | time:2016-7-1 6 | 7 | author:Crisschan 8 | time 2016-7-11 modi for the headers check the " to \" 9 | ''' 10 | from mitmproxy.models.http import HTTPRequest 11 | from mitmproxy.models.http import HTTPResponse 12 | class F2requests(): 13 | def __init__(self,fnamescript): 14 | self.fscript = open(fnamescript,'w+') 15 | self.__InitScript() 16 | def __del__(self): 17 | self.fscript.close() 18 | def F2Req(self,request): 19 | self.request = request 20 | if str(self.request.method) == 'GET': 21 | self.__F2Get() 22 | else: 23 | self.__F2Post() 24 | 25 | def __InsertHost(self): 26 | # insert the request host information 27 | self.fscript.write(self.__Insert8blank()+'######'+str(self.request.host)+'#######') 28 | # insert the request host information 29 | def __InsertTimeStampStart(self): 30 | # insert the request host information 31 | self.__InsertBlankRow() 32 | self.__InsertHost() 33 | self.__InsertBlankRow() 34 | self.fscript.write(self.__Insert8blank()+'# start : ') 35 | self.fscript.write(str(self.request.timestamp_start)) 36 | 37 | self.__InsertBlankRow() 38 | 39 | def __InsertTimeStampEnd(self): 40 | # inser the time stamp of end 41 | self.__InsertBlankRow() 42 | self.fscript.write(self.__Insert8blank()+'# end : ') 43 | self.fscript.write(str(self.request.timestamp_end)) 44 | 45 | self.__InsertBlankRow() 46 | 47 | def __InitScript(self): 48 | # insert the global import 49 | strPreScript = '#!/usr/bin/env python\r\n' 50 | strPreScript=strPreScript+'#coding=utf-8\r\n' 51 | strPreScript=strPreScript+'import requests\r\nimport json\r\nimport time\r\n\r\ndef script():' 52 | self.fscript.write(strPreScript) 53 | self.__InsertBlankRow() 54 | 55 | def __InsertBlankRow(self): 56 | # insert a blank row to script 57 | self.fscript.write('\r\n') 58 | 59 | def __InserAssert(self): 60 | # insert the assert target point 61 | self.__InsertBlankRow() 62 | self.fscript.write(self.__Insert8blank()+'#insert the assert or other check point #exp. print r.text') 63 | self.__InsertBlankRow() 64 | 65 | def __F2Header(self): 66 | # insert the http header 67 | # modi add the replace " to \" 68 | strT = str(self.request.headers) 69 | strT= strT.replace('\"','\\\"') 70 | strT = '\"' + strT 71 | strT = strT.replace('\r\n', '\n') 72 | strT = strT.replace('\n', '","') 73 | #strT = strT.replace('\n', '",\r\n"') #for format header 74 | strT = strT.replace(': ', '":"') 75 | strT = '{' + strT[:-2] + '}' 76 | return strT 77 | def __Insert8blank(self): 78 | return ' ' 79 | def __F2Get(self): 80 | #print 'get --' 81 | self.__InsertTimeStampStart() 82 | #insert the header 83 | self.fscript.write(self.__Insert8blank()+'headers='+self.__F2Header()) 84 | self.__InsertBlankRow() 85 | # insert the get request 86 | strRquest = 'http://'+str(self.request.host)+str(self.request.path) 87 | strRquest=self.__Insert8blank()+'r=requests.get("'+strRquest+'",headers=headers)' 88 | self.fscript.write(strRquest) 89 | self.__InsertTimeStampEnd() 90 | self.__InserAssert() 91 | def __F2Post(self): 92 | self.__InsertTimeStampStart() 93 | self.__InsertBlankRow() 94 | self.fscript.write(self.__Insert8blank()+'headers=' + self.__F2Header()) 95 | self.__InsertBlankRow() 96 | self.fscript.write(self.__Insert8blank()+'payload = "'+self.request.content+'"') 97 | self.__InsertBlankRow() 98 | strRquest = 'http://'+str(self.request.host) + str(self.request.path) 99 | strRquest = self.__Insert8blank()+'r=requests.post("' + strRquest + '",data=payload,headers=headers)' 100 | self.fscript.write(strRquest) 101 | self.__InsertTimeStampEnd() 102 | self.__InserAssert() 103 | 104 | -------------------------------------------------------------------------------- /FriedRing/F2requests.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crisschan/FriedRing/dad6594c440c0e37239ff934895d35a7d69826df/FriedRing/F2requests.pyc -------------------------------------------------------------------------------- /FriedRing/FriedRing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | ''' 4 | author:Crisschan 5 | time:2016-6-30 6 | ''' 7 | from mitmproxy import controller, proxy 8 | import os 9 | import datetime 10 | from F2requests import F2requests 11 | from Cfg import Cfg 12 | 13 | 14 | class FriedRing(controller.Master): 15 | # fscript = 16 | def __init__(self, server, fnamescript): 17 | curscenrioscript = fnamescript 18 | curpath = os.path.abspath(os.curdir) 19 | fscriptsolutionpath = os.path.join(curpath, fnamescript) 20 | if not os.path.isdir(fscriptsolutionpath): 21 | os.makedirs(fscriptsolutionpath) 22 | else: 23 | fnamescript = fnamescript + str(datetime.datetime.now().microsecond) 24 | fscriptsolutionpath = os.path.join(curpath, fnamescript) 25 | os.makedirs(fscriptsolutionpath) 26 | 27 | Cfg(fscriptsolutionpath, curscenrioscript) 28 | self.fnamescript = str(fscriptsolutionpath) + '/test_scripts/' + curscenrioscript + 'script.py' 29 | print 'script solution path(include script files, config files and results:' + str(fscriptsolutionpath) 30 | 31 | controller.Master.__init__(self, server) 32 | self.f2r = F2requests(self.fnamescript) 33 | 34 | # def shutdown(self): 35 | # self.shutdown() 36 | def run(self): 37 | try: 38 | return controller.Master.run(self) 39 | except KeyboardInterrupt: 40 | self.shutdown() 41 | 42 | def handle_request(self, msg): 43 | # print msg 44 | req = msg.request 45 | print str(req.host) + str(req.path) 46 | self.f2r.F2Req(req) 47 | msg.reply() 48 | 49 | def handle_response(self, msgg): 50 | # print msg 51 | msgg.reply() 52 | res = msgg.response 53 | ''' 54 | print res.status_code 55 | print res.headers 56 | print res.content+'\n' 57 | print res.reason+'\n' 58 | print res.timestamp_start+'\n' 59 | print res.timestamp_end+'\n' 60 | print '--------------------------------------\n' 61 | ''' 62 | 63 | 64 | ''' 65 | if __name__ == '__main__': 66 | opts = options.Options(cadir="~/.mitmproxy/", listen_port=8888) 67 | config = proxy.ProxyConfig(opts) 68 | server = proxy.ProxyServer(config) 69 | m = FriedRing(server,'/Users/chancriss/Desktop/WorkSpace/PythonSpace/FriedRingWorkSpace/') 70 | m.run() 71 | ''' 72 | -------------------------------------------------------------------------------- /FriedRing/FriedRing.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crisschan/FriedRing/dad6594c440c0e37239ff934895d35a7d69826df/FriedRing/FriedRing.pyc -------------------------------------------------------------------------------- /FriedRing/Img2Base64.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # encoding=utf8 3 | import base64 4 | import os 5 | 6 | 7 | class Img2Base64(object): 8 | ''' 9 | 将图片变成base64编码,然后在web中打开,不用引入图片外部图片文件 10 | ''' 11 | 12 | def __init__(self, sImgDir): 13 | fr = open(sImgDir, 'rb') 14 | self.hexImg = base64.b64encode(fr.read()) 15 | fr.close() 16 | 17 | 18 | '''if __name__=='__main__': 19 | 20 | print ' ' 21 | ''' 22 | -------------------------------------------------------------------------------- /FriedRing/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crisschan/FriedRing/dad6594c440c0e37239ff934895d35a7d69826df/FriedRing/__init__.py -------------------------------------------------------------------------------- /FriedRing/alasRun.py: -------------------------------------------------------------------------------- 1 | # encoding=utf8 2 | # !/usr/bin/python 3 | 4 | import os 5 | import subprocess 6 | from Img2Base64 import Img2Base64 7 | import time 8 | import shutil 9 | 10 | 11 | class alasRun(object): 12 | ''' 13 | 多场景的混合运行类,可以执行在test workspace下的全部测试场景, 14 | 支持并发和线性执行两种模式 15 | this is a class for merge all performance testing scenario 16 | that scenario under the current test workspace dir 17 | ''' 18 | 19 | def __init__(self): 20 | 21 | self.strCurPath = os.path.abspath(os.curdir) # get the current work space 22 | 23 | self.scenariolist = [] 24 | # self._collectReport() 25 | 26 | # self.startTime=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time())) 27 | # self.endTime=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time())) 28 | 29 | def _collectScenario(self): 30 | ''' 31 | collect performance test scenario that under test workspace name 32 | Returns: 33 | null 34 | ''' 35 | for root, dirs, files in os.walk(self.strCurPath): 36 | # print dirs 37 | 38 | for file in files: 39 | 40 | if file.find('script.py') >= 0 and root.find('Parralle_Scenario') < 0 and file[len(file) - 1] != 'c': 41 | tempscenario = root[len(self.strCurPath):] 42 | tempscenario = tempscenario[1:tempscenario.rfind('/')] 43 | # print tempscenario 44 | self.scenariolist.append(tempscenario) 45 | 46 | def _SerialReportIndex(self, ScenarioList, sResult): 47 | ''' 48 | make the serial report index page 49 | Args: 50 | ScenarioList: scenario list 51 | sResult: the result dir 52 | 53 | Returns: 54 | 55 | ''' 56 | wf = open(sResult + 'index.html', 'w') 57 | wf.write(''' 59 | 60 | 61 | Serial Report 62 | 63 | 64 | 123 | 124 | 125 | 126 |

Performance Results Report List

127 | 128 |

Summary

''') 129 | wf.write('test start: ' + self.startTime + '

') 130 | wf.write('test finish: ' + self.endTime + '

') 131 | wf.write('''

All Scenario

132 |

Detail

133 | 134 | 135 | ''') 136 | for Scenario in ScenarioList: 137 | wf.write( 138 | '') 139 | wf.write('''
Scanrio Name Report link
' + Scenario + '' + Scenario + '
140 | 141 | ''') 142 | wf.close() 143 | 144 | def _ImgtoHTMLBase(self, imgfile): 145 | sImgBase64 = ' ' 147 | return sImgBase64 148 | 149 | def _collectReport(self): 150 | ''' 151 | this is a collection all scenrio report fun,and output the serial_result dir 152 | Returns: 153 | the report dir 154 | ''' 155 | if not os.path.exists(self.strCurPath + '/Report/Serial_Result/'): 156 | os.makedirs(self.strCurPath + '/Report/Serial_Result/') 157 | sCurResult = self.strCurPath + '/Report/Serial_Result/Serial_Result' + time.strftime("%Y%m%d%H%M%S", 158 | time.localtime( 159 | time.time())) + '/' 160 | 161 | os.makedirs(sCurResult) 162 | 163 | aTempReportList = [] 164 | # aTempReportfilelist=[] 165 | for scenario in self.scenariolist: 166 | aTempstr = self.strCurPath + '/' + scenario + '/results/' 167 | for root, dirs, files in os.walk(aTempstr): 168 | for file in files: 169 | if file == 'results.html': 170 | # All_Transactions_response_times_intervals.png 171 | # All_Transactions_response_times.png 172 | # All_Transactions_throughput.png 173 | reportfile = os.path.join(root, file) 174 | rf = open(reportfile, 'r') 175 | sResult = rf.read() 176 | rf.close() 177 | sbtimesintervals = self._ImgtoHTMLBase( 178 | os.path.join(root, 'All_Transactions_response_times_intervals.png')) 179 | 180 | sbtimes = self._ImgtoHTMLBase(os.path.join(root, 'All_Transactions_response_times.png')) 181 | sthroughput = self._ImgtoHTMLBase(os.path.join(root, 'All_Transactions_throughput.png')) 182 | sResult = sResult.replace('', 183 | sbtimesintervals) 184 | sResult = sResult.replace('', 185 | sbtimes) 186 | sResult = sResult.replace('', 187 | sthroughput) 188 | aTempReportList.append(scenario) 189 | 190 | sTempResultfile = sCurResult + scenario + '.html' 191 | 192 | wf = open(sTempResultfile, 'w') 193 | wf.write(sResult) 194 | wf.close() 195 | 196 | self._SerialReportIndex(aTempReportList, sCurResult) 197 | 198 | def _mvReport(self): 199 | 200 | sCurReport = self.strCurPath + '/Report/Parralle_Result/' 201 | 202 | sOldReport = self.strCurPath + '/Parralle_Scenario/results/' 203 | 204 | if os.path.exists(sCurReport): 205 | shutil.rmtree(sCurReport) 206 | shutil.copytree(sOldReport, sCurReport) 207 | 208 | def _clearHistoryScenrioResult(self): 209 | ''' 210 | clear all scenrio history result 211 | Returns: 212 | 213 | ''' 214 | for scenario in self.scenariolist: 215 | aTempstr = self.strCurPath + '/' + scenario + '/results/' 216 | if os.path.exists(aTempstr): 217 | shutil.rmtree(aTempstr) 218 | 219 | def sRun(self): 220 | ''' 221 | serial process all scenario under test work space 222 | Returns: 223 | 224 | ''' 225 | self.scenariolist = [] 226 | self._collectScenario() 227 | if len(self.scenariolist) <= 0: 228 | print 'No Performance Test Scenario Under Current Test WorkSpace' 229 | return 0 230 | self._clearHistoryScenrioResult() 231 | 232 | i = 0 233 | self.startTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) 234 | print '##Performance Test is running,Please wait!!' 235 | print 'Serial Run:' 236 | # print self.scenariolist 237 | 238 | for aline in self.scenariolist: 239 | i = i + 1 240 | print '*****************************************************************' 241 | print 'Run Scenario ' + str(i) + ' : ' + aline 242 | print '*****************************************************************' 243 | sTempCommand = 'multimech-run ' + aline 244 | 245 | sSubp = subprocess.Popen(sTempCommand, shell=True, stdout=subprocess.PIPE) 246 | while sSubp.poll() == None: 247 | print sSubp.stdout.readline() 248 | self.endTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) 249 | self._collectReport() 250 | 251 | def _ParrallelConfig(self, sConfig,run_time = 30,rampup = 0,results_ts_interval = 1,progress_bar = 'on',console_logging = 'on',xml_report = 'off',threads = 10): 252 | wf = open(sConfig, 'w') 253 | sGlobalCfg= '[global]\r\n' \ 254 | 'run_time = '+run_time+'\r\n' \ 255 | 'rampup = '+rampup+'\r\n' \ 256 | 'results_ts_interval = '+results_ts_interval+'\r\n' \ 257 | 'progress_bar = '+progress_bar+'\r\n' \ 258 | 'console_logging = '+console_logging+'\r\n' \ 259 | 'xml_report = '+xml_report+'\r\n' 260 | wf.write(sGlobalCfg) 261 | i = 1 262 | # print self.scenariolist 263 | for scenariotemp in self.scenariolist: 264 | wf.write('[user_group - ' + str(i) + ']\r\n') 265 | i = i + 1 266 | wf.write('threads = '+threads+'\r\n') 267 | wf.write('script = ' + scenariotemp + 'v_user.py\r\n') 268 | wf.close() 269 | 270 | def _MergParralleScript(self,run_time,rampup,results_ts_interval,progress_bar,console_logging,xml_report,threads): 271 | 272 | sCurScenario = self.strCurPath + '/Parralle_Scenario/' 273 | if not os.path.exists(sCurScenario): 274 | os.makedirs(sCurScenario) 275 | self.scenariolist = [] 276 | self._collectScenario() 277 | if len(self.scenariolist) <= 0: 278 | # print 'No Performance Test Scenario Under Current Test WorkSpace' 279 | return 0 280 | sCruScenarioTestScript = sCurScenario + 'test_scripts/' 281 | if os.path.exists(sCruScenarioTestScript): 282 | shutil.rmtree(sCruScenarioTestScript) 283 | os.makedirs(sCruScenarioTestScript) 284 | sConfig = sCurScenario + 'config.cfg' 285 | self._ParrallelConfig(sConfig,run_time,rampup,results_ts_interval,progress_bar,console_logging,xml_report,threads) 286 | for ascenario in self.scenariolist: 287 | 288 | for root, dirs, files in os.walk(self.strCurPath + '/' + ascenario + '/test_scripts/'): 289 | for file in files: 290 | shutil.copyfile(os.path.join(self.strCurPath + '/' + ascenario + '/test_scripts/', file), 291 | sCruScenarioTestScript + file) 292 | # shutil.copyfile 293 | 294 | def pRun(self,run_time = 30,rampup = 0,results_ts_interval = 1,progress_bar = 'on',console_logging = 'on',xml_report = 'off',threads = 10): 295 | self._MergParralleScript(run_time,rampup,results_ts_interval,progress_bar,console_logging,xml_report,threads) 296 | if len(self.scenariolist) <= 0: 297 | print 'No Performance Test Scenario Under Current Test WorkSpace' 298 | return 0 299 | # self.startTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) 300 | sTempCommand = 'multimech-run Parralle_Scenario' 301 | sSubp = subprocess.Popen(sTempCommand, shell=True, stdout=subprocess.PIPE) 302 | print '##Performance Test is running,Please wait!!' 303 | while sSubp.poll() == None: 304 | print sSubp.stdout.readline() 305 | 306 | # self.endTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) 307 | self._mvReport() 308 | 309 | 310 | ''' 311 | if __name__ == '__main__': 312 | arun = alasRun() 313 | arun.pRun() 314 | arun.sRun() 315 | ''' 316 | -------------------------------------------------------------------------------- /FriedRing/fr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | import getopt 4 | import os 5 | import time 6 | import sys 7 | import types 8 | from mitmproxy import proxy 9 | from FriedRing import FriedRing 10 | from alasRun import alasRun 11 | 12 | VERSION = '2.0.6' 13 | #run_time = 30,rampup = 0,results_ts_interval = 1,progress_bar = 'on',console_logging = 'on',xml_report = 'off',threads = 10): 14 | 15 | def main(): 16 | opts, args = getopt.getopt(sys.argv[1:], "hp:w:r:t:u:i:b:c:x:v:", 17 | ["help","proxyport=", "workspace=","run=","runtime=","rampup=","resultinterval=","progressbar=","consolelogging=","xmlreport=","vusers="]) 18 | strPort = 8888 19 | fnamescript = '__crisschan_TEMP' + time.strftime("%Y%m%d%H%M%S", time.localtime(time.time())) 20 | op='' 21 | sTargetRun='c' 22 | run_time = 30 23 | rampup = 0 24 | results_ts_interval = 1 25 | progress_bar = 'on' 26 | console_logging = 'on' 27 | xml_report = 'off' 28 | threads = 10 29 | for op, value in opts: 30 | if op in ("-p","--proxyport"): 31 | strPort = value 32 | elif op in ("-w","--workspace"): 33 | fnamescript = value 34 | elif op in ("-r","--run"): 35 | sTargetRun = value 36 | elif op in ('-t',"--runtime"): 37 | run_time =value 38 | elif op in ("-u","--rampup"): 39 | rampup=value 40 | elif op in ("-i","--resultinterval"): 41 | results_ts_interval=value 42 | elif op in ("-b","--progressbar"): 43 | progress_bar=value 44 | elif op in ("-c","--consolelogging"): 45 | console_logging=value 46 | elif op in ("-x","--xmlreport"): 47 | xml_report=value 48 | elif op in ("-v","--vusers"): 49 | threads=value 50 | elif op in ("-h","--help"): 51 | # usage() 52 | print '-p the proxy port\r\n' \ 53 | '-r the run all scenario under test workspace,the param is:\r\n' \ 54 | ' s - is serial run all scenrio \r\n' \ 55 | ' p - is parralle run all scenrio\r\n' \ 56 | '-w the performance test workspace name \r\n\r\n' \ 57 | 'other is the scenrio config seting that is available for parralle run:\r\n' \ 58 | ' -t is runtime that duration of test (seconds)\r\n' \ 59 | ' -u is rampup that duration of user rampup\r\n' \ 60 | ' -i is resultinterval that time series interval for results analysis (seconds) \r\n' \ 61 | ' -b is progressbar that turn on/off console progress bar during test run default = on\r\n' \ 62 | ' -c is consolelogging that turn on/off logging to stdout default = on\r\n' \ 63 | ' -x is xmlreport that turn on/off xml/jtl report default = off\r\n' \ 64 | ' -v is vusers that number of threads/virtual users for each scenrio default=10\r\n' 65 | 66 | sys.exit() 67 | 68 | config = proxy.ProxyConfig( 69 | cadir=os.path.expanduser("~/.mitmproxy/"), 70 | port=int(strPort) 71 | ) 72 | #print run_time,rampup,results_ts_interval,progress_bar,console_logging,xml_report,threads 73 | if sTargetRun != 'c': 74 | ARun = alasRun() 75 | if sTargetRun == 's': 76 | ARun.sRun() 77 | elif sTargetRun == 'p': 78 | 79 | if progress_bar!='on' and progress_bar!='off': 80 | print 'progress_bar only input on/off!' 81 | return 0 82 | if console_logging!='on' and console_logging!='off': 83 | print 'console_logging only input on/off!' 84 | return 0 85 | if xml_report!='on' and xml_report!='off': 86 | print 'xml_report only input on/off!' 87 | return 0 88 | 89 | ARun.pRun(run_time,rampup,results_ts_interval,progress_bar,console_logging,xml_report,threads) 90 | else: 91 | print '-r is the error input!!!!' 92 | return 0 93 | else: 94 | server = proxy.ProxyServer(config) 95 | print 'the porxy port is ' + str(strPort) 96 | m = FriedRing(server, fnamescript) 97 | m.run() 98 | 99 | 100 | ''' 101 | print strPort 102 | print fnamescript 103 | print op 104 | print sTargetRun 105 | print run_time 106 | print rampup 107 | print results_ts_interval 108 | print progress_bar 109 | print console_logging 110 | print xml_report 111 | print threads 112 | ''' 113 | 114 | if __name__ == "__main__": 115 | main() 116 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include setup.py 2 | include requirement.txt 3 | include README.md 4 | include MANIFEST.in -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #FriedRing 2 | ##简介 3 | 通过mitmproxy实现了交互脚本的录制,通过multimechanize实现了并发测试和测试报告(html格式)生产,同时格式化了mitmproxy脚本为requests格式 4 | ##基础 5 | 1、mitmproxy 6 | 7 | 2、multimechanize 8 | 9 | 3、requests 10 | 11 | ##安装mitmproxy和multimechanize 12 | ###Mac or Unbuntu 13 | pip install mitmproxy 14 | pip install -U multi-mechanize 15 | pip install requests 16 | ###Windows 17 | python -m pip install --upgrade pip(最支持版本8.1.2,多次运行可以升级到对应版本) []() 18 | python -m pip install netlib pyopenssl pyasn1 urwid pil lxml flask 19 | python -m pip install pyamf protobuf 20 | python -m pip install pil 21 | python -m pip install nose pathod countershape 22 | python -m pip install matplotlib 23 | python -m pip install mitmproxy 24 | pip install -U multi-mechanize 25 | pip install requests 26 | ##安装FiredRing 27 | 28 | pip install -U FiredRing 29 | 30 | ##使用FriedRing 31 | ####录制脚本 32 | 首先,输入命令 33 | 34 | fr -p 8888 -w scriptsolution 35 | 36 | -p 端口号,-w 测试脚本文件夹 37 | 38 | 其次,在测试浏览器或者测试手机中设置代理(ip为运行主机ip,端口为888) 39 | 按照功能测试流程进行功能测试,在当前文件夹中会产生一个scriptsolition的文件夹,结构如下: 40 | 41 | scriptsolution/config.cfg(multimechan的配置文件) 42 | 43 | scriptsolution/test _ scripts/v_user.py(默认的初始化脚步) 44 | 45 | scriptsolution/test _ scripts/script.py(生成的测试脚步) 46 | 47 | 在录制完成后,需要修改scriptsolution/test _ scripts/script.py文件,去掉不属于本次测试的请求。 48 | 49 | 同时可以通过加入assert等信息做断言(详情可以参考requests包) 50 | 51 | 52 | 53 | ####运行脚本 54 | #####Mac or Unbuntu 55 | 在scriptsolution的父文件夹(也就是fr的workspace),执行 56 | 57 | fr -r s 58 | 59 | fr -r p 60 | 61 | 参数说明: 62 | s - 线性执行当前父文件夹(workspace)下的全部性能测试场景 63 | p - 并发执行执行当前父文件夹(workspace)下的全部性能测试场景 64 | 65 | 测试结果在当前父文件夹(workspace)下的Report文件夹内,分为并发测试报告(Report/Parralle_Result/文件夹下)和线性执行测试报告(Report/Serial_Result/) 66 | 67 | fr -r p后的扩展参数: 68 | 69 | -t is runtime that duration of test (seconds) 70 | -u is rampup that duration of user rampup 71 | -i is resultinterval that time series interval for results analysis (seconds) 72 | -b is progressbar that turn on/off console progress bar during test run default = on 73 | -c is consolelogging that turn on/off logging to stdout default = on 74 | -x is xmlreport that turn on/off xml/jtl report default = off 75 | -v is vusers that number of threads/virtual users for each scenrio default=10 76 | 77 | 78 | #####Windows 79 | 80 | 在scriptsolution的父文件夹,执行 81 | 82 | C:\FriedRing>python c:\Python27\Lib\site-packages\multimechanize\utilities\run.py scriptsolution 83 | 84 | ##查看结果 85 | 结果在scriptsolution文件夹下的results里面,按照时间顺序生产的文件夹,里面有一个result.html,用浏览器打开就可以看到结果信息了。 86 | ## 源代码地址 87 | https://github.com/crisschan/FriedRing 88 | ## config文件 89 | 90 | config文件在脚本的根目录,文件名字config.cfg 91 | 格式如下: 92 | 93 | [global] 94 | run_time = 300 95 | rampup = 300 96 | results_ts_interval = 30 97 | progress_bar = on 98 | console_logging = off 99 | xml_report = off 100 | results_database = sqlite:///my_project/results.db 101 | post_run_script = python my_project/foo.py 102 | 103 | [user_group-1] 104 | threads = 30 105 | script = vu_script1.py 106 | 107 | [user_group-2] 108 | threads = 30 109 | script = vu_script2.py 110 | 111 | 112 | 其中[global]是场景全局配置[user_group-*]是各个脚本的配置 113 | 114 | 115 | Global Options 116 | 117 | 118 | 119 | run_time: 测试时长 (seconds) [required] 120 | rampup: vuser也就是虚拟用户的启动时间(例如100个vusers,rampup要是10秒的话,就是1秒钟启动10个vusers) (seconds) [required] 121 | results_ts_interval: 结果分析采样点时间间隔 (seconds) [required] 122 | progress_bar: 测试过程中console是不是显示执行进度条(on/off) [optional, default = on] 123 | console_logging: 标准输出日志开关on/off [optional, default = off] 124 | xml_report: xml格式报告开关on/off [optional, default = off] 125 | results_database: 数据库连接字符串 [optional] 126 | post_run_script: 测试完成后要调用的脚本[optional] 127 | User Groups 128 | 129 | threads: 并发线程数(vusers) 130 | script: 测试脚本 -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crisschan/FriedRing/dad6594c440c0e37239ff934895d35a7d69826df/__init__.py -------------------------------------------------------------------------------- /build/lib/FriedRing/Cfg.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | class Cfg(): 4 | def __init__(self,fscriptsolutionpath): 5 | self.fscriptsolutionpath=fscriptsolutionpath 6 | self.__Setcfg() 7 | self.__SetVU() 8 | def __Setcfg(self): 9 | fcfgpath = str(self.fscriptsolutionpath)+'/config.cfg' 10 | fcfg = open(fcfgpath,'w') 11 | scfglines = '[global]\r\nrun_time = 30\r\nrampup = 0\r\nresults_ts_interval = 1\r\nprogress_bar = on\r\nconsole_logging = on\r\nxml_report = off\r\n\r\n[user_group - 1]\r\nthreads = 1\r\nscript = v_user.py' 12 | fcfg.write(scfglines) 13 | fcfg.close() 14 | def __SetVU(self): 15 | fV_UserPath = os.path.join(self.fscriptsolutionpath,'test_scripts') 16 | if not os.path.isdir(fV_UserPath): 17 | os.makedirs(fV_UserPath) 18 | fV_Userfile = str(fV_UserPath)+'/v_user.py' 19 | fV_Userscript = open(fV_Userfile,'w') 20 | sScript = '#!/usr/bin/env python\r\n#coding=utf-8\r\nimport requests\r\nimport json\r\nimport time\r\nimport script\r\nclass Transaction(object):\r\n def __init__(self):\r\n #self.custom_timers={}\r\n pass\r\n def run(self):\r\n #start_timer = time.time()\r\n script.script()\r\n #latency = time.time() - start_timer\r\n #user\'s transaction \r\n #self.custom_timers[\'Transaction_Custom\']=latency\r\nif __name__ == \'__main__\':\r\n trans = Transaction()\r\n trans.run()\r\n #print trans.custom_timers' 21 | fV_Userscript.write(sScript) 22 | fV_Userscript.close() 23 | 24 | 25 | -------------------------------------------------------------------------------- /build/lib/FriedRing/F2requests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #coding=utf-8 3 | ''' 4 | author:Crisschan 5 | time:2016-7-1 6 | 7 | author:Crisschan 8 | time 2016-7-11 modi for the headers check the " to \" 9 | ''' 10 | from mitmproxy.models.http import HTTPRequest 11 | from mitmproxy.models.http import HTTPResponse 12 | class F2requests(): 13 | def __init__(self,fnamescript): 14 | self.fscript = open(fnamescript,'w+') 15 | self.__InitScript() 16 | def __del__(self): 17 | self.fscript.close() 18 | def F2Req(self,request): 19 | self.request = request 20 | if str(self.request.method) == 'GET': 21 | self.__F2Get() 22 | else: 23 | self.__F2Post() 24 | 25 | def __InsertHost(self): 26 | # insert the request host information 27 | self.fscript.write(self.__Insert8blank()+'######'+str(self.request.host)+'#######') 28 | # insert the request host information 29 | def __InsertTimeStampStart(self): 30 | # insert the request host information 31 | self.__InsertBlankRow() 32 | self.__InsertHost() 33 | self.__InsertBlankRow() 34 | self.fscript.write(self.__Insert8blank()+'# start : ') 35 | self.fscript.write(str(self.request.timestamp_start)) 36 | 37 | self.__InsertBlankRow() 38 | 39 | def __InsertTimeStampEnd(self): 40 | # inser the time stamp of end 41 | self.__InsertBlankRow() 42 | self.fscript.write(self.__Insert8blank()+'# end : ') 43 | self.fscript.write(str(self.request.timestamp_end)) 44 | 45 | self.__InsertBlankRow() 46 | 47 | def __InitScript(self): 48 | # insert the global import 49 | strPreScript = '#!/usr/bin/env python\r\n' 50 | strPreScript=strPreScript+'#coding=utf-8\r\n' 51 | strPreScript=strPreScript+'import requests\r\nimport json\r\nimport time\r\n\r\ndef script():' 52 | self.fscript.write(strPreScript) 53 | self.__InsertBlankRow() 54 | 55 | def __InsertBlankRow(self): 56 | # insert a blank row to script 57 | self.fscript.write('\r\n') 58 | 59 | def __InserAssert(self): 60 | # insert the assert target point 61 | self.__InsertBlankRow() 62 | self.fscript.write(self.__Insert8blank()+'#insert the assert or other check point #exp. print r.text') 63 | self.__InsertBlankRow() 64 | 65 | def __F2Header(self): 66 | # insert the http header 67 | # modi add the replace " to \" 68 | strT = str(self.request.headers) 69 | strT= strT.replace('\"','\\\"') 70 | strT = '\"' + strT 71 | strT = strT.replace('\r\n', '\n') 72 | strT = strT.replace('\n', '","') 73 | #strT = strT.replace('\n', '",\r\n"') #for format header 74 | strT = strT.replace(': ', '":"') 75 | strT = '{' + strT[:-2] + '}' 76 | return strT 77 | def __Insert8blank(self): 78 | return ' ' 79 | def __F2Get(self): 80 | #print 'get --' 81 | self.__InsertTimeStampStart() 82 | #insert the header 83 | self.fscript.write(self.__Insert8blank()+'headers='+self.__F2Header()) 84 | self.__InsertBlankRow() 85 | # insert the get request 86 | strRquest = 'http://'+str(self.request.host)+str(self.request.path) 87 | strRquest=self.__Insert8blank()+'r=requests.get("'+strRquest+'",headers=headers)' 88 | self.fscript.write(strRquest) 89 | self.__InsertTimeStampEnd() 90 | self.__InserAssert() 91 | def __F2Post(self): 92 | self.__InsertTimeStampStart() 93 | self.__InsertBlankRow() 94 | self.fscript.write(self.__Insert8blank()+'headers=' + self.__F2Header()) 95 | self.__InsertBlankRow() 96 | self.fscript.write(self.__Insert8blank()+'payload = "'+self.request.content+'"') 97 | self.__InsertBlankRow() 98 | strRquest = 'http://'+str(self.request.host) + str(self.request.path) 99 | strRquest = self.__Insert8blank()+'r=requests.post("' + strRquest + '",data=payload,headers=headers)' 100 | self.fscript.write(strRquest) 101 | self.__InsertTimeStampEnd() 102 | self.__InserAssert() 103 | 104 | -------------------------------------------------------------------------------- /build/lib/FriedRing/FriedRing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #coding=utf-8 3 | ''' 4 | author:Crisschan 5 | time:2016-6-30 6 | ''' 7 | from mitmproxy import controller, proxy,flow 8 | from mitmproxy.proxy import ProxyServer,ProxyConfig 9 | import os 10 | import sys 11 | import pdb 12 | import requests 13 | import datetime 14 | from F2requests import F2requests 15 | from Cfg import Cfg 16 | class FriedRing(controller.Master): 17 | #fscript = 18 | def __init__(self, server,fnamescript): 19 | 20 | curpath = os.path.abspath(os.curdir) 21 | fscriptsolutionpath = os.path.join(curpath,fnamescript) 22 | if not os.path.isdir(fscriptsolutionpath): 23 | os.makedirs(fscriptsolutionpath) 24 | else: 25 | fnamescript=fnamescript+str(datetime.datetime.now().microsecond) 26 | fscriptsolutionpath = os.path.join(curpath,fnamescript) 27 | os.makedirs(fscriptsolutionpath) 28 | 29 | Cfg(fscriptsolutionpath) 30 | self.fnamescript=str(fscriptsolutionpath)+'/test_scripts/script.py' 31 | print 'script solution path(include script files, config files and results:'+str(fscriptsolutionpath) 32 | 33 | controller.Master.__init__(self, server) 34 | self.f2r = F2requests(self.fnamescript) 35 | #def shutdown(self): 36 | # self.shutdown() 37 | def run(self): 38 | try: 39 | return controller.Master.run(self) 40 | except KeyboardInterrupt: 41 | self.shutdown() 42 | def handle_request(self, msg): 43 | #print msg 44 | req=msg.request 45 | print str(req.host)+str(req.path) 46 | self.f2r.F2Req(req) 47 | msg.reply() 48 | def handle_response(self, msgg): 49 | #print msg 50 | msgg.reply() 51 | res = msgg.response 52 | ''' 53 | print res.status_code 54 | print res.headers 55 | print res.content+'\n' 56 | print res.reason+'\n' 57 | print res.timestamp_start+'\n' 58 | print res.timestamp_end+'\n' 59 | print '--------------------------------------\n' 60 | ''' 61 | '''if __name__ == '__main__': 62 | config = proxy.ProxyConfig( 63 | cadir = os.path.expanduser("~/.mitmproxy/"), 64 | port=8888 65 | ) 66 | server = proxy.ProxyServer(config) 67 | m = FriedRing(server) 68 | m.run()''' 69 | 70 | -------------------------------------------------------------------------------- /build/lib/FriedRing/__Conf/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crisschan/FriedRing/dad6594c440c0e37239ff934895d35a7d69826df/build/lib/FriedRing/__Conf/__init__.py -------------------------------------------------------------------------------- /build/lib/FriedRing/__Conf/test_scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crisschan/FriedRing/dad6594c440c0e37239ff934895d35a7d69826df/build/lib/FriedRing/__Conf/test_scripts/__init__.py -------------------------------------------------------------------------------- /build/lib/FriedRing/__Conf/test_scripts/script.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | 4 | def script(): 5 | 6 | 7 | 8 | # start : 1467623525.76 9 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 10 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 11 | "Accept": "image/webp,image/*,*/*;q=0.8", 12 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 13 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 14 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 15 | r = requests.get( 16 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=20001507&t=1467623524806", 17 | headers=headers) 18 | # end : 1467623525.8 19 | 20 | # insert the assert or other check point 21 | 22 | # start : 1467623525.76 23 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 24 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 25 | "Accept": "image/webp,image/*,*/*;q=0.8", 26 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 27 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 28 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 29 | r = requests.get( 30 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=20001501&t=1467623524815", 31 | headers=headers) 32 | # end : 1467623525.8 33 | 34 | # insert the assert or other check point 35 | 36 | # start : 1467623525.76 37 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 38 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 39 | "Accept": "image/webp,image/*,*/*;q=0.8", 40 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 41 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 42 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 43 | r = requests.get( 44 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=20001508&t=1467623524814&time=1467606424", 45 | headers=headers) 46 | # end : 1467623525.8 47 | 48 | # insert the assert or other check point 49 | 50 | # start : 1467623526.2 51 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 52 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 53 | "Accept": "image/webp,image/*,*/*;q=0.8", 54 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 55 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 56 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 57 | r = requests.get( 58 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=20004406&t=1467623525126", 59 | headers=headers) 60 | # end : 1467623526.22 61 | 62 | # insert the assert or other check point 63 | 64 | # start : 1467623526.2 65 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 66 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 67 | "Accept": "image/webp,image/*,*/*;q=0.8", 68 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 69 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 70 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 71 | r = requests.get( 72 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=20001201&t=1467623525130", 73 | headers=headers) 74 | # end : 1467623526.22 75 | 76 | # insert the assert or other check point 77 | 78 | # start : 1467623526.37 79 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 80 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 81 | "Accept": "image/webp,image/*,*/*;q=0.8", 82 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 83 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 84 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 85 | r = requests.get( 86 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=30000406&t=1467623525455", 87 | headers=headers) 88 | # end : 1467623526.41 89 | 90 | # insert the assert or other check point 91 | 92 | # start : 1467623526.37 93 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 94 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 95 | "Accept": "image/webp,image/*,*/*;q=0.8", 96 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 97 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 98 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 99 | r = requests.get( 100 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=30000403&t=1467623525447", 101 | headers=headers) 102 | # end : 1467623526.41 103 | 104 | # insert the assert or other check point 105 | 106 | # start : 1467623526.37 107 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 108 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 109 | "Accept": "image/webp,image/*,*/*;q=0.8", 110 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 111 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 112 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 113 | r = requests.get( 114 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=20001513&t=1467623525460", 115 | headers=headers) 116 | # end : 1467623526.41 117 | 118 | # insert the assert or other check point 119 | 120 | # start : 1467623526.49 121 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 122 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 123 | "Accept": "image/webp,image/*,*/*;q=0.8", 124 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 125 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 126 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 127 | r = requests.get( 128 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=30000404&t=1467623525570", 129 | headers=headers) 130 | # end : 1467623526.51 131 | 132 | # insert the assert or other check point 133 | 134 | # start : 1467623526.5 135 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 136 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 137 | "Accept": "image/webp,image/*,*/*;q=0.8", 138 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 139 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 140 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 141 | r = requests.get( 142 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=30000407&t=1467623525580", 143 | headers=headers) 144 | # end : 1467623526.52 145 | 146 | # insert the assert or other check point 147 | 148 | # start : 1467623526.5 149 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 150 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 151 | "Accept": "image/webp,image/*,*/*;q=0.8", 152 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 153 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 154 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 155 | r = requests.get( 156 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=20001516&t=1467623525604", 157 | headers=headers) 158 | # end : 1467623526.52 159 | 160 | # insert the assert or other check point 161 | 162 | # start : 1467623526.62 163 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 164 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 165 | "Accept": "image/webp,image/*,*/*;q=0.8", 166 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 167 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 168 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 169 | r = requests.get( 170 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=300001175101&t=1467623525721", 171 | headers=headers) 172 | # end : 1467623526.64 173 | 174 | # insert the assert or other check point 175 | 176 | # start : 1467623526.62 177 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 178 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 179 | "Accept": "image/webp,image/*,*/*;q=0.8", 180 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 181 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 182 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 183 | r = requests.get( 184 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=3000037201&t=1467623525729", 185 | headers=headers) 186 | # end : 1467623526.64 187 | 188 | # insert the assert or other check point 189 | 190 | # start : 1467623527.69 191 | headers = {"Host": "nsclick.baidu.com", "Proxy-Connection": "keep-alive", 192 | "User-Agent": "Mozilla/5.0 (Linux; Android 5.1; m2 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36", 193 | "Accept": "image/webp,image/*,*/*;q=0.8", 194 | "Referer": "http://wapbaike.baidu.com/subview/7410/5040563.htm?fr=aladdin&ref=wise&ssid=0&from=844b&uid=0&pu=usm@2,sz@1320_1001,ta@iphone_2_5.1_3_537&bd_page_type=1&baiduid=D1D8246AC804B5D314977701F7E75E7D&tj=Xv_2_0_10_title", 195 | "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", 196 | "Cookie": "plus_cv=0::m:1-nav:250e8bac-hotword:a6eb63c2; plus_lsv=4388bdbef257d8ef; BAIDULOC=12960396.239553755_4834358.330481074_35_131_1467606415694; H5LOC=1; BAIDUID=D1D8246AC804B5D314977701F7E75E7D:FG=1"} 197 | r = requests.get( 198 | "http://nsclick.baidu.com/v.gif?pid=103&url=http%3A%2F%2Fwapbaike.baidu.com%2Fsubview%2F7410%2F5040563.htm%3Ffr%3Daladdin%26ref%3Dwise%26ssid%3D0%26from%3D844b%26uid%3D0%26pu%3Dusm%402%2Csz%401320_1001%2Cta%40iphone_2_5.1_3_537%26bd_page_type%3D1%26baiduid%3DD1D8246AC804B5D314977701F7E75E7D%26tj%3DXv_2_0_10_title&type=30000401&t=1467623526751&blockInfo={%22mobile-lemma-top-ad%22:{%22isValid%22:true},%22mobile-lemma-float-ad%22:{%22isValid%22:true}}&page=mobile-lemma", 199 | headers=headers) 200 | # end : 1467623527.7 201 | 202 | # insert the assert or other check point 203 | 204 | 205 | 206 | # start : 1467623531.78 207 | -------------------------------------------------------------------------------- /build/lib/FriedRing/__Conf/test_scripts/v_user.py: -------------------------------------------------------------------------------- 1 | 2 | #!/usr/bin/env python 3 | #coding=utf-8 4 | ''' 5 | author:Crisschan 6 | time:2016-7-5 7 | from:multimech 8 | ''' 9 | import script 10 | class Transaction(object): 11 | def __init__(self): 12 | #self.custom_timers={} 13 | pass 14 | 15 | def run(self): 16 | #start_timer = time.time() 17 | script.script() 18 | #latency = time.time() - start_timer 19 | #user's transaction 20 | #self.custom_timers['Transaction_Custom']=latency 21 | 22 | 23 | 24 | 25 | 26 | if __name__ == '__main__': 27 | trans = Transaction() 28 | trans.run() 29 | #print trans.custom_timers 30 | -------------------------------------------------------------------------------- /build/lib/FriedRing/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crisschan/FriedRing/dad6594c440c0e37239ff934895d35a7d69826df/build/lib/FriedRing/__init__.py -------------------------------------------------------------------------------- /build/lib/FriedRing/fr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #coding=utf-8 3 | import getopt 4 | import os 5 | import time 6 | #import shutil 7 | #import subprocess 8 | import sys 9 | #import optparse 10 | 11 | from mitmproxy import proxy 12 | 13 | from FriedRing import FriedRing 14 | 15 | VERSION='1.0.5' 16 | def main(): 17 | opts, args = getopt.getopt(sys.argv[1:], "hp:w:") 18 | strPort=8888 19 | fnamescript='__crisschan_TEMP'+str(time.time()) 20 | for op, value in opts: 21 | if op == "-p": 22 | strPort = value 23 | elif op == "-w": 24 | fnamescript = value 25 | elif op == "-h": 26 | #usage() 27 | print '-p the proxy port\r\n-w the script_solution name' 28 | sys.exit() 29 | 30 | config = proxy.ProxyConfig( 31 | cadir=os.path.expanduser("~/.mitmproxy/"), 32 | port=int(strPort) 33 | ) 34 | server = proxy.ProxyServer(config) 35 | print 'the porxy port is '+str(strPort) 36 | m = FriedRing(server, fnamescript) 37 | m.run() 38 | if __name__ == "__main__": 39 | main() -------------------------------------------------------------------------------- /files.txt: -------------------------------------------------------------------------------- 1 | /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/FriedRing-1.0.0-py2.7.egg 2 | /Library/Frameworks/Python.framework/Versions/2.7/bin/fr 3 | /Library/Frameworks/Python.framework/Versions/2.7/bin/watchmedo 4 | /Library/Frameworks/Python.framework/Versions/2.7/bin/scapy 5 | /Library/Frameworks/Python.framework/Versions/2.7/bin/UTscapy 6 | /Library/Frameworks/Python.framework/Versions/2.7/bin/pygmentize 7 | /Library/Frameworks/Python.framework/Versions/2.7/bin/multimech-run 8 | /Library/Frameworks/Python.framework/Versions/2.7/bin/multimech-newproject 9 | /Library/Frameworks/Python.framework/Versions/2.7/bin/multimech-gridgui 10 | /Library/Frameworks/Python.framework/Versions/2.7/bin/mitmproxy 11 | /Library/Frameworks/Python.framework/Versions/2.7/bin/pathod 12 | /Library/Frameworks/Python.framework/Versions/2.7/bin/mitmweb 13 | /Library/Frameworks/Python.framework/Versions/2.7/bin/mitmdump 14 | /Library/Frameworks/Python.framework/Versions/2.7/bin/pathoc 15 | /Library/Frameworks/Python.framework/Versions/2.7/bin/http 16 | /Library/Frameworks/Python.framework/Versions/2.7/bin/http-prompt 17 | /Library/Frameworks/Python.framework/Versions/2.7/bin/html2text 18 | /Library/Frameworks/Python.framework/Versions/2.7/bin/easy_install-3.4 19 | /Library/Frameworks/Python.framework/Versions/2.7/bin/easy_install 20 | -------------------------------------------------------------------------------- /requirement.txt: -------------------------------------------------------------------------------- 1 | argh==0.26.2 2 | backports-abc==0.4 3 | backports.ssl-match-hostname==3.5.0.1 4 | blinker==1.4 5 | certifi==2016.2.28 6 | cffi==1.7.0 7 | click==6.6 8 | ConfigArgParse==0.10.0 9 | construct==2.5.2 10 | cryptography==1.3.4 11 | html2text==2016.4.2 12 | cycler==0.10.0 13 | enum34==1.1.6 14 | Flask==0.10.1 15 | h2==2.3.1 16 | hpack==2.2.0 17 | http-prompt==0.2.0 18 | httpie==0.9.3 19 | hyperframe==3.2.0 20 | idna==2.1 21 | ipaddress==1.0.16 22 | itsdangerous==0.24 23 | Jinja2==2.8 24 | jsonpickle==0.4.0 25 | lxml==3.6.0 26 | MarkupSafe==0.23 27 | matplotlib==1.5.1 28 | mechanize==0.2.5 29 | mitmproxy==0.17 30 | multi-mechanize==1.2.0 31 | numpy==1.11.0 32 | parsimonious==0.6.2 33 | passlib==1.6.5 34 | pathtools==0.1.2 35 | Pillow==3.2.0 36 | plac==0.9.1 37 | poster==0.8.1 38 | prompt-toolkit==1.0.0 39 | pyasn1==0.1.9 40 | pycparser==2.14 41 | Pygments==2.1.3 42 | pyOpenSSL==16.0.0 43 | pyparsing==2.1.4 44 | pyperclip==1.5.27 45 | python-dateutil==2.5.3 46 | pytz==2016.4 47 | PyYAML==3.11 48 | requests==2.9.1 49 | scapy==2.3.2 50 | singledispatch==3.4.0.3 51 | six==1.10.0 52 | tornado==4.3 53 | Unirest==1.1.7 54 | urwid==1.3.1 55 | watchdog==0.8.3 56 | wcwidth==0.1.6 57 | Werkzeug==0.11.10 -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #coding=utf-8 3 | import codecs 4 | import os 5 | import sys 6 | try: 7 | from setuptools import setup,find_packages 8 | except: 9 | from distutils.core import setup 10 | '''import the setup lib''' 11 | 12 | 13 | ''' 14 |     定义一个read方法,用来读取目录下的长描述 15 |     我们一般是将README文件中的内容读取出来作为长描述,这个会在PyPI中你这个包的页面上展现出来, 16 |     你也可以不用这个方法,自己手动写内容即可, 17 |     PyPI上支持.rst格式的文件。暂不支持.md格式的文件,
.rst文件PyPI会自动把它转为HTML形式显示在你包的信息页面上。 18 | ''' 19 | def read(fname): 20 | return codecs.open(os.path.join(os.path.dirname(__file__), fname)).read() 21 | NAME = "FriedRing" 22 | ''' 23 | 名字,一般放你包的名字即可 24 | ''' 25 | PACKAGES = find_packages(include=[ 26 | "FriedRing", "FriedRing.*" 27 | ]) 28 | ''' 29 | 包含的包,可以多个,这是一个列表 30 | ''' 31 | DESCRIPTION = "this is a FriedRing package for get http request and response." 32 | ''' 33 | 关于这个包的描述 34 | ''' 35 | LONG_DESCRIPTION = read("README.md") 36 | ''' 37 | 参见read方法说明 38 | ''' 39 | KEYWORDS = "FriedRing python package" 40 | ''' 41 | 关于当前包的一些关键字,方便PyPI进行分类。 42 | ''' 43 | AUTHOR = "CrissChan" 44 | 45 | AUTHOR_EMAIL = "can101208@gmail.com" 46 | ''' 47 | 作者的邮件地址 48 | ''' 49 | URL = "http://blog.csdn.net/crisschan" 50 | ''' 51 | 你这个包的项目地址,如果有,给一个吧,没有你直接填写在PyPI你这个包的地址也是可以的 52 | ''' 53 | VERSION = "2.0.6" 54 | ''' 55 | 当前包的版本,这个按你自己需要的版本控制方式来 56 | ''' 57 | LICENSE = "MIT" 58 | ''' 59 | 授权方式,我喜欢的是MIT的方式,你可以换成其他方式 60 | ''' 61 | REQUIREMENTS = [i.strip() for i in open("requirement.txt").readlines()] 62 | 63 | ''' 64 | this grabs the requirements from requirements.txt 65 | ''' 66 | setup( 67 | name = NAME, 68 | version = VERSION, 69 | description = DESCRIPTION, 70 | long_description = LONG_DESCRIPTION, 71 | install_requires=REQUIREMENTS, 72 | classifiers=[ 73 | "License :: OSI Approved :: MIT License", 74 | "Development Status :: 5 - Production/Stable", 75 | "Environment :: Console", 76 | "Environment :: Console :: Curses", 77 | "Operating System :: MacOS :: MacOS X", 78 | "Operating System :: POSIX", 79 | "Programming Language :: Python", 80 | "Programming Language :: Python :: 2.7", 81 | "Programming Language :: Python :: Implementation :: CPython", 82 | "Programming Language :: Python :: Implementation :: PyPy", 83 | "Topic :: Internet", 84 | "Topic :: Internet :: WWW/HTTP", 85 | "Topic :: Software Development :: Testing" 86 | ], 87 | 88 | keywords = KEYWORDS, 89 | author = AUTHOR, 90 | author_email = AUTHOR_EMAIL, 91 | url = URL, 92 | license = LICENSE, 93 | packages = PACKAGES, 94 | include_package_data=True, 95 | zip_safe=True, 96 | entry_points={ 97 | 'console_scripts': [ 98 | "fr = FriedRing.fr:main" 99 | ] 100 | }, 101 | # scripts=["scripts/test.py"],scripts表示将该文件放到 Python的Scripts目录下,可以直接用 102 | ) 103 | ## 把上面的变量填入了一个setup()中即可。 --------------------------------------------------------------------------------