python httplib相关

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 httplib
import base64

auth = 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值