You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2020/05/18 21:27:39 UTC

[allura] branch db/8361 updated (abd7d55 -> c3985df)

This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8361
in repository https://gitbox.apache.org/repos/asf/allura.git.


    from abd7d55  [#8361] e.message doesn't exist in py3
     new add3a21  [#8361] don't utf8 encode urls in tests
     new 9911196  [#8361] referer fixes (comes in as bytes, we want to use it as a string)
     new 8e2eca5  [#8361] more header encoding fixes
     new c3985df  [#8361] work on test; will need Easywidgets version bump

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Allura/allura/app.py                               |  6 +++---
 Allura/allura/controllers/attachments.py           |  4 +++-
 Allura/allura/controllers/auth.py                  | 16 +++++++++-------
 Allura/allura/controllers/discuss.py               | 22 +++++++++++-----------
 Allura/allura/controllers/project.py               |  8 ++++----
 Allura/allura/controllers/repository.py            |  4 ++--
 Allura/allura/controllers/site_admin.py            | 12 ++++++------
 Allura/allura/ext/admin/admin_main.py              |  5 +++--
 Allura/allura/ext/user_profile/user_main.py        |  9 +++++----
 Allura/allura/lib/repository.py                    |  8 +++++---
 Allura/allura/lib/utils.py                         |  2 +-
 Allura/allura/tests/functional/test_discuss.py     | 20 ++++++++++----------
 Allura/allura/tests/unit/patches.py                |  7 +++++--
 ForgeBlog/forgeblog/main.py                        |  8 ++++----
 ForgeBlog/forgeblog/tests/functional/test_rest.py  |  6 +++---
 ForgeChat/forgechat/main.py                        |  3 ++-
 .../forgediscussion/controllers/root.py            |  6 ++++--
 ForgeDiscussion/forgediscussion/forum_main.py      |  2 +-
 ForgeSVN/forgesvn/svn_main.py                      |  4 +++-
 ForgeShortUrl/forgeshorturl/main.py                | 10 ++++++----
 .../forgetracker/tests/functional/test_root.py     | 16 ++++++++--------
 ForgeTracker/forgetracker/tracker_main.py          | 12 ++++++------
 ForgeWiki/forgewiki/wiki_main.py                   |  8 +++++---
 requirements.in                                    |  2 +-
 24 files changed, 110 insertions(+), 90 deletions(-)


[allura] 04/04: [#8361] work on test; will need Easywidgets version bump

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8361
in repository https://gitbox.apache.org/repos/asf/allura.git

commit c3985dfb9a307ede384548307d2f631d16097e76
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Mon May 18 17:27:29 2020 -0400

    [#8361] work on test; will need Easywidgets version bump
---
 Allura/allura/tests/functional/test_discuss.py | 3 ++-
 requirements.in                                | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 8518b00..de143c4 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -292,7 +292,8 @@ class TestDiscuss(TestDiscussBase):
         r = self._make_post('Test post')
         post_link = str(
             r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])
-        self.app.post(post_link + 'moderate', params=dict(spam='spam'))
+        r = self.app.post(post_link + 'moderate', params=dict(spam='spam'))
+        assert_equal(r.json, {"result": "success"})
         post = M.Post.query.find().first()
         post_username = post.author().username
         moderate_link = '/p/test/wiki/_discuss/moderate'
diff --git a/requirements.in b/requirements.in
index cc30883..b80e7b9 100644
--- a/requirements.in
+++ b/requirements.in
@@ -42,7 +42,7 @@ requests
 requests-oauthlib
 # for taskd proc name switching
 setproctitle==1.1.9
-six==1.12.0
+six
 TimerMiddleware==0.5.1
 TurboGears2==2.3.12
 WebHelpers2


[allura] 01/04: [#8361] don't utf8 encode urls in tests

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8361
in repository https://gitbox.apache.org/repos/asf/allura.git

commit add3a21afc5af80f5c8f56ccf94292331252ff32
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Mon May 18 11:19:50 2020 -0400

    [#8361] don't utf8 encode urls in tests
---
 Allura/allura/tests/functional/test_discuss.py          |  4 ++--
 ForgeBlog/forgeblog/main.py                             |  2 +-
 ForgeBlog/forgeblog/tests/functional/test_rest.py       |  6 +++---
 ForgeTracker/forgetracker/tests/functional/test_root.py | 16 ++++++++--------
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 020ce0c..2849946 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -83,7 +83,7 @@ class TestDiscuss(TestDiscussBase):
             if field.has_attr('name'):
                 params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = text
-        r = self.app.post(f['action'].encode('utf-8'), params=params,
+        r = self.app.post(f['action'], params=params,
                           headers={str('Referer'): str(thread_link.encode("utf-8"))},
                           extra_environ=dict(username=str('root')))
         r = r.follow()
@@ -416,7 +416,7 @@ class TestAttachment(TestDiscussBase):
             if field.has_attr('name'):
                 params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'Test Post'
-        r = self.app.post(f['action'].encode('utf-8'), params=params,
+        r = self.app.post(f['action'], params=params,
                           headers={str('Referer'): str(self.thread_link.encode('utf-8'))})
         r = r.follow()
         self.post_link = str(
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 344a4b1..52a01b7 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -608,7 +608,7 @@ class RootRestController(BaseController, AppRestControllerMixin):
     def _lookup(self, year=None, month=None, title=None, *rest):
         if not (year and month and title):
             raise exc.HTTPNotFound()
-        slug = '/'.join((year, month, six.moves.urllib.parse.unquote(title).decode('utf-8')))
+        slug = '/'.join((year, month, six.ensure_text(six.moves.urllib.parse.unquote(title))))
         post = BM.BlogPost.query.get(slug=slug, app_config_id=c.app.config._id)
         if not post:
             raise exc.HTTPNotFound()
diff --git a/ForgeBlog/forgeblog/tests/functional/test_rest.py b/ForgeBlog/forgeblog/tests/functional/test_rest.py
index 826a0ed..8b685ae 100644
--- a/ForgeBlog/forgeblog/tests/functional/test_rest.py
+++ b/ForgeBlog/forgeblog/tests/functional/test_rest.py
@@ -137,7 +137,7 @@ class TestBlogApi(TestRestApiBase):
         self.api_post('/rest/p/test/blog/', title='test',
                       text='test text', state='published')
         url = '/rest' + BM.BlogPost.query.find().first().url()
-        self.app.post(url.encode('utf-8'),
+        self.app.post(url,
                       params=dict(title='test2', text='test text2',
                                   state='published'),
                       extra_environ={'username': str('*anonymous')},
@@ -147,7 +147,7 @@ class TestBlogApi(TestRestApiBase):
         anon = M.ProjectRole.by_name('*anonymous')._id
         anon_write = M.ACE.allow(anon, 'write')
         acl.append(anon_write)
-        self.app.post(url.encode('utf-8'),
+        self.app.post(url,
                       params=dict(title='test2', text='test text2',
                                   state='published'),
                       extra_environ={'username': str('*anonymous')},
@@ -164,7 +164,7 @@ class TestBlogApi(TestRestApiBase):
                          extra_environ={'username': str('*anonymous')})
         assert_equal(r.json['posts'], [])
         url = '/rest' + BM.BlogPost.query.find().first().url()
-        self.app.post(url.encode('utf-8'),
+        self.app.post(url,
                       params=dict(title='test2', text='test text2',
                                   state='published'),
                       extra_environ={'username': str('*anonymous')},
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index bcb8069..eb341cc 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -926,7 +926,7 @@ class TestFunctionalController(TrackerTestController):
             if field.has_attr('name'):
                 params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'test comment'
-        self.app.post(f['action'].encode('utf-8'), params=params,
+        self.app.post(f['action'], params=params,
                       headers={'Referer': '/bugs/1/'.encode("utf-8")})
         r = self.app.get('/bugs/1/', dict(page='1'))
         post_link = str(r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])
@@ -1522,7 +1522,7 @@ class TestFunctionalController(TrackerTestController):
             if field.has_attr('name'):
                 params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = post_content
-        r = self.app.post(f['action'].encode('utf-8'), params=params,
+        r = self.app.post(f['action'], params=params,
                           headers={'Referer': '/bugs/1/'.encode("utf-8")})
         r = self.app.get('/bugs/1/', dict(page='1'))
         assert_true(post_content in r)
@@ -1538,7 +1538,7 @@ class TestFunctionalController(TrackerTestController):
             if field.has_attr('name'):
                 params[field['name']] = field.get('value') or ''
         params['ticket_form.summary'] = new_summary
-        r = self.app.post(f['action'].encode('utf-8'), params=params,
+        r = self.app.post(f['action'], params=params,
                           headers={'Referer': '/bugs/1/'.encode("utf-8")})
         r = self.app.get('/bugs/1/', dict(page='1'))
         assert_true(summary + ' --&gt; ' + new_summary in r)
@@ -1557,7 +1557,7 @@ class TestFunctionalController(TrackerTestController):
             if field.has_attr('name'):
                 params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = post_content
-        r = self.app.post(f['action'].encode('utf-8'), params=params,
+        r = self.app.post(f['action'], params=params,
                           headers={'Referer': '/bugs/1/'.encode("utf-8")})
         r = self.app.get('/bugs/1/', dict(page='-1'))
         assert_true(summary in r)
@@ -1567,7 +1567,7 @@ class TestFunctionalController(TrackerTestController):
         assert_false('Page 1 of 1' in r)
         # add some more posts and check for pager
         for i in range(2):
-            r = self.app.post(f['action'].encode('utf-8'), params=params,
+            r = self.app.post(f['action'], params=params,
                               headers={'Referer': '/bugs/1/'.encode("utf-8")})
         r = self.app.get('/bugs/1/', dict(page='1', limit='2'))
         assert_true('Page 2 of 2' in r)
@@ -1585,7 +1585,7 @@ class TestFunctionalController(TrackerTestController):
             if field.has_attr('name'):
                 params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = post_content
-        self.app.post(f['action'].encode('utf-8'), params=params,
+        self.app.post(f['action'], params=params,
                       headers={'Referer': '/bugs/1/'.encode("utf-8")})
         r = self.app.get('/bugs/feed.rss')
         post = M.Post.query.find().first()
@@ -2201,7 +2201,7 @@ class TestFunctionalController(TrackerTestController):
             if field.has_attr('name'):
                 params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = post_content
-        r = self.app.post(f['action'].encode('utf-8'), params=params,
+        r = self.app.post(f['action'], params=params,
                           headers={'Referer': '/p/test2/bugs2/1/'.encode("utf-8")})
         r = self.app.get('/p/test2/bugs2/1/', dict(page='1'))
         assert_true(post_content in r)
@@ -2451,7 +2451,7 @@ class TestFunctionalController(TrackerTestController):
             if field.has_attr('name'):
                 params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'test comment'
-        self.app.post(f['action'].encode('utf-8'), params=params,
+        self.app.post(f['action'], params=params,
                       headers={'Referer': '/bugs/1/'.encode("utf-8")})
         r = self.app.get('/bugs/1/', dict(page='1'))
         post_link = str(r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])


[allura] 02/04: [#8361] referer fixes (comes in as bytes, we want to use it as a string)

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8361
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 9911196571115f95598bdccfd97065e35576522a
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Mon May 18 12:47:07 2020 -0400

    [#8361] referer fixes (comes in as bytes, we want to use it as a string)
---
 Allura/allura/app.py                               |  6 +++---
 Allura/allura/controllers/attachments.py           |  4 +++-
 Allura/allura/controllers/auth.py                  | 16 +++++++++-------
 Allura/allura/controllers/discuss.py               | 22 +++++++++++-----------
 Allura/allura/controllers/project.py               |  8 ++++----
 Allura/allura/controllers/repository.py            |  4 ++--
 Allura/allura/controllers/site_admin.py            | 12 ++++++------
 Allura/allura/ext/admin/admin_main.py              |  5 +++--
 Allura/allura/ext/user_profile/user_main.py        |  9 +++++----
 Allura/allura/lib/repository.py                    |  8 +++++---
 Allura/allura/lib/utils.py                         |  2 +-
 Allura/allura/tests/functional/test_discuss.py     |  2 +-
 Allura/allura/tests/unit/patches.py                |  7 +++++--
 ForgeBlog/forgeblog/main.py                        |  4 ++--
 ForgeChat/forgechat/main.py                        |  3 ++-
 .../forgediscussion/controllers/root.py            |  6 ++++--
 ForgeDiscussion/forgediscussion/forum_main.py      |  2 +-
 ForgeSVN/forgesvn/svn_main.py                      |  4 +++-
 ForgeShortUrl/forgeshorturl/main.py                | 10 ++++++----
 ForgeTracker/forgetracker/tracker_main.py          | 12 ++++++------
 ForgeWiki/forgewiki/wiki_main.py                   |  8 +++++---
 21 files changed, 87 insertions(+), 67 deletions(-)

diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index a631fb7..ef751ef 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -918,7 +918,7 @@ class DefaultAdminController(BaseController, AdminControllerMixin):
         require_access(self.app, 'configure')
         self.app.config.options['mount_label'] = mount_label
         g.post_event('project_menu_updated')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose('jinja:allura:templates/app_admin_options.html')
     def options(self):
@@ -973,7 +973,7 @@ class DefaultAdminController(BaseController, AdminControllerMixin):
                          + self.app.config.options.mount_point
                          + '/')
             else:
-                redirect(request.referer or '/')
+                redirect(six.ensure_text(request.referer or '/'))
 
     @without_trailing_slash
     @expose()
@@ -1026,7 +1026,7 @@ class DefaultAdminController(BaseController, AdminControllerMixin):
                 if (ace.permission == perm) and (ace.access == model.ACE.DENY):
                     self.app.config.acl.append(ace)
         g.post_event('project_menu_updated')  # since 'read' permission changes can affect what is visible in menu
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
 
 class WebhooksLookup(BaseController, AdminControllerMixin):
diff --git a/Allura/allura/controllers/attachments.py b/Allura/allura/controllers/attachments.py
index 427a329..f93c684 100644
--- a/Allura/allura/controllers/attachments.py
+++ b/Allura/allura/controllers/attachments.py
@@ -17,6 +17,8 @@
 
 from __future__ import unicode_literals
 from __future__ import absolute_import
+
+import six
 from six.moves.urllib.parse import unquote
 from webob import exc
 
@@ -117,7 +119,7 @@ class AttachmentController(BaseController):
             self.handle_post(delete, **kw)
             if is_ajax(request):
                 return
-            redirect(request.referer or '/')
+            redirect(six.ensure_text(request.referer or '/'))
         if self.artifact.deleted:
             raise exc.HTTPNotFound
         embed = False
diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index a83604d..dc7aec7 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -137,10 +137,12 @@ class AuthController(BaseController):
         elif orig_request:
             return_to = orig_request.url
         else:
-            if request.referer is not None and request.referer.split('/')[-1] == 'neighborhood':
+            if request.referer is not None and six.ensure_text(request.referer).split('/')[-1] == 'neighborhood':
                 return_to = '/'
+            elif request.referer:
+                return_to = six.ensure_text(request.referer)
             else:
-                return_to = request.referer
+                return_to = None
         c.form = F.login_form
         return dict(return_to=return_to)
 
@@ -277,7 +279,7 @@ class AuthController(BaseController):
             flash('Verification link sent')
         else:
             flash('No such address', 'error')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     def _verify_addr(self, addr, do_auth_check=True):
         confirmed_by_other = M.EmailAddress.find(dict(email=addr.email, confirmed=True)).all() if addr else []
@@ -371,7 +373,7 @@ class AuthController(BaseController):
 
         if 'multifactor-username' not in session:
             tg.flash('Your multifactor login was disrupted, please start over.', 'error')
-            redirect('/auth/', return_to=kwargs.get('return_to', ''))
+            redirect('/auth/', {'return_to': kwargs.get('return_to', '')})
 
         user = M.User.by_username(session['multifactor-username'])
         try:
@@ -698,7 +700,7 @@ class PreferencesController(BaseController):
     @require_post()
     def user_message(self, allow_user_messages=False):
         c.user.set_pref('disable_user_messages', not allow_user_messages)
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose('jinja:allura:templates/user_totp.html')
     @without_trailing_slash
@@ -1221,7 +1223,7 @@ class SubscriptionsController(BaseController):
         if email_format:
             c.user.set_pref('email_format', email_format)
 
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose()
     @require_post()
@@ -1232,7 +1234,7 @@ class SubscriptionsController(BaseController):
             h.auditlog_user('User mention notifications are enabled')
         else:
             h.auditlog_user('User mention notifications are disabled')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
 
 class OAuthController(BaseController):
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index d6fa61e..c6f18e7 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -100,7 +100,7 @@ class DiscussionController(BaseController, FeedController):
             self.moderate = ModerationController(self)
 
     def error_handler(self, *args, **kwargs):
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @h.vardec
     @expose()
@@ -115,7 +115,7 @@ class DiscussionController(BaseController, FeedController):
                 thread.unsubscribe()
             session(self.M.Thread)._get().skip_mod_date = True
             session(self.M.Thread)._get().skip_last_updated = True
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     def get_feed(self, project, app, user):
         """Return a :class:`allura.controllers.feed.FeedArgs` object describing
@@ -215,7 +215,7 @@ class ThreadController(six.with_metaclass(h.ProxiedAttrMeta, BaseController, Fee
                     show_moderate=kw.get('show_moderate'))
 
     def error_handler(self, *args, **kwargs):
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @memorable_forget()
     @h.vardec
@@ -236,7 +236,7 @@ class ThreadController(six.with_metaclass(h.ProxiedAttrMeta, BaseController, Fee
         if self.thread.ref:
             require_access(self.thread.ref.artifact, 'post')
         self.thread.labels = labels.split(',')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose()
     def flag_as_spam(self, **kw):
@@ -260,14 +260,14 @@ class ThreadController(six.with_metaclass(h.ProxiedAttrMeta, BaseController, Fee
 
 def handle_post_or_reply(thread, edit_widget, rate_limit, kw, parent_post_id=None):
     require_access(thread, 'post')
-    rate_limit(M.Post, "Comment", redir=request.referrer)
+    rate_limit(M.Post, "Comment", redir=six.ensure_text(request.referer or '/'))
     if thread.ref:
         require_access(thread.ref.artifact, 'post')
     kw = edit_widget.to_python(kw, None)  # could raise Invalid, but doesn't seem like it ever does
     if not kw['text']:
         flash('Your post was not saved. You must provide content.',
               'error')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
     file_info = kw.get('file_info', None)
     p = thread.add_post(parent_id=parent_post_id, **kw)
     p.add_multiple_attachments(file_info)
@@ -275,7 +275,7 @@ def handle_post_or_reply(thread, edit_widget, rate_limit, kw, parent_post_id=Non
         thread.artifact.mod_date = datetime.utcnow()
     flash('Message posted')
     notification_tasks.send_usermentions_notification.post(p.index_id(), kw['text'])
-    redirect(request.referer or '/')
+    redirect(six.ensure_text(request.referer or '/'))
 
 
 class PostController(six.with_metaclass(h.ProxiedAttrMeta, BaseController)):
@@ -332,7 +332,7 @@ class PostController(six.with_metaclass(h.ProxiedAttrMeta, BaseController)):
                                        target=self.post.thread.artifact or self.post.thread,
                                        related_nodes=[self.post.app_config.project],
                                        tags=['comment'])
-            redirect(request.referer or '/')
+            redirect(six.ensure_text(request.referer or '/'))
         elif request.method == 'GET':
             if self.post.deleted:
                 raise exc.HTTPNotFound
@@ -406,7 +406,7 @@ class PostController(six.with_metaclass(h.ProxiedAttrMeta, BaseController)):
         return dict(status=status, counts=self.post.react_counts)
 
     def error_handler(self, *args, **kwargs):
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @memorable_forget()
     @h.vardec
@@ -450,7 +450,7 @@ class PostController(six.with_metaclass(h.ProxiedAttrMeta, BaseController)):
     def attach(self, file_info=None):
         require_access(self.post, 'moderate')
         self.post.add_multiple_attachments(file_info)
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose()
     def _lookup(self, id, *remainder):
@@ -564,7 +564,7 @@ class ModerationController(six.with_metaclass(h.ProxiedAttrMeta, BaseController)
                     posted.thread.post_to_feed(posted)
         flash('{} {}'.format(h.text.plural(count, 'post', 'posts'),
                               'deleted' if delete else 'marked as spam' if spam else 'approved'))
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose()
     @require_post()
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 4240042..77fea7e 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -874,7 +874,7 @@ class NeighborhoodAwardsController(object):
                     icon.filename, icon.file, content_type=icon.type,
                     square=True, thumbnail_size=(48, 48),
                     thumbnail_meta=dict(award_id=award._id))
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose()
     @require_post()
@@ -895,7 +895,7 @@ class NeighborhoodAwardsController(object):
             award.comment = comment
             with h.push_context(recipient_q._id):
                 g.post_event('project_updated')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
 
 class AwardController(object):
@@ -963,7 +963,7 @@ class AwardController(object):
                     g.post_event('project_updated')
             M.AwardFile.query.remove(dict(award_id=self.award._id))
             self.award.delete()
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
 
 class GrantController(object):
@@ -1005,7 +1005,7 @@ class GrantController(object):
         self.grant.delete()
         with h.push_context(self.project._id):
             g.post_event('project_updated')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
 
 class ProjectImporterController(object):
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 08fcde0..4959af7 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -116,7 +116,7 @@ class RepoRootController(BaseController, FeedController):
         allura.tasks.repo_tasks.refresh.post()
         if request.referer:
             flash('Repository is being refreshed')
-            redirect(request.referer or '/')
+            redirect(six.ensure_text(request.referer or '/'))
         else:
             return '%r refresh queued.\n' % c.app.repo
 
@@ -157,7 +157,7 @@ class RepoRootController(BaseController, FeedController):
                     raise
                 except Exception as ex:
                     flash(str(ex), 'error')
-                    redirect(request.referer or '/')
+                    redirect(six.ensure_text(request.referer or '/'))
 
     @property
     def mr_widget(self):
diff --git a/Allura/allura/controllers/site_admin.py b/Allura/allura/controllers/site_admin.py
index 4fa7ffc..7def94e 100644
--- a/Allura/allura/controllers/site_admin.py
+++ b/Allura/allura/controllers/site_admin.py
@@ -513,7 +513,7 @@ class SiteNotificationController(object):
     def delete(self):
         self.note.delete()
         ThreadLocalORMSession().flush_all()
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
 
 class TaskManagerController(object):
@@ -696,7 +696,7 @@ class AdminUserDetailsController(object):
             flash('Comment added', 'ok')
         else:
             flash('Can not add comment "%s" for user %s' % (comment, user))
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose()
     @require_post()
@@ -715,7 +715,7 @@ class AdminUserDetailsController(object):
             AuthenticationProvider.get(request).deactivate_user(user)
             AuthenticationProvider.get(request).enable_user(user, audit=False)
             flash('Set user status to pending')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose()
     @require_post()
@@ -727,7 +727,7 @@ class AdminUserDetailsController(object):
         AuthenticationProvider.get(request).set_password(user, None, pwd)
         h.auditlog_user('Set random password', user=user)
         flash('Password is set', 'ok')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose()
     @require_post()
@@ -740,7 +740,7 @@ class AdminUserDetailsController(object):
             allura.controllers.auth.AuthController().password_recovery_hash(email)
         except HTTPFound:
             pass  # catch redirect to '/'
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose()
     @require_post()
@@ -759,7 +759,7 @@ class AdminUserDetailsController(object):
         if not user or user.is_anonymous():
             raise HTTPNotFound()
         allura.controllers.auth.PreferencesController()._update_emails(user, admin=True, form_params=kw)
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
 
 class StatsSiteAdminExtension(SiteAdminExtension):
diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index 3930a94..4fd8623 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -645,10 +645,11 @@ class ProjectAdminController(BaseController):
             flash('%s: %s' % (exc.__class__.__name__, exc.args[0]),
                   'error')
         if request.referer is not None and tool is not None and 'delete' in tool[0] and \
-            re.search(c.project.url() + r'(admin\/|)' + tool[0]['mount_point']+ r'\/*', request.referer):
+            re.search(c.project.url() + r'(admin\/|)' + tool[0]['mount_point']+ r'\/*',
+                      six.ensure_text(request.referer)):
             # Redirect to root when deleting currect module
             redirect('../')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose('jinja:allura.ext.admin:templates/export.html')
     def export(self, tools=None, with_attachments=False):
diff --git a/Allura/allura/ext/user_profile/user_main.py b/Allura/allura/ext/user_profile/user_main.py
index bf96096..2125605 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -22,6 +22,7 @@ import logging
 import pkg_resources
 from datetime import datetime
 
+import six
 from formencode import validators
 from tg import request
 from tg import tmpl_context as c, app_globals as g
@@ -128,21 +129,21 @@ class UserProfileController(BaseController, FeedController):
     def _check_can_message(self, from_user, to_user):
         if from_user is User.anonymous():
             flash('You must be logged in to send user messages.', 'info')
-            redirect(request.referer or '/')
+            redirect(six.ensure_text(request.referer or '/'))
 
         if not (from_user and from_user.get_pref('email_address')):
             flash('In order to send messages, you must have an email address '
                   'associated with your account.', 'info')
-            redirect(request.referer or '/')
+            redirect(six.ensure_text(request.referer or '/'))
 
         if not (to_user and to_user.get_pref('email_address')):
             flash('This user can not receive messages because they do not have '
                   'an email address associated with their account.', 'info')
-            redirect(request.referer or '/')
+            redirect(six.ensure_text(request.referer or '/'))
 
         if to_user.get_pref('disable_user_messages'):
             flash('This user has disabled direct email messages', 'info')
-            redirect(request.referer or '/')
+            redirect(six.ensure_text(request.referer or '/'))
 
     @expose('jinja:allura.ext.user_profile:templates/user_index.html')
     def index(self, **kw):
diff --git a/Allura/allura/lib/repository.py b/Allura/allura/lib/repository.py
index af88d9b..be49df1 100644
--- a/Allura/allura/lib/repository.py
+++ b/Allura/allura/lib/repository.py
@@ -18,6 +18,8 @@
 from __future__ import unicode_literals
 from __future__ import absolute_import
 import logging
+
+import six
 from six.moves.urllib.parse import quote
 
 from tg import tmpl_context as c, app_globals as g
@@ -269,14 +271,14 @@ class RepoAdminController(DefaultAdminController):
     @require_post()
     def set_extensions(self, **post_data):
         self.repo.additional_viewable_extensions = post_data['additional_viewable_extensions']
-        redirect(request.referer)
+        redirect(six.ensure_text(request.referer or '/'))
 
     @without_trailing_slash
     @expose('jinja:allura:templates/repo/default_branch.html')
     def set_default_branch_name(self, branch_name=None, **kw):
         if (request.method == 'POST') and branch_name:
             self.repo.set_default_branch(branch_name)
-            redirect(request.referer or '/')
+            redirect(six.ensure_text(request.referer or '/'))
         else:
             return dict(app=self.app,
                         default_branch_name=self.app.default_branch_name)
@@ -312,7 +314,7 @@ class RepoAdminController(DefaultAdminController):
             flash(message,
                   'error' if 'Invalid' in message else 'ok')
 
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
 
 class RepoAdminRestController(BaseController):
diff --git a/Allura/allura/lib/utils.py b/Allura/allura/lib/utils.py
index a16fa91..a6f782e 100644
--- a/Allura/allura/lib/utils.py
+++ b/Allura/allura/lib/utils.py
@@ -383,7 +383,7 @@ class AntiSpam(object):
                 else:
                     # regular antispam failure handling
                     tg.flash(error_msg, 'error')
-                    redirect(error_url or tg.request.referer or '.')
+                    redirect(error_url or six.ensure_text(tg.request.referer or '.'))
         return before_validate(antispam_hook)
 
 
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 2849946..80b8633 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -84,7 +84,7 @@ class TestDiscuss(TestDiscussBase):
                 params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = text
         r = self.app.post(f['action'], params=params,
-                          headers={str('Referer'): str(thread_link.encode("utf-8"))},
+                          headers={str('Referer'): str(thread_link)},
                           extra_environ=dict(username=str('root')))
         r = r.follow()
         return r
diff --git a/Allura/allura/tests/unit/patches.py b/Allura/allura/tests/unit/patches.py
index f8818be..02897dc 100644
--- a/Allura/allura/tests/unit/patches.py
+++ b/Allura/allura/tests/unit/patches.py
@@ -17,7 +17,7 @@
 
 from __future__ import unicode_literals
 from __future__ import absolute_import
-from mock import Mock, patch
+from mock import Mock, patch, MagicMock
 from tg import tmpl_context as c
 
 from allura.tests.unit.factories import (
@@ -60,4 +60,7 @@ def fake_redirect_patch(test_case):
 
 
 def fake_request_patch(test_case):
-    return patch('allura.controllers.discuss.request')
+    return patch('allura.controllers.discuss.request',
+                 MagicMock(
+                     referer='.'
+                 ))
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 52a01b7..c27ed0b 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -526,7 +526,7 @@ class BlogAdminController(DefaultAdminController):
         self.app.config.options[
             'AllowEmailPosting'] = allow_email_posting and True or False
         flash('Blog options updated')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @without_trailing_slash
     @expose('jinja:forgeblog:templates/blog/admin_exfeed.html')
@@ -568,7 +568,7 @@ class BlogAdminController(DefaultAdminController):
             flash('Invalid link(s): %s' %
                   ','.join(link for link in invalid_list), 'error')
 
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
 
 class RootRestController(BaseController, AppRestControllerMixin):
diff --git a/ForgeChat/forgechat/main.py b/ForgeChat/forgechat/main.py
index e3b4765..92dc696 100644
--- a/ForgeChat/forgechat/main.py
+++ b/ForgeChat/forgechat/main.py
@@ -24,6 +24,7 @@ import logging
 from datetime import date, time, datetime, timedelta
 
 # Non-stdlib imports
+import six
 from tg import expose, validate, redirect, flash
 from tg.decorators import with_trailing_slash
 from tg import tmpl_context as c, request
@@ -127,7 +128,7 @@ class AdminController(DefaultAdminController):
 
     @with_trailing_slash
     def index(self, **kw):
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose()
     @require_post()
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py b/ForgeDiscussion/forgediscussion/controllers/root.py
index 0356f30..b636f7c 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -19,6 +19,8 @@ from __future__ import unicode_literals
 from __future__ import absolute_import
 import json
 import logging
+
+import six
 from six.moves.urllib.parse import unquote
 from datetime import date, datetime, timedelta, time
 import calendar
@@ -133,13 +135,13 @@ class RootController(BaseController, DispatchIndex, FeedController):
     @validate(W.new_topic, error_handler=create_topic)
     @AntiSpam.validate('Spambot protection engaged', error_url='create_topic')
     def save_new_topic(self, subject=None, text=None, forum=None, subscribe=False, **kw):
-        self.rate_limit(model.ForumPost, 'Topic creation', request.referer)
+        self.rate_limit(model.ForumPost, 'Topic creation', six.ensure_text(request.referer or '/'))
         discussion = model.Forum.query.get(
             app_config_id=c.app.config._id,
             shortname=forum)
         if discussion.deleted and not has_access(c.app, 'configure')():
             flash('This forum has been removed.')
-            redirect(request.referer or '/')
+            redirect(six.ensure_text(request.referer or '/'))
         require_access(discussion, 'post')
         thd = discussion.get_discussion_thread(dict(
             headers=dict(Subject=subject)))[0]
diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py
index e481c23..5c6b19d 100644
--- a/ForgeDiscussion/forgediscussion/forum_main.py
+++ b/ForgeDiscussion/forgediscussion/forum_main.py
@@ -331,7 +331,7 @@ class ForumAdminController(DefaultAdminController):
                 else:
                     forum.acl = []
         flash('Forums updated')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @h.vardec
     @expose()
diff --git a/ForgeSVN/forgesvn/svn_main.py b/ForgeSVN/forgesvn/svn_main.py
index 5fafbf7..315d910 100644
--- a/ForgeSVN/forgesvn/svn_main.py
+++ b/ForgeSVN/forgesvn/svn_main.py
@@ -19,6 +19,8 @@
 from __future__ import unicode_literals
 from __future__ import absolute_import
 import logging
+
+import six
 from tg import tmpl_context as c, request
 
 # Non-stdlib imports
@@ -184,7 +186,7 @@ class SVNImportController(BaseController, AdminControllerMixin):
             M.Notification.post_user(
                 c.user, self.app.repo, 'error',
                 text="Can't import into non empty repository.")
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
 
 class SVNCommitBrowserController(BaseController):
diff --git a/ForgeShortUrl/forgeshorturl/main.py b/ForgeShortUrl/forgeshorturl/main.py
index a471983..f03b9b6 100644
--- a/ForgeShortUrl/forgeshorturl/main.py
+++ b/ForgeShortUrl/forgeshorturl/main.py
@@ -17,6 +17,8 @@
 
 from __future__ import unicode_literals
 from __future__ import absolute_import
+
+import six
 from tg import expose, validate, redirect, flash, request
 from tg.decorators import without_trailing_slash
 
@@ -203,7 +205,7 @@ class ShortURLAdminController(DefaultAdminController):
 
     @expose()
     def index(self, **kw):
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @without_trailing_slash
     @expose('json:')
@@ -231,7 +233,7 @@ class ShortURLAdminController(DefaultAdminController):
                     names = {'short_url': 'Short url', 'full_url': 'Full URL'}
                     error_msg += '%s: %s ' % (names[msg], c.form_errors[msg])
                     flash(error_msg, 'error')
-                redirect(request.referer or '/')
+                redirect(six.ensure_text(request.referer or '/'))
 
             shorturl = ShortUrl.query.find({
                 'app_config_id': self.app.config._id,
@@ -240,7 +242,7 @@ class ShortURLAdminController(DefaultAdminController):
             if shorturl is not None:
                 if not update:
                     flash('Short url %s already exists' % short_url, 'error')
-                    redirect(request.referer or '/')
+                    redirect(six.ensure_text(request.referer or '/'))
                 else:
                     msg = ('update short url %s from %s to %s'
                            % (short_url, shorturl.full_url, full_url))
@@ -261,7 +263,7 @@ class ShortURLAdminController(DefaultAdminController):
             shorturl.last_updated = datetime.utcnow()
 
             M.AuditLog.log(msg)
-            redirect(request.referer or '/')
+            redirect(six.ensure_text(request.referer or '/'))
         return dict(
             app=self.app,
             url_len=len(ShortUrl.build_short_url(c.app, short_name='')))
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 28c7727..2aa2b0e 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1605,16 +1605,16 @@ class TicketController(BaseController, FeedController):
             tracker = M.AppConfig.query.get(_id=t_id)
             if tracker is None:
                 flash('Select valid tracker', 'error')
-                redirect(request.referer or '/')
+                redirect(six.ensure_text(request.referer or '/'))
 
             if tracker == self.ticket.app.config:
                 flash('Ticket already in a selected tracker', 'info')
-                redirect(request.referer or '/')
+                redirect(six.ensure_text(request.referer or '/'))
 
             if not has_access(tracker, 'admin')():
                 flash('You should have admin access to destination tracker',
                       'error')
-                redirect(request.referer or '/')
+                redirect(six.ensure_text(request.referer or '/'))
 
             new_ticket = self.ticket.move(tracker)
             c.app.globals.invalidate_bin_counts()
@@ -1702,7 +1702,7 @@ class TrackerAdminController(DefaultAdminController):
         for k, val in six.iteritems(kw):
             self.app.config.options[k] = val
         flash('Options updated')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose()
     @require_post()
@@ -1712,7 +1712,7 @@ class TrackerAdminController(DefaultAdminController):
                 self.app.globals['show_in_search'][column] = True
             else:
                 self.app.globals['show_in_search'][column] = False
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose()
     def update_tickets(self, **post_data):
@@ -1805,7 +1805,7 @@ class TrackerAdminController(DefaultAdminController):
 
         self.app.globals.custom_fields = custom_fields
         flash('Fields updated')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
 
 class RootRestController(BaseController, AppRestControllerMixin):
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index d635222..c30eb8e 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -22,6 +22,8 @@ import json
 import logging
 import os
 from pprint import pformat
+
+import six
 from six.moves.urllib.parse import unquote
 
 # Non-stdlib imports
@@ -521,7 +523,7 @@ class RootController(BaseController, DispatchIndex, FeedController):
             M.Mailbox.subscribe(type='direct')
         elif unsubscribe:
             M.Mailbox.unsubscribe()
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
 
 class PageController(BaseController, FeedController):
@@ -793,7 +795,7 @@ class PageController(BaseController, FeedController):
         self.page.add_multiple_attachments(file_info)
         if is_ajax(request):
             return
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))
 
     @expose('json:')
     @require_post()
@@ -940,4 +942,4 @@ class WikiAdminController(DefaultAdminController):
         self.app.show_right_bar = show_right_bar
         self.app.allow_email_posting = allow_email_posting
         flash('Wiki options updated')
-        redirect(request.referer or '/')
+        redirect(six.ensure_text(request.referer or '/'))


[allura] 03/04: [#8361] more header encoding fixes

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8361
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 8e2eca595836558ed66d3c58c72a432a4f717118
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Mon May 18 17:23:06 2020 -0400

    [#8361] more header encoding fixes
---
 Allura/allura/tests/functional/test_discuss.py | 11 +++++------
 ForgeBlog/forgeblog/main.py                    |  2 +-
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 80b8633..8518b00 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -31,7 +31,6 @@ from io import open
 from six.moves import range
 
 
-
 class TestDiscussBase(TestController):
 
     def _thread_link(self):
@@ -110,7 +109,7 @@ class TestDiscuss(TestDiscussBase):
         params[post_form.find('textarea')['name']] = 'This is a new post'
         r = self.app.post(post_link,
                           params=params,
-                          headers={str('Referer'): str(thread_link.encode("utf-8"))})
+                          headers={str('Referer'): str(thread_link)})
         r = r.follow()
         assert 'This is a new post' in r, r
         r = self.app.get(post_link)
@@ -124,10 +123,10 @@ class TestDiscuss(TestDiscussBase):
         params[post_form.find('textarea')['name']] = 'Tis a reply'
         r = self.app.post(post_link + 'reply',
                           params=params,
-                          headers={str('Referer'): str(post_link.encode("utf-8"))})
+                          headers={str('Referer'): str(post_link)})
         r = self.app.get(thread_link)
         assert 'Tis a reply' in r, r
-        permalinks = [post.find('form')['action'].encode('utf-8')
+        permalinks = [post.find('form')['action']
                       for post in r.html.findAll('div', {'class': 'edit_post_form reply'})]
         self.app.post(permalinks[1] + 'flag')
         self.app.post(permalinks[1] + 'moderate', params=dict(delete='delete'))
@@ -409,7 +408,7 @@ class TestAttachment(TestDiscussBase):
         for f in thread.html.findAll('form'):
             if f.get('action', '').endswith('/post'):
                 break
-        self.post_form_link = f['action'].encode('utf-8')
+        self.post_form_link = f['action']
         params = dict()
         inputs = f.findAll('input')
         for field in inputs:
@@ -417,7 +416,7 @@ class TestAttachment(TestDiscussBase):
                 params[field['name']] = field.get('value') or ''
         params[f.find('textarea')['name']] = 'Test Post'
         r = self.app.post(f['action'], params=params,
-                          headers={str('Referer'): str(self.thread_link.encode('utf-8'))})
+                          headers={str('Referer'): str(self.thread_link)})
         r = r.follow()
         self.post_link = str(
             r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index c27ed0b..6e286c2 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -592,7 +592,7 @@ class RootRestController(BaseController, AppRestControllerMixin):
                 text=text,
                 labels=labels.split(','),
                 **kw)
-            return exc.HTTPCreated(headers=dict(Location=str(h.absurl('/rest' + post.url()).encode('utf-8'))))
+            return exc.HTTPCreated(headers=dict(Location=str(h.absurl('/rest' + post.url()))))
 
         else:
             result = RootController().index(limit=limit, page=page)