python httplib相关

来源:互联网 发布:js分割字符串成数组 编辑:程序博客网 时间:2024/06/05 19:30

httplib库浅析

目录:/usr/lib64/python2.7
库依赖:

from array import array import os import re import socket from sys import py3kwarning from urlparse import urlsplit import warnings

行数: 1409
工作流程:

    (null)      |      | HTTPConnection()      v    Idle      |      | putrequest()      v    Request-started      |      | ( putheader() )*  endheaders()      v    Request-sent      |      | response = getresponse()      v    Unread-response   [Response-headers-read]      |\____________________      |                     |      | response.read()     | putrequest()      v                     v    Idle                  Req-started-unread-response                     ______/|                   /        |   response.read() |        | ( putheader() )*  endheaders()                   v        v       Request-started    Req-sent-unread-response                            |                            | response.read()                            v                          Request-sent

类目:

"HTTP" "HTTPResponse" "HTTPConnection""HTTPException" "NotConnected" "UnknownProtocol""UnknownTransferEncoding" "UnimplementedFileMode""IncompleteRead" "InvalidURL" "ImproperConnectionState""CannotSendRequest" "CannotSendHeader""ResponseNotReady""BadStatusLine""error" "responses"

关键类

HTTPConnection
初始化:

def __init__(self, host, port=None, strict=None,                 timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None):        self.timeout = timeout        self.source_address = source_address        self.sock = None        self._buffer = []        self.__response = None        self.__state = _CS_IDLE        self._method = None        self._tunnel_host = None        self._tunnel_port = None        self._tunnel_headers = {}        self._set_hostport(host, port)        if strict is not None:            self.strict = strict

评论:指定host&port即可。初始化时会设置一些对象属性,其中self._set_hostport(host, port)会对host和port进行解析,源码如下:

def _set_hostport(self, host, port):        if port is None:            i = host.rfind(':')            j = host.rfind(']')         # ipv6 addresses have [...]            if i > j:                try:                    port = int(host[i+1:])                except ValueError:                    if host[i+1:] == "":  # http://foo.com:/ == http://foo.com/                        port = self.default_port                    else:                        raise InvalidURL("nonnumeric port: '%s'" % host[i+1:])                host = host[:i]            else:                port = self.default_port            if host and host[0] == '[' and host[-1] == ']':                host = host[1:-1]        self.host = host        self.port = port

发送请求:

def request(self, method, url, body=None, headers={}):    """Send a complete request to the server."""    self._send_request(method, url, body, headers)def _send_request(self, method, url, body, headers):    # Honor explicitly requested Host: and Accept-Encoding: headers.    header_names = dict.fromkeys([k.lower() for k in headers])    skips = {}    if 'host' in header_names:        skips['skip_host'] = 1    if 'accept-encoding' in header_names:        skips['skip_accept_encoding'] = 1    self.putrequest(method, url, **skips)    if body is not None and 'content-length' not in header_names:        self._set_content_length(body)    for hdr, value in headers.iteritems():        self.putheader(hdr, value)    self.endheaders(body) 

评论:method和url由你请求的服务器提供的api决定,body和headers由你执行的动作决定。这里多说一句,我使用的服务器提供的api需要基本验证(Basic Authentication),这一步需要在headers上增加一个键值对,下面再详谈。

得到回应(对象):

def getresponse(self, buffering=False):    "Get the response from the server."    # if a prior response has been completed, then forget about it.    if self.__response and self.__response.isclosed():        self.__response = None    #    # if a prior response exists, then it must be completed (otherwise, we    # cannot read this response's header to determine the connection-close    # behavior)    #    # note: if a prior response existed, but was connection-close, then the    # socket and response were made independent of this HTTPConnection    # object since a new request requires that we open a whole new    # connection    #    # this means the prior response had one of two states:    #   1) will_close: this connection was reset and the prior socket and    #                  response operate independently    #   2) persistent: the response was retained and we await its    #                  isclosed() status to become true.    #    if self.__state != _CS_REQ_SENT or self.__response:        raise ResponseNotReady()    args = (self.sock,)    kwds = {"strict":self.strict, "method":self._method}    if self.debuglevel > 0:        args += (self.debuglevel,)    if buffering:        kwds["buffering"] = True;    response = self.response_class(*args, **kwds)    response.begin()    assert response.will_close != _UNKNOWN    self.__state = _CS_IDLE    if response.will_close:        # this effectively passes the connection to the response        self.close()    else:        # remember this, so we can tell when it is complete        self.__response = response    return response

base64库简介

Base64编码是一种“防君子不防小人”的编码方式。广泛应用于MIME协议,作为电子邮件的传输编码,生成的编码可逆,后一两位可能有“=”,生成的编码都是ascii字符。

优点:速度快,ascii字符,肉眼不可理解
缺点:编码比较长,非常容易被破解,仅适用于加密非关键信息的场合

执行服务器的基本验证信息需要进行base64编码转换。

项目实践(测试部分)

import httplibimport base64auth = base64.b64encode('lin'+ ':'+ '123') headers = {"Authorization": "Basic "+ auth} url = "http://192.168.222.128:8080/kie-server/services/rest/server"conn = httplib.HTTPConnection("192.168.222.128",8080)conn.request(method="GET", url=url,headers=headers)response = conn.getresponse()res = response.read()print res

结果:

(xcdw_env_new) [xcdw@localhost rule]$ python httptest.py <?xml version="1.0" encoding="UTF-8" standalone="yes"?><response type="SUCCESS" msg="Kie Server info">    <kie-server-info>        <capabilities>KieServer</capabilities>        <capabilities>BRM</capabilities>        <capabilities>BPM</capabilities>        <capabilities>BPM-UI</capabilities>        <capabilities>BRP</capabilities>        <location>http://192.168.222.128:8080/kie-server/services/rest/server</location>        <messages>            <content>Server KieServerInfo{serverId='tomcat-kieserver', version='6.5.0.Final', location='http://192.168.222.128:8080/kie-server/services/rest/server'}started successfully at Tue Dec 20 17:13:15 PST 2016</content>            <severity>INFO</severity>            <timestamp>2016-12-20T17:13:15.293-08:00</timestamp>        </messages>        <name>tomcat-kieserver</name>        <id>tomcat-kieserver</id>        <version>6.5.0.Final</version>    </kie-server-info></response>
0 0
原创粉丝点击