PageRenderTime 45ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/httxlib/httxoptions.py

https://code.google.com/
Python | 377 lines | 240 code | 17 blank | 120 comment | 3 complexity | 5e7343be8e2018fd1352b8b3dbc81984 MD5 | raw file
Possible License(s): GPL-3.0
  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. Module that implements the domain wide options that connecting objects can share
  33. A set of options apply to a HttxManager and all pending objects.
  34. If a L{HttxManager} is cloned, it can be cloned sharing the options or not. If the options
  35. are shared, so will be the cookies, compression schemes allowed, username and passwords,
  36. certificate files.
  37. If the options are not shared the new L{HttxManager} will be completely separate from
  38. the original.
  39. Since options can be directly instantiated by L{HttxNetLocation} and L{HttxConnection}, the
  40. same logic applies on cloning
  41. @var proxydefaults: If True try to automatically find and use the system
  42. (via environment variables, registry or others) defined proxies
  43. @type proxydefault: bool (Default: False)
  44. '''
  45. from copy import deepcopy
  46. from httxauthcache import HttxAuthCache
  47. from httxcertificates import HttxCertKeyManager, HttxCertReqManager, HttxCACertManager
  48. from httxcookiejar import HttxCookieJar
  49. from httxcompressionset import HttxCompressionSet
  50. from httxobject import HttxObject
  51. from httxpassmanager import HttxPassManager
  52. proxydefaults = False
  53. class HttxOption(object):
  54. '''
  55. A class representing an individual option.
  56. The class is implemented as a descriptor. The class locks access
  57. automatically on access (read/write) to the storage by using the
  58. lock from the instance object accessing the option.
  59. @ivar name: Name of the option
  60. @type name: str
  61. @ivar defvalue: Default value of the option
  62. @type defvalue: Opaque type. Each option may have different types
  63. @ivar storage: Actual storage for the option value(s) on a per
  64. instance (descriptor) basis
  65. @type storage: dict
  66. '''
  67. __slots__ = ['name', 'defvalue', 'storage', '__weakref__']
  68. def __init__(self, name, defvalue):
  69. '''
  70. Constructor.
  71. Initializes the member variables
  72. @param name: Name of the option
  73. @type name: str
  74. @param defvalue: Default value of the option
  75. @type defvalue: Opaque type. Each option may have different types
  76. '''
  77. self.name = name
  78. self.defvalue = defvalue
  79. self.storage = dict()
  80. def __get__(self, instance, owner):
  81. '''
  82. Descriptor get
  83. @param instance: instance that wants to access the storage
  84. @type instance: object instance
  85. @param owner: Not used but needed for descriptor implementation
  86. @type owner: Not used
  87. @return: the value of the requested option (the default value if
  88. the option had not been set yet
  89. @rtype: Opaque type. Each option may have different types
  90. '''
  91. with instance.lock:
  92. # XXX is deepcopy really needed?
  93. return self.storage.setdefault(instance, deepcopy(self.defvalue))
  94. def __set__(self, instance, value):
  95. '''
  96. Descriptor set
  97. @param instance: instance that wants to access the storage
  98. @type instance: object instance
  99. @param value: Value to set
  100. @type value: Opaque type. Each option may have different types
  101. '''
  102. with instance.lock:
  103. # XXX is deepcopy really needed?
  104. self.storage[instance] = deepcopy(value)
  105. class HttxOptionsMeta(type):
  106. '''
  107. Metaclass for L{HttxOptions} to initialize the list of options
  108. on instantiation
  109. '''
  110. def __new__(mcs, name, bases, dict):
  111. '''
  112. On L{HttxOptions} instantiation the options present in the
  113. class variable I{defoptions} are added to the dictionary of the
  114. instance to start them with the default value
  115. '''
  116. for defoption in dict['defoptions']:
  117. dict[defoption.name] = defoption
  118. return type.__new__(mcs, name, bases, dict)
  119. class HttxOptions(HttxObject):
  120. '''
  121. Class implementing a set of options per domain to be held by HttxLib
  122. connecting objects like L{HttxManager}, L{HttxNetLocation} and L{HttxConnection}
  123. @ivar defoptions: list of L{HttxOption} definitions
  124. @type defoptions: tuple
  125. - timeout
  126. Default value: 15 seconds
  127. Timeout for network operations
  128. - keepalive
  129. Default value: 90 seconds
  130. Timeout for HTTP keepalive
  131. - connkeepalive
  132. Default value: True
  133. Timeout for HTTP Send the 'Connection: Keep-Alive' header
  134. - httpsconnect
  135. Default value: True
  136. Use CONNECT for proxying HTTPS
  137. - httpconnect
  138. Default value: False
  139. Use CONNECT for proxying HTTP
  140. - sendfullurl
  141. Default value: False
  142. HTTP 1.1 allows this, but some servers may crash if they receive the full url
  143. - proxy
  144. Default value: None
  145. A dictionary of scheme:url tuples can be set to use proxy servers
  146. scheme can be * for any scheme or have the http/https values
  147. - compression
  148. Default value: False
  149. If True the body of a POST will be sent compressed. This is supported
  150. by very few servers
  151. - compmethod
  152. Default value: HttxCompressionSet('gzip')
  153. Method to use when sending compressed requests
  154. - decompression
  155. Default value: True
  156. Request compressed answers and decompress the body of an HTTP answer
  157. - autodecompression
  158. Default value: True
  159. Even if compression was not requested, decompressed answers that
  160. contain a compressed body
  161. - decompmethod
  162. Default value: HttxCompressionSet('gzip', 'deflate', 'bzip2')
  163. Methods to use when requesting compressed answers
  164. - useragent
  165. Default value: ''
  166. Sets the user agent header value
  167. - redirect
  168. Default value: True
  169. Allows or disallows redirection support
  170. - externalredirect
  171. Default value: True
  172. Allows or disallows external redirection support
  173. - maxredirect
  174. Default value: 3
  175. Maximum number of redirects to follow
  176. - rfc2616postredir
  177. Default value: True
  178. If a redir after a post as specified in RFC 2616 should be followed
  179. - cookies
  180. Default value: True
  181. Allows or disallows cookie support
  182. - cookiejar
  183. Default value: HttxCookieJar
  184. For internal storage of cookies in a HttxOptions domain
  185. - auth
  186. Default value: True
  187. Allows or disallows authentication support
  188. - authuser
  189. Default value: True
  190. Allows or disallows www authentication support
  191. - authproxy
  192. Default value: True
  193. Allows or disallows proxy authentication support
  194. - authhandler
  195. Default value: None
  196. It can hold a reference to a function (or callable object) that accepts
  197. the following parameters:
  198. - authhandler(authurl, authschemes, authcachedata)
  199. authurl is the url that generated the authorization request
  200. authschemes is a dictionary. The keys contain the names of the
  201. authentication schemes the server supports. Each value is a dictionary
  202. or paramaters (ex: realm='My AuthRealm', where realm is the key and
  203. 'My AuthRealm' is the associated value)
  204. - The function has to return a tuple:
  205. (authscheme, authanswer, authcachedata) If either authscheme or authanswer
  206. happen to be None then the handler cannot handle authentication)
  207. authscheme contains the chosen scheme from the varios that may have
  208. been presented to the handler
  209. authanswer contains the answer to the authentication challenge
  210. authcachedata is a value that the handler may wish to store and will receive
  211. on next authentication challenges for the same url. If None is returned
  212. nothing will be stored
  213. - passmanager
  214. Default value: HttxPassManager
  215. Internal storage of username/password credentials for realm and urls
  216. - authcache
  217. Default value: HttxAuthCache
  218. Internal storage of authentication answers for reuse
  219. - certkeyfile
  220. Default value: HttxCertKeyManager
  221. Internal storage of certificate/private key pair of path to files
  222. containing the certificates and private keys for client
  223. validation
  224. Being empty at the beginning, no files will be used in client validation
  225. - certreq
  226. Default value: HttxCertReqManager
  227. Internal storage of requirement of validation for server certificates
  228. Being empty at the beginning, no validation will be performed
  229. - cacert
  230. Default value: HttxCACertManager
  231. Internal storage of root (chain of) certificates(s) for server
  232. certificate validation.
  233. Being empty at the beginning, no validation can be performed
  234. '''
  235. defoptions = (
  236. HttxOption('timeout', 15),
  237. HttxOption('keepalive', 90),
  238. HttxOption('connkeepalive', True),
  239. HttxOption('httpsconnect', True),
  240. HttxOption('httpconnect', False),
  241. HttxOption('sendfullurl', False),
  242. HttxOption('proxy', None),
  243. HttxOption('compression', False),
  244. HttxOption('compmethod', HttxCompressionSet('gzip')),
  245. HttxOption('decompression', True),
  246. HttxOption('autodecompression', True),
  247. HttxOption('decompmethods', HttxCompressionSet('gzip', 'deflate', 'bzip2')),
  248. HttxOption('useragent', ''),
  249. HttxOption('redirect', True),
  250. HttxOption('externalredirect', True),
  251. HttxOption('maxredirects', 3),
  252. HttxOption('rfc2616postredir', True),
  253. HttxOption('cookies', True),
  254. HttxOption('cookiejar', HttxCookieJar()),
  255. HttxOption('auth', True),
  256. HttxOption('authuser', True),
  257. HttxOption('authproxy', True),
  258. HttxOption('authhandler', None),
  259. HttxOption('passmanager', HttxPassManager()),
  260. HttxOption('authcache', HttxAuthCache()),
  261. HttxOption('certkeyfile', HttxCertKeyManager()),
  262. HttxOption('certreq', HttxCertReqManager()),
  263. HttxOption('cacert', HttxCACertManager()),
  264. )
  265. __metaclass__ = HttxOptionsMeta
  266. def __init__(self):
  267. '''
  268. Constructor. It delegates construction to the base class
  269. L{HttxObject}
  270. '''
  271. HttxObject.__init__(self)
  272. def __deepcopy__(self, memo):
  273. '''
  274. Deepcopy support.
  275. @param memo: standard __deepcopy__ parameter to avoid circular references
  276. @type memo: dict
  277. @return: a cloned object
  278. @rtype: L{HttxOptions}
  279. '''
  280. clone = self.__class__()
  281. # lock is un(deep)copyable
  282. # copy the attributes we want: options
  283. for defoption in self.defoptions:
  284. setattr(clone, defoption.name, deepcopy(getattr(self, defoption.name)))
  285. return clone
  286. def clone(self):
  287. '''
  288. Alias for deepcopy, for consistency with the rest of objects
  289. @return: a cloned object
  290. @rtype: L{HttxOptions}
  291. '''
  292. return deepcopy(self)
  293. def update(self, **kwargs):
  294. '''
  295. Given a set of keyword arguments update the value of options
  296. @param kwargs: keyword args
  297. @type kwargs: dict
  298. '''
  299. for option in kwargs:
  300. if hasattr(self, option):
  301. setattr(self, option, kwargs[option])