summaryrefslogtreecommitdiff
path: root/repoze/bfg/url.py
diff options
context:
space:
mode:
Diffstat (limited to 'repoze/bfg/url.py')
-rw-r--r--repoze/bfg/url.py72
1 files changed, 4 insertions, 68 deletions
diff --git a/repoze/bfg/url.py b/repoze/bfg/url.py
index 99b4cdabf..0c6031c26 100644
--- a/repoze/bfg/url.py
+++ b/repoze/bfg/url.py
@@ -1,11 +1,13 @@
""" Utility functions for dealing with URLs in repoze.bfg """
-import re
import urllib
from zope.component import queryMultiAdapter
from repoze.bfg.interfaces import IContextURL
+from repoze.bfg.traversal import TraversalContextURL
+from repoze.bfg.traversal import quote_path_segment
+
def model_url(model, request, *elements, **kw):
"""
Generate a string representing the absolute URL of the model (or
@@ -58,7 +60,6 @@ def model_url(model, request, *elements, **kw):
context_url = queryMultiAdapter((model, request), IContextURL)
if context_url is None:
# b/w compat for unit tests
- from repoze.bfg.traversal import TraversalContextURL
context_url = TraversalContextURL(model, request)
model_url = context_url()
@@ -68,7 +69,7 @@ def model_url(model, request, *elements, **kw):
qs = ''
if elements:
- suffix = '/'.join([_urlsegment(s) for s in elements])
+ suffix = '/'.join([quote_path_segment(s) for s in elements])
else:
suffix = ''
@@ -112,69 +113,4 @@ def urlencode(query, doseq=False):
return urllib.urlencode(newquery, doseq=doseq)
-_segment_cache = {}
-
-def _urlsegment(s):
- """ The bit of this code that deals with ``_segment_cache`` is an
- optimization: we cache all the computation of URL path segments in
- this module-scope dictionary with the original string (or unicode
- value) as the key, so we can look it up later without needing to
- reencode or re-url-quote it """
- result = _segment_cache.get(s)
- if result is None:
- if s.__class__ is unicode: # isinstance slighly slower (~15%)
- result = _url_quote(s.encode('utf-8'))
- else:
- result = _url_quote(s)
- # we don't need a lock to mutate _segment_cache, as the below
- # will generate exactly one Python bytecode (STORE_SUBSCR)
- _segment_cache[s] = result
- return result
-
-
-always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
- 'abcdefghijklmnopqrstuvwxyz'
- '0123456789' '_.-')
-_safemaps = {}
-_must_quote = {}
-
-def _url_quote(s, safe = '/'):
- """quote('abc def') -> 'abc%20def'
-
- Faster version of Python stdlib urllib.quote. See
- http://bugs.python.org/issue1285086 for more information.
-
- Each part of a URL, e.g. the path info, the query, etc., has a
- different set of reserved characters that must be quoted.
-
- RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax lists
- the following reserved characters.
-
- reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
- "$" | ","
-
- Each of these characters is reserved in some component of a URL,
- but not necessarily in all of them.
-
- By default, the quote function is intended for quoting the path
- section of a URL. Thus, it will not encode '/'. This character
- is reserved, but in typical usage the quote function is being
- called on a path where the existing slash characters are used as
- reserved characters.
- """
- cachekey = (safe, always_safe)
- try:
- safe_map = _safemaps[cachekey]
- if not _must_quote[cachekey].search(s):
- return s
- except KeyError:
- safe += always_safe
- _must_quote[cachekey] = re.compile(r'[^%s]' % safe)
- safe_map = {}
- for i in range(256):
- c = chr(i)
- safe_map[c] = (c in safe) and c or ('%%%02X' % i)
- _safemaps[cachekey] = safe_map
- res = map(safe_map.__getitem__, s)
- return ''.join(res)