Changeset 315708 in indico
- Timestamp:
- 08/23/11 15:38:51 (21 months ago)
- Branches:
- master, hello-world-walkthrough, ipv6, v0.98-series, v0.98.2, v0.98.3, v0.98b2, v0.99, 051b2622c51afb171a1dedb46a0df4fbb0cbd02e, 0da0c1403bae8e51d8229f460181c71b9e6dda72
- Children:
- fcdc60
- Parents:
- 1ea4c5
- git-author:
- Adrian Moennich <jerome.ernst.monnich@…> (05/12/11 14:06:08)
- git-committer:
- Jose Benito <jose.benito.gonzalez@…> (08/23/11 15:38:51)
- Location:
- indico/web/http_api
- Files:
-
- 2 edited
-
cache.py (modified) (2 diffs)
-
handlers.py (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
indico/web/http_api/cache.py
r9b51c4 r315708 20 20 from MaKaC.common.cache import MultiLevelCacheEntry, MultiLevelCache 21 21 import datetime 22 import hashlib 22 23 import time 23 24 import os … … 51 52 return ['requests'] 52 53 53 def _generateKey(self, path, qdata):54 queryHash = hash(frozenset((key, frozenset(values)) for key, values in qdata.iteritems()))55 return '.'.join(map(str, (hash(path), queryHash)))54 def cacheObject(self, key, obj): 55 key = hashlib.sha256(key).hexdigest() 56 return super(RequestCache, self).cacheObject(key, obj) 56 57 57 def cacheObject(self, path, qdata, obj): 58 return super(RequestCache, self).cacheObject(self._generateKey(path, qdata), obj) 59 60 def loadObject(self, path, qdata): 61 return super(RequestCache, self).loadObject(self._generateKey(path, qdata)) 58 def loadObject(self, key): 59 key = hashlib.sha256(key).hexdigest() 60 return super(RequestCache, self).loadObject(key) 62 61 63 62 def isDirty(self, path, object): -
indico/web/http_api/handlers.py
r1ea4c5 r315708 28 28 import re 29 29 import time 30 import urllib 30 31 from urlparse import parse_qs 31 32 from ZODB.POSException import ConflictError … … 61 62 } 62 63 63 # Compile regexps64 # Compile url regexps 64 65 EXPORT_URL_MAP = dict((re.compile(pathRe), handlerFunc) for pathRe, handlerFunc in EXPORT_URL_MAP.iteritems()) 65 RE_REMOVE_EXTENSION = re.compile(r'\.(\w+)$') 66 # Remove the extension at the end or before the querystring 67 RE_REMOVE_EXTENSION = re.compile(r'\.(\w+)(?:$|(?=\?))') 68 69 70 def normalizeQuery(path, query, ts=None, remove=('timestamp', 'signature')): 71 """Normalize request path and query so it can be used for caching and signing 72 73 Returns a string consisting of path and sorted query string. 74 Dynamic arguments like signature and timestamp are removed from the query string. 75 """ 76 qdata = remove_lists(parse_qs(query)) 77 if remove: 78 for key in remove: 79 qdata.pop(key, None) 80 if ts is not None: 81 qdata['timestamp'] = ts 82 sortedQuery = sorted(qdata.items(), key=lambda x: x[0].lower()) 83 if sortedQuery: 84 return '%s?%s' % (path, urllib.urlencode(sortedQuery)) 85 else: 86 return path 66 87 67 88 … … 72 93 candidates = [] 73 94 for i in xrange(-1, 2): 74 h = hmac.new(key, '%s?%s&%d' %(path, query, ts + i), hashlib.sha1)95 h = hmac.new(key, normalizeQuery(path, query, ts + i), hashlib.sha1) 75 96 candidates.append(h.hexdigest()) 76 97 if signature not in candidates: … … 172 193 def handler(req, **params): 173 194 path, query = req.URLFields['PATH_INFO'], req.URLFields['QUERY_STRING'] 174 # Extract HMAC signature175 signature = None176 m = re.search(r'&([0-9a-fA-F]{40})$', query)177 if m:178 signature = m.group(1).lower()179 query = query[:-41]180 181 195 # Parse the actual query string 182 196 qdata = parse_qs(query) 183 no_cache = get_query_parameter(qdata, ['nc', 'nocache'], 'no') == 'yes'184 197 185 198 dbi = DBMgr.getInstance() 186 199 dbi.startRequest() 187 200 188 # Copy qdata for the cache key189 qdata_copy = dict(qdata)190 201 cache = RequestCache(HelperMaKaCInfo.getMaKaCInfoInstance().getAPICacheTTL()) 191 202 203 apiKey = get_query_parameter(qdata, ['ak', 'apikey'], None) 204 signature = get_query_parameter(qdata, ['signature']) 205 no_cache = get_query_parameter(qdata, ['nc', 'nocache'], 'no') == 'yes' 192 206 pretty = get_query_parameter(qdata, ['p', 'pretty'], 'no') == 'yes' 193 apiKey = get_query_parameter(qdata, ['ak', 'apikey'], None)194 207 onlyPublic = get_query_parameter(qdata, ['op', 'onlypublic'], 'no') == 'yes' 195 208 … … 210 223 # Get rid of API key in cache key if we did not impersonate a user 211 224 if ak and aw.getUser() is None: 212 qdata_copy.pop('ak', None) 213 qdata_copy.pop('apikey', None) 225 cache_key = normalizeQuery(path, query, remove=('ak', 'apiKey', 'signature', 'timestamp')) 226 else: 227 cache_key = normalizeQuery(path, query, remove=('signature', 'timestamp')) 214 228 215 229 obj = None 216 230 add_to_cache = True 217 cache_ path = RE_REMOVE_EXTENSION.sub('', path)231 cache_key = RE_REMOVE_EXTENSION.sub('', cache_key) 218 232 if not no_cache: 219 obj = cache.loadObject(cache_ path, qdata_copy)233 obj = cache.loadObject(cache_key) 220 234 if obj is not None: 221 235 result, complete = obj.getContent() … … 226 240 result, complete = func(dbi, aw, qdata, *args) 227 241 if result is not None and add_to_cache: 228 cache.cacheObject(cache_ path, qdata_copy, (result, complete))242 cache.cacheObject(cache_key, (result, complete)) 229 243 except HTTPAPIError, e: 230 244 error = e
Note: See TracChangeset
for help on using the changeset viewer.
