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

Source Code for Module httxlib.httxutil

  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  import sys 
 31  if sys.platform == 'win32': 
 32      from time import clock as tclock 
 33  else: 
 34      from time import time as tclock 
 35   
 36   
 37  ################################################################################ 
 38  # 
 39  # NOTES: 
 40  #  HttxLib is distributed under the GPLv3 as noted above. 
 41  # 
 42  #  But the functions below have been extracted from the 
 43  #  httplib module of Python 2.6.5 with no modification 
 44  # 
 45  #  The Python Software Foundation (PSF) License Version 2 applies to them 
 46  # 
 47  #  Hereby a copy of the PSF License Version 2 
 48  # 
 49  # PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 
 50  # -------------------------------------------- 
 51  #  
 52  # 1. This LICENSE AGREEMENT is between the Python Software Foundation 
 53  # ("PSF"), and the Individual or Organization ("Licensee") accessing and 
 54  # otherwise using this software ("Python") in source or binary form and 
 55  # its associated documentation. 
 56  #  
 57  # 2. Subject to the terms and conditions of this License Agreement, PSF 
 58  # hereby grants Licensee a nonexclusive, royalty-free, world-wide 
 59  # license to reproduce, analyze, test, perform and/or display publicly, 
 60  # prepare derivative works, distribute, and otherwise use Python 
 61  # alone or in any derivative version, provided, however, that PSF's 
 62  # License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 
 63  # 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights 
 64  # Reserved" are retained in Python alone or in any derivative version  
 65  # prepared by Licensee. 
 66  #  
 67  # 3. In the event Licensee prepares a derivative work that is based on 
 68  # or incorporates Python or any part thereof, and wants to make 
 69  # the derivative work available to others as provided herein, then 
 70  # Licensee hereby agrees to include in any such work a brief summary of 
 71  # the changes made to Python. 
 72  #  
 73  # 4. PSF is making Python available to Licensee on an "AS IS" 
 74  # basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR 
 75  # IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND 
 76  # DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS 
 77  # FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT 
 78  # INFRINGE ANY THIRD PARTY RIGHTS. 
 79  #  
 80  # 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 
 81  # FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS 
 82  # A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, 
 83  # OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 
 84  #  
 85  # 6. This License Agreement will automatically terminate upon a material 
 86  # breach of its terms and conditions. 
 87  #  
 88  # 7. Nothing in this License Agreement shall be deemed to create any 
 89  # relationship of agency, partnership, or joint venture between PSF and 
 90  # Licensee.  This License Agreement does not grant permission to use PSF 
 91  # trademarks or trade name in a trademark sense to endorse or promote 
 92  # products or services of Licensee, or any third party. 
 93  #  
 94  # 8. By copying, installing or otherwise using Python, Licensee 
 95  # agrees to be bound by the terms and conditions of this License 
 96  # Agreement. 
 97  #  
 98  ############################################################################### 
 99  ''' 
100  Utility functions for http header parsing and digest authentication 
101  extracted from httplib (Python 2.6.5) for convenience. 
102   
103  Rather than importing them from the library and risking a change in 
104  name or signature, a local copy will help avoiding trouble 
105  ''' 
106   
107  from hashlib import sha1, md5 
108  from random import randrange 
109  from time import ctime 
110   
111   
112 -def parse_keqv_list(l):
113 """Parse list of key=value strings where keys are not duplicated.""" 114 parsed = {} 115 for elt in l: 116 k, v = elt.split('=', 1) 117 if v[0] == '"' and v[-1] == '"': 118 v = v[1:-1] 119 parsed[k] = v 120 return parsed
121 122
123 -def parse_http_list(s):
124 """Parse lists as described by RFC 2068 Section 2. 125 126 In particular, parse comma-separated lists where the elements of 127 the list may include quoted-strings. A quoted-string could 128 contain a comma. A non-quoted string could have quotes in the 129 middle. Neither commas nor quotes count if they are escaped. 130 Only double-quotes count, not single-quotes. 131 """ 132 res = [] 133 part = '' 134 135 escape = quote = False 136 for cur in s: 137 if escape: 138 part += cur 139 escape = False 140 continue 141 if quote: 142 if cur == '\\': 143 escape = True 144 continue 145 elif cur == '"': 146 quote = False 147 part += cur 148 continue 149 150 if cur == ',': 151 res.append(part) 152 part = '' 153 continue 154 155 if cur == '"': 156 quote = True 157 158 part += cur 159 160 # append last part 161 if part: 162 res.append(part) 163 164 return [part.strip() for part in res]
165 166
167 -def get_cnonce(nonce_count, nonce):
168 dig = sha1("%s:%s:%s:%s" % (nonce_count, nonce, ctime(), randombytes(8))).hexdigest() 169 cnonce = dig[:16] 170 171 return cnonce
172 173
174 -def get_algorithm_impls(algorithm):
175 # algorithm should be case-insensitive according to RFC2617 176 algorithm = algorithm.upper() 177 # lambdas assume digest modules are imported at the top level 178 if algorithm == 'MD5': 179 H = lambda x: md5(x).hexdigest() 180 elif algorithm == 'SHA': 181 H = lambda x: sha1(x).hexdigest() 182 # XXX MD5-sess 183 KD = lambda s, d: H('%s:%s' % (s, d)) 184 return H, KD
185 186
187 -def randombytes(n):
188 L = [chr(randrange(0, 256)) for i in range(n)] 189 return ''.join(L)
190