Repository: mozilla-services/requests-hawk

Issue:
POST with json body not working
What is the correct syntax to send post with JSON? 
The below command works fine with other authentication POST requests like basic, diges, jwt plugin and many more but not with hawk
I am trying to work with post request with json body 

echo '{"hello": "world"}' | http POST http://localhost:8080/ --auth-type=hawk --auth 'username:password'

http: error: TypeError: a bytes-like object is required, not 'str'

GET WORKS FINE
http GET http://localhost:8080/ --auth-type=hawk --auth 'username:password'                                                      
HTTP/1.1 200                                                                                                                                                                                          
Cache-Control: no-cache, no-store, max-age=0, must-revalidate                                                                                                                                         
Content-Type: application/json;charset=UTF-8                                                                                                                                                          
Date: Fri, 10 Jul 2020 00:55:04 GMT                                                                                                                                                                   
Expires: 0                                                                                                                                                                                            
Pragma: no-cache                                                                                                                                                                                      
Transfer-Encoding: chunked                                                                                                                                                                            
X-Content-Type-Options: nosniff                                                                                                                                                                       
X-Frame-Options: DENY                                                                                                                                                                                 
X-XSS-Protection: 1; mode=block                                                                                                                                                                       
                                                                                                                                                                                                      
{                                                                                                                                                                                                     
    "auth_details": "Hawk mac=\"vt5k/EXix//GYELPtcH/vIUK2iVHmFT4p9y8FAlfDl0=\", hash=\"B0weSUXsMcb5UhL41FZbrUJCAotzSI3HawE1NPLRUz8=\", id=\"username\", ts=\"1594342504\", nonce=\"v3z28M\"",         
    "body_info": null,                                                                                                                                                                                
    "host_info": "localhost:8080",                                                                                                                                                                    
    "id": 4,                                                                                                                                                                                          
    "method_info": "GET",                                                                                                                                                                             
    "path_info": "/",                                                                                                                                                                                 
    "protocol_info": "http",                                                                                                                                                                          
    "query_params": null                                                                                                                                                                              
}                                                                                                                                                                                                     

Discussion:

Patch:
diff --git a/CHANGES.txt b/CHANGES.txt
index 10950c3..1ce7404 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,11 @@
 CHANGELOG
 =========
 
+1.1.1 (unreleased)
+------------------
+
+- Handle cases where Content-Type is defined as bytes rather than string. (#25)
+
 1.1.0 (2020-12-16)
 ------------------
 
diff --git a/requests_hawk/__init__.py b/requests_hawk/__init__.py
index 4b3110b..1541b23 100644
--- a/requests_hawk/__init__.py
+++ b/requests_hawk/__init__.py
@@ -73,12 +73,16 @@ class HawkAuth(AuthBase):
         if self.host is not None:
             r.headers['Host'] = self.host
 
+        content_type = r.headers.get("Content-Type") or ""
+        if not isinstance(content_type, text_type):
+            content_type = content_type.decode("utf-8")
+
         sender = mohawk.Sender(
             self.credentials,
             r.url,
             r.method,
             content=r.body or EmptyValue,
-            content_type=r.headers.get("Content-Type", EmptyValue),
+            content_type=content_type or EmptyValue,
             always_hash_content=self.always_hash_content,
             _timestamp=self._timestamp
         )


Test patch:
diff --git a/requests_hawk/tests/test_hawkauth.py b/requests_hawk/tests/test_hawkauth.py
index 3d9a251..38b2635 100644
--- a/requests_hawk/tests/test_hawkauth.py
+++ b/requests_hawk/tests/test_hawkauth.py
@@ -101,3 +101,12 @@ class TestHawkAuth(unittest.TestCase):
         request = Request('GET', 'http://www.example.com', auth=auth)
         r = request.prepare()
         self.assertNotIn('hash="', r.headers['Authorization'])
+
+    def test_hawk_auth_supports_binary_content_type(self):
+        headers = {'Content-Type': b'application/json'}
+        auth = HawkAuth(id='test_id', key='test_key')
+        request = Request('POST', 'https://example.com', auth=auth,
+                          headers=headers, data=b"data")
+        r = request.prepare()
+        auth_header = r.headers['Authorization']
+        self.assertTrue('id="test_id"' in auth_header, "ID doesn't match")