diff --git a/swiftclient/client.py b/swiftclient/client.py
index 896dd354..ff35f652 100644
--- a/swiftclient/client.py
+++ b/swiftclient/client.py
@@ -20,6 +20,7 @@ Cloud Files client library used internally
 import socket
 import os
 import logging
+from functools import wraps
 
 from urllib import quote as _quote
 from urlparse import urlparse, urlunparse
@@ -81,9 +82,17 @@ def quote(value, safe='/'):
     """
     Patched version of urllib.quote that encodes utf8 strings before quoting
     """
+    value = encode_utf8(value)
+    if isinstance(value, str):
+        return _quote(value, safe)
+    else:
+        return value
+
+
+def encode_utf8(value):
     if isinstance(value, unicode):
         value = value.encode('utf8')
-    return _quote(value, safe)
+    return value
 
 
 # look for a real json parser first
@@ -161,6 +170,7 @@ def http_connection(url, proxy=None):
     :returns: tuple of (parsed url, connection object)
     :raises ClientException: Unable to handle protocol scheme
     """
+    url = encode_utf8(url)
     parsed = urlparse(url)
     proxy_parsed = urlparse(proxy) if proxy else None
     if parsed.scheme == 'http':
@@ -170,6 +180,25 @@ def http_connection(url, proxy=None):
     else:
         raise ClientException('Cannot handle protocol scheme %s for url %s' %
                               (parsed.scheme, repr(url)))
+
+    def putheader_wrapper(func):
+
+        @wraps(func)
+        def putheader_escaped(key, value):
+            func(encode_utf8(key), encode_utf8(value))
+        return putheader_escaped
+    conn.putheader = putheader_wrapper(conn.putheader)
+
+    def request_wrapper(func):
+
+        @wraps(func)
+        def request_escaped(method, url, body=None, headers=None):
+            url = encode_utf8(url)
+            if body:
+                body = encode_utf8(body)
+            func(method, url, body=body, headers=headers or {})
+        return request_escaped
+    conn.request = request_wrapper(conn.request)
     if proxy:
         conn._set_tunnel(parsed.hostname, parsed.port)
     return parsed, conn
diff --git a/tests/test_swiftclient.py b/tests/test_swiftclient.py
index 121456c1..aad6e249 100644
--- a/tests/test_swiftclient.py
+++ b/tests/test_swiftclient.py
@@ -15,6 +15,7 @@
 
 # TODO: More tests
 import socket
+import StringIO
 import unittest
 from urlparse import urlparse
 
@@ -121,6 +122,24 @@ class MockHttpTest(unittest.TestCase):
         reload(c)
 
 
+class MockHttpResponse():
+    def __init__(self):
+        self.status = 200
+        self.buffer = []
+
+    def read(self):
+        return ""
+
+    def getheader(self, name, default):
+        return ""
+
+    def fake_response(self):
+        return MockHttpResponse()
+
+    def fake_send(self, msg):
+        self.buffer.append(msg)
+
+
 class TestHttpHelpers(MockHttpTest):
 
     def test_quote(self):
@@ -360,6 +379,26 @@ class TestPutObject(MockHttpTest):
         value = c.put_object(*args)
         self.assertTrue(isinstance(value, basestring))
 
+    def test_unicode_ok(self):
+        conn = c.http_connection(u'http://www.test.com/')
+        file = StringIO.StringIO(u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91')
+        args = (u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
+                '\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
+                u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
+                u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
+                file)
+        headers = {'X-Header1': u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
+                   'X-2': 1, 'X-3': {'a': 'b'}, 'a-b': '.x:yz mn:fg:lp'}
+
+        resp = MockHttpResponse()
+        conn[1].getresponse = resp.fake_response
+        conn[1].send = resp.fake_send
+        value = c.put_object(*args, headers=headers, http_conn=conn)
+        self.assertTrue(isinstance(value, basestring))
+        # Test for RFC-2616 encoded symbols
+        self.assertTrue("a-b: .x:yz mn:fg:lp" in resp.buffer[0],
+                      "[a-b: .x:yz mn:fg:lp] header is missing")
+
     def test_server_error(self):
         body = 'c' * 60
         c.http_connection = self.fake_http_connection(500, body=body)
@@ -378,6 +417,23 @@ class TestPostObject(MockHttpTest):
         args = ('http://www.test.com', 'asdf', 'asdf', 'asdf', {})
         value = c.post_object(*args)
 
+    def test_unicode_ok(self):
+        conn = c.http_connection(u'http://www.test.com/')
+        args = (u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
+                '\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
+                u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
+                u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91')
+        headers = {'X-Header1': u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
+                   'X-2': 1, 'X-3': {'a': 'b'}, 'a-b': '.x:yz mn:kl:qr'}
+
+        resp = MockHttpResponse()
+        conn[1].getresponse = resp.fake_response
+        conn[1].send = resp.fake_send
+        c.post_object(*args, headers=headers, http_conn=conn)
+        # Test for RFC-2616 encoded symbols
+        self.assertTrue("a-b: .x:yz mn:kl:qr" in resp.buffer[0],
+                      "[a-b: .x:yz mn:kl:qr] header is missing")
+
     def test_server_error(self):
         body = 'c' * 60
         c.http_connection = self.fake_http_connection(500, body=body)