Package httxlib :: Module httxrequest
[hide private]
[frames] | no frames]

Source Code for Module httxlib.httxrequest

  1  #!/usr/bin/env python 
  2  # -*- coding: latin-1; py-indent-offset:4 -*- 
  3  ################################################################################ 
  4  #  
  5  # This file is part of HttxLib 
  6  # 
  7  # HttxLib is an HTTP(s) Python library suited multithreaded/multidomain 
  8  # applications 
  9  # 
 10  # Copyright (C) 2010-2011 Daniel Rodriguez (aka Daniel Rodriksson) 
 11  # Copyright (C) 2011 Sensible Odds Ltd 
 12  # 
 13  # You can learn more and contact the author at: 
 14  # 
 15  #    http://code.google.com/p/httxlib/ 
 16  # 
 17  # HttxLib is free software: you can redistribute it and/or modify 
 18  # it under the terms of the GNU General Public License as published by 
 19  # the Free Software Foundation, either version 3 of the License, or 
 20  # (at your option) any later version. 
 21  # 
 22  # HttxLib is distributed in the hope that it will be useful, 
 23  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 24  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 25  # GNU General Public License for more details. 
 26  # 
 27  # You should have received a copy of the GNU General Public License 
 28  # along with HttxLib. If not, see <http://www.gnu.org/licenses/>. 
 29  # 
 30  ################################################################################ 
 31  ''' 
 32  urllib2 compatible Request object with additional functionality 
 33   
 34  It can therefore be supplied to urllib2 objects (like a CookieJar) 
 35  ''' 
 36   
 37  from urllib2 import Request 
 38  from urlparse import urlparse, urlsplit 
39 40 41 -class HttxRequest(Request):
42 ''' 43 A subclass of urllib2 Request to retain compatibility and make it usable 44 for cookies and whatever may be needed 45 46 @ivar parsed: It holds the result of the urlsplit(url) done in the constructor 47 for practical purposes 48 @type parsed: namedtuple result of urlsplit (check the Python docs) 49 ''' 50
51 - def __init__(self, url, data=None, headers=None, origin_req_host=None, unverifiable=False):
52 ''' 53 Constructor. It delegates construction to the base class 54 Request and initializes the member variables 55 56 It performs an additional call of Request.get_type and Request.get_host 57 to ensure that the Request object is properly initialized. Because this 58 is done by the urllib2 library, but we are just using the request 59 60 @param url: url to be requested in the HTTP request 61 @type url: str 62 @param data: data for the HTTP request body (which enforces a POST) 63 @type data: str 64 @param headers: dictionary of header name/header value 65 @type headers: dict 66 @param origin_req_host: request host of the origin transaction as per 67 RFC 2965 - Host name or IP address of the host 68 @type origin_req_host: str 69 @param unverifiable: if the request was not verified/requested by the end 70 user and it is rather automatic (redirection, download 71 of a picture inside a web page) - RFC 2965 72 @type unverifiable: bool 73 ''' 74 if headers is None: 75 headers = dict() 76 Request.__init__(self, url, data, headers, origin_req_host, unverifiable) 77 self.parsed = urlsplit(url) 78 # Done to force split of the url fields inside the request 79 self.get_type() 80 self.get_host()
81 82 83 @property
84 - def allheaders(self):
85 ''' 86 Property to return all the headers to be sent in a request 87 88 urllib2 distinguishes amongst normal headers and headers that will 89 not be used if the original request is redirected 90 91 Therefore it is impossible to request all headers in just one call 92 93 Although Request has a utility function, it returns a list of tuples 94 rather than a dictionary 95 96 This property returns a dictionary 97 ''' 98 hdrs = self.unredirected_hdrs.copy() 99 hdrs.update(self.headers) 100 return hdrs
101 102 103 @property
104 - def method(self):
105 ''' 106 Property to have a handy alias for Request.get_method 107 ''' 108 return self.get_method()
109 110
111 - def ispost(self):
112 ''' 113 Utility function to avoid cluttering external code with 114 string comparisons 115 116 @return: if the request will be a POST request 117 @rtype: bool 118 ''' 119 return self.get_method() == 'POST'
120 121
122 - def isget(self):
123 ''' 124 Utility function to avoid cluttering external code with 125 string comparisons 126 127 @return: if the request will be a GET request 128 @rtype: bool 129 ''' 130 return self.get_method() == 'GET'
131 132 133 @property
134 - def scheme(self):
135 ''' 136 Property to have a handy alias for Request.get_type or 137 parsed.scheme 138 ''' 139 # return self.get_type() 140 return self.parsed.scheme
141 142 143 @property
144 - def netloc(self):
145 ''' 146 Property to have a handy alias for Request.get_host or 147 parsed.netloc 148 ''' 149 # return self.get_host() 150 return self.parsed.netloc
151 152 153 @property
154 - def body(self):
155 ''' 156 Property to have a handy alias for Request.get_data 157 ''' 158 return self.get_data()
159 160
161 - def clone(self, url=None):
162 ''' 163 Clone a request with a change of url to support redirection 164 165 By using the normal/unredirected header separation in Request it is 166 easy to clone for a redirection by only supplying the new headers 167 to the class 168 169 @param url: url to redirect to if needed. Default of None for no 170 redirection 171 @type url: str|None 172 @return: a cloned object 173 @rtype: L{HttxRequest} 174 ''' 175 176 # The only non-cloned thing: unredirected_headers and this is possibly how it has to be 177 if not url: 178 url = self.get_full_url() 179 headers = self.allheaders 180 else: 181 headers = self.headers 182 183 return self.__class__(url, self.data, headers, self.origin_req_host, self.unverifiable)
184 185
186 - def __deepcopy__(self, memo):
187 ''' 188 Deepcopy support. 189 190 @param memo: standard __deepcopy__ parameter to avoid circular references 191 @type memo: dict 192 @return: a cloned object 193 @rtype: L{HttxRequest} 194 ''' 195 return self.clone()
196