Repository: falconry/falcon

Issue:
More complex example crashes on any request
I tried to get the [more complex example](https://falcon.readthedocs.org/en/stable/user/quickstart.html#more-features) working and encountered the following error on any request:

```
2016-04-16 18:23:44 +0200] [13566] [ERROR] Error handling request /
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/gunicorn/workers/sync.py", line 130, in handle
    self.handle_request(listener, req, client, addr)
  File "/Library/Python/2.7/site-packages/gunicorn/workers/sync.py", line 171, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/Library/Python/2.7/site-packages/falcon/api.py", line 167, in __call__
    self._call_req_mw(middleware_stack, req, resp)
  File "/Library/Python/2.7/site-packages/falcon/api.py", line 535, in _call_req_mw
    process_request(req, resp)
  File "/Users/gigi/Development/newspaper3k-api-using-falcon/more-complex-example.py", line 61, in process_request
    href='http://docs.example.com/auth')
TypeError: __init__() takes exactly 4 arguments (3 given)
```



Discussion:
I was able to reproduce the problem. The complex example was not updated to reflect changes since 0.3.


Resolving patch:
diff --git a/falcon/errors.py b/falcon/errors.py
--- a/falcon/errors.py
+++ b/falcon/errors.py
@@ -52,7 +52,8 @@ class HTTPUnauthorized(HTTPError):
             a helpful suggestion or two.
         challenges (iterable of str): One or more authentication
             challenges to use as the value of the WWW-Authenticate header in
-            the response.
+            the response. See also:
+            http://tools.ietf.org/html/rfc7235#section-2.1
         kwargs (optional): Same as for ``HTTPError``.
 
     """


Test patch:
diff --git a/tests/test_example.py b/tests/test_example.py
--- a/tests/test_example.py
+++ b/tests/test_example.py
@@ -49,8 +49,10 @@ def __call__(self, req, resp, engine):
 class AuthMiddleware(object):
 
     def process_request(self, req, resp):
-        token = req.get_header('X-Auth-Token')
-        project = req.get_header('X-Project-ID')
+        token = req.get_header('Authorization')
+        account_id = req.get_header('Account-ID')
+
+        challenges = ['Token type="Fernet"']
 
         if token is None:
             description = ('Please provide an auth token '
@@ -58,18 +60,19 @@ def process_request(self, req, resp):
 
             raise falcon.HTTPUnauthorized('Auth token required',
                                           description,
+                                          challenges,
                                           href='http://docs.example.com/auth')
 
-        if not self._token_is_valid(token, project):
+        if not self._token_is_valid(token, account_id):
             description = ('The provided auth token is not valid. '
                            'Please request a new token and try again.')
 
             raise falcon.HTTPUnauthorized('Authentication required',
                                           description,
-                                          href='http://docs.example.com/auth',
-                                          scheme='Token; UUID')
+                                          challenges,
+                                          href='http://docs.example.com/auth')
 
-    def _token_is_valid(self, token, project):
+    def _token_is_valid(self, token, account_id):
         return True  # Suuuuuure it's valid...
 
 
@@ -135,7 +138,7 @@ def hook(req, resp, resource, params):
     return hook
 
 
-class ThingsResource:
+class ThingsResource(object):
 
     def __init__(self, db):
         self.db = db
@@ -165,7 +168,7 @@ def on_get(self, req, resp, user_id):
         # that would serialize to JSON under the covers.
         req.context['result'] = result
 
-        resp.set_header('X-Powered-By', 'Small Furry Creatures')
+        resp.set_header('Powered-By', 'Falcon')
         resp.status = falcon.HTTP_200
 
     @falcon.before(max_body(64 * 1024))
@@ -204,7 +207,10 @@ def on_post(self, req, resp, user_id):
 sink = SinkAdapter()
 app.add_sink(sink, r'/search/(?P<engine>ddg|y)\Z')
 
-# Useful for debugging problems in your API; works with pdb.set_trace()
+# Useful for debugging problems in your API; works with pdb.set_trace(). You
+# can also use Gunicorn to host your app. Gunicorn can be configured to
+# auto-restart workers when it detects a code change, and it also works
+# with pdb.
 if __name__ == '__main__':
     httpd = simple_server.make_server('127.0.0.1', 8000, app)
     httpd.serve_forever()
diff --git a/tests/test_httperror.py b/tests/test_httperror.py
--- a/tests/test_httperror.py
+++ b/tests/test_httperror.py
@@ -73,18 +73,18 @@ class UnauthorizedResource:
 
     def on_get(self, req, resp):
         raise falcon.HTTPUnauthorized('Authentication Required',
-                                      'Missing or invalid token header.',
+                                      'Missing or invalid authorization.',
                                       ['Basic realm="simple"'])
 
     def on_post(self, req, resp):
         raise falcon.HTTPUnauthorized('Authentication Required',
-                                      'Missing or invalid token header.',
+                                      'Missing or invalid authorization.',
                                       ['Newauth realm="apps"',
                                        'Basic realm="simple"'])
 
     def on_put(self, req, resp):
         raise falcon.HTTPUnauthorized('Authentication Required',
-                                      'Missing or invalid token header.', [])
+                                      'Missing or invalid authorization.', [])
 
 
 class NotFoundResource: