搭建HttpServer测试工具

未来已来2018-09-12 13:10

作者:马涛


前言

工欲善其事必先利其器,测试过程中,希望流程或数据能够按照我们设计的用例执行,所以自己写HttpServer工具可以省事不少!


目的

为了解决Outlook账号能够绕过OAuth登录,直接使用Exchange协议登录。


问题

以下有两个问题需要解决:

  1. 目前我们默认Outlook账号是使用OAuth登录,那么服务器配置文件是使用IMAP协议,本次功能是需要测试EXchange协议,所以就需要想办法绕过OAuth。这是今天主要讲的一个方法,本地搭建httpServer解决。
  2. 客户端默认访问Host:protocol.mail.163.com来获取SMPT、IMAP配置的,而我们需要使用EXchange协议,因为protocol.mail.163.com下的配置是线上配置,所以当然不可以修改线上。只能用测试服,测试服已经配置可以使用EXchange协议登录,问题是怎么能让客户端访问到测试服:protocolquey.hztest.mail.163.com


方法

  1. 手动搭建简单的 HttpServer,绕过OAuth登录(本次着重写的方法)
  2. 在Fiddler中使用FiddlerScript,修改脚本内容,对protocol.mail.163.com、protocolquey.hztest.mail.163.com 这两个Host做判断映射。(本次提出,后期研究,之前改过脚本一直无法顺利执行,所以换为方法1)


步骤

  • 抓包获取请求
  • HttpServer脚本
  • 配置host


抓包获取请求

  1. 工具:Fiddler
  2. 请求:每次在程序启动时,会发出这样一个请求。
    http://update.client.163.com/apptrack/confinfo/searchbyappid.do?appid=10&appver=3.4.2
    
  3. 返回Json:
    {
     "code": 200,
     "error": null,
     "conf": {
         "ContactMerge": {
             "enable": true
         },
         "festivals": {
             "tag": "20170406",
             "md5": "ecb75195f787ef08bebabab00d069ca8",
             "url": "http://nos.netease.com/mailyxpublic/master/festival.ics"
         },
         "hotmailOAuth": {
             "useOAuth": true,
             "authType": 3
         },
         "gmailOAuth": {
             "useOAuth": true,
             "authType": 3
         },
         "SkinSwitch": {
             "enable": true
         },
         "VIPClub": true
     }
    }
    
    字段hotmailOAuth内的useOAuth目前返回为true,告诉客户端目前可以使用OAuth登录。所有下面脚本的思路很简单,就是:1、拿到这一串儿Json;2、然后将以上useOAuth字段value改为''false'';3、让客户端拿到我们修改后的配置。

HttpServer脚本

import sys
import BaseHTTPServer

class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        """Respond to a GET request."""
        self.json = '{"code":200,"error":null,"conf":{"ContactMerge":{"enable":true},"festivals":{"tag":"20170406","md5":"ecb75195f787ef08bebabab00d069ca8","url":"http://nos.netease.com/mailyxpublic/master/festival.ics"},"hotmailOAuth":{"useOAuth":false,"authType":3},"gmailOAuth":{"useOAuth":true,"authType":3},"SkinSwitch":{"enable":true},"VIPClub":true}}'
        self.error_json = '{"error": "404", "code": 404}'
        self.request_version = 'HTTP/1.1'
        self.send_response(200)
        self.send_header('Content-Type', 'application/json')
        if self.path == '/apptrack/confinfo/searchbyappid.do?appid=10&appver=3.4.2':
            self.send_header('Content-Length', str(len(self.json)))
            self.end_headers()
            self.wfile.write(self.json)
        else:
            self.send_header('Content-Length', str(len(self.error_json)))
            self.end_headers()
            self.wfile.write(self.error_json)

if __name__ == '__main__':
    server = BaseHTTPServer.HTTPServer(('', 80), RequestHandler)
    sys.stderr.write('Serving on port http://localhost:80 ...\n')
    server.serve_forever()

我们用到了BaseHTTPServer这个模块,BaseHTTPServer 这个模块提供了两个类让开发实现http server,分别是:HTTPServer 和BaseHTTPRequestHandler。所以通常不直接使用BaseHTTPServer,而是使用这两个类来实现。


【HTTPServer】

HTTPServer 继承了 SocketServer.BaseServer, 主要功能是:创建和监听socket, 把请求转发给handler去处理。主要工作就是在BaseHTTPHandler中处理。 在代码里可以看到这句:

server = BaseHTTPServer.HTTPServer(('', 80), RequestHandler)

监听http请求的80端口,然后把请求转发给handler(这里就是RequestHandler)

【BaseHTTPRequestHandler】

BaseHTTPRequestHandler类,把和请求有关的信息都分装成了自己的实例变量,可以再子类中直接使用。代码里如: 

    if self.path == '/apptrack/confinfo/searchbyappid.do?appid=10&appver=3.4.2':
        self.send_header('Content-Length', str(len(self.json)))
        self.end_headers()
        self.wfile.write(self.json)
    else:
        self.send_header('Content-Length', str(len(self.error_json)))
        self.end_headers()
        self.wfile.write(self.error_json)

以上就在判断,如果这个请求是 self.path路径的话,就对该请求做处理,返回self.json:

self.json =
{
    "code": 200,
    "error": null,
    "conf": {
        "ContactMerge": {
            "enable": true
        },
        "festivals": {
            "tag": "20170406",
            "md5": "ecb75195f787ef08bebabab00d069ca8",
            "url": "http://nos.netease.com/mailyxpublic/master/festival.ics"
        },
        "hotmailOAuth": {
            "useOAuth": false,
            "authType": 3
        },
        "gmailOAuth": {
            "useOAuth": true,
            "authType": 3
        },
        "SkinSwitch": {
            "enable": true
        },
        "VIPClub": true
    }
}

以上Json就是我们需要的返回的数据。其中这里包括了我们想要修改的字段:"useOAuth”:false


配置host

在你的本地配置host:

127.0.0.1 update.client.163.com

然后运行http_server.py文件,本地就建立了一个简单的http服务。

» python http_server.py
Serving on port http://localhost:80 ...
127.0.0.1 - - [29/Jan/2018 14:02:16] "GET /apptrack/confinfo/searchbyappid.do?appid=11&appver=2.2.1 HTTP/1.1" 200 -
127.0.0.1 - - [29/Jan/2018 14:02:17] "GET /apptrack/overseas/getConf.do?appid=11&appver=2.2.1 HTTP/1.1" 200 -
127.0.0.1 - - [29/Jan/2018 14:02:17] "GET /apptrack/confinfo/searchbyappid.do?appid=11&appver=2.2.1 HTTP/1.1" 200 -
127.0.0.1 - - [29/Jan/2018 14:02:17] "GET /apptrack/overseas/getConf.do?appid=11&appver=2.2.1 HTTP/1.1" 200 -

实例

本地未开启HttpServer之前,通过OAuth登录:

本地已开启HttpServer之后,绕过OAuth登录:


参考文献:

https://docs.python.org/2/library/basehttpserver.html


本文来自网易实践者社区,经作者马涛授权发布