From: W. Trevor King Date: Wed, 21 Jul 2010 19:12:19 +0000 (-0400) Subject: Encode URLs into ASCII. X-Git-Tag: v0.1~13 X-Git-Url: http://git.tremily.us/?p=cookbook.git;a=commitdiff_plain;h=3d90ba0a12f7aebfb20cccefa54f832b52c0aad2 Encode URLs into ASCII. URL encoding is undefined. See http://www.cherrypy.org/ticket/825 http://www.w3schools.com/TAGS/ref_urlencode.asp http://www.rfc-editor.org/rfc/rfc2396.txt Therefore, safe URLs should be in a subset of ASCII. We convert our URLs to UTF-8, and then use urllib.quote_plus() to escape the UTF-8 into ASCII. --- diff --git a/cookbook/cookbook.py b/cookbook/cookbook.py index 2c395c5..de3a84b 100644 --- a/cookbook/cookbook.py +++ b/cookbook/cookbook.py @@ -27,6 +27,7 @@ import os import os.path import textwrap import types +from urllib import quote_plus import yaml @@ -439,12 +440,12 @@ class Recipe (object): self.url = url self.tags = tags - def clean_name(self): + def clean_name(self, ascii=False): name = self.name - for from_,to in [(' ','_'), ('/', '_'), - (',', ''), (u'\xe2\x80\x99', ''), - ('&', 'and')]: + for from_,to in [(' ','_'), ('/', '_'), (',', ''), ('&', 'and')]: name = name.replace(from_, to) + if ascii == True: + return quote_plus(name.encode('utf-8')) return name def matches_tags(self, tags): @@ -540,6 +541,7 @@ class Cookbook (list): for recipe in self: self.index[recipe.name] = recipe self.index[recipe.clean_name()] = recipe + self.index[recipe.clean_name(ascii=True)] = recipe def tags(self): """List all tags used in this cookbook. diff --git a/cookbook/server.py b/cookbook/server.py index 94f70f6..fb5a61d 100644 --- a/cookbook/server.py +++ b/cookbook/server.py @@ -63,8 +63,8 @@ class Server (object): if name == None: recipe = random.choice(self.cookbook) else: - if type(name) == types.StringType: - name = unicode(name, encoding='utf-8') + if isinstance(name, types.StringType): + name = unicode(name, 'utf-8') recipe = self.cookbook.index[name] template = self.env.get_template('recipe.html') return template.render(cookbook=self.cookbook, recipe=recipe) @@ -72,8 +72,8 @@ class Server (object): @cherrypy.expose def add_tag(self, name, tag): """Add a tag to a single recipe.""" - if type(name) == types.StringType: - name = unicode(name, encoding='utf-8') + if isinstance(name, types.StringType): + name = unicode(name, 'utf-8') recipe = self.cookbook.index[name] if recipe.tags == None: recipe.tags = [] @@ -83,13 +83,13 @@ class Server (object): with open(recipe.path, 'w') as f: recipe.save(f) raise cherrypy.HTTPRedirect( - 'recipe?name=%s' % recipe.clean_name(), status=302) + u'recipe?name=%s' % recipe.clean_name(ascii=True), status=302) @cherrypy.expose def remove_tag(self, name, tag): """Remove a tag from a single recipe.""" - if type(name) == types.StringType: - name = unicode(name, encoding='utf-8') + if isinstance(name, types.StringType): + name = unicode(name, 'utf-8') recipe = self.cookbook.index[name] if recipe.tags == None: return @@ -99,7 +99,7 @@ class Server (object): with open(recipe.path, 'w') as f: recipe.save(f) raise cherrypy.HTTPRedirect( - 'recipe?name=%s' % recipe.clean_name(), status=302) + u'recipe?name=%s' % recipe.clean_name(ascii=True), status=302) def _clean_tag(self, tag): """Sanitize tag.""" diff --git a/cookbook/template/recipes.html b/cookbook/template/recipes.html index a9bfc07..c362e66 100644 --- a/cookbook/template/recipes.html +++ b/cookbook/template/recipes.html @@ -15,7 +15,7 @@