Skip to content

Commit 5e3e9a8

Browse files
committed
local WSGI Request and Response classes
This change replaces WebOb with a mostly compatible local library, swift.common.swob. Subtle changes to WebOb's API over the years have been a huge headache. Swift doesn't even run on the current version. There are a few incompatibilities to simplify the implementation/interface: * It only implements the header properties we use. More can be easily added. * Casts header values to str on assignment. * Response classes ("HTTPNotFound") are no longer subclasses, but partials on Response, so things like isinstance no longer work on them. * Unlike newer webob versions, will never return unicode objects. Change-Id: I76617a0903ee2286b25a821b3c935c86ff95233f
1 parent f0bd91d commit 5e3e9a8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1448
-225
lines changed

doc/source/debian_package_guide.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Instructions for Building Debian Packages for Swift
5858
apt-get install python-software-properties
5959
add-apt-repository ppa:swift-core/release
6060
apt-get update
61-
apt-get install curl gcc bzr python-configobj python-coverage python-dev python-nose python-setuptools python-simplejson python-xattr python-webob python-eventlet python-greenlet debhelper python-sphinx python-all python-openssl python-pastedeploy python-netifaces bzr-builddeb
61+
apt-get install curl gcc bzr python-configobj python-coverage python-dev python-nose python-setuptools python-simplejson python-xattr python-eventlet python-greenlet debhelper python-sphinx python-all python-openssl python-pastedeploy python-netifaces bzr-builddeb
6262

6363
* As you
6464

@@ -105,7 +105,7 @@ Instructions for Deploying Debian Packages for Swift
105105

106106
#. Install dependencies::
107107
108-
apt-get install rsync python-openssl python-setuptools python-webob
108+
apt-get install rsync python-openssl python-setuptools
109109
python-simplejson python-xattr python-greenlet python-eventlet
110110
python-netifaces
111111

doc/source/development_auth.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,15 @@ Example Authentication with TempAuth:
6363

6464
Authorization is performed through callbacks by the Swift Proxy server to the
6565
WSGI environment's swift.authorize value, if one is set. The swift.authorize
66-
value should simply be a function that takes a webob.Request as an argument and
66+
value should simply be a function that takes a Request as an argument and
6767
returns None if access is granted or returns a callable(environ,
6868
start_response) if access is denied. This callable is a standard WSGI callable.
6969
Generally, you should return 403 Forbidden for requests by an authenticated
7070
user and 401 Unauthorized for an unauthenticated request. For example, here's
7171
an authorize function that only allows GETs (in this case you'd probably return
7272
405 Method Not Allowed, but ignore that for the moment).::
7373

74-
from webob.exc import HTTPForbidden, HTTPUnauthorized
74+
from swift.common.swob import HTTPForbidden, HTTPUnauthorized
7575

7676

7777
def authorize(req):
@@ -87,7 +87,7 @@ middleware as authentication and authorization are often paired together. But,
8787
you could create separate authorization middleware that simply sets the
8888
callback before passing on the request. To continue our example above::
8989

90-
from webob.exc import HTTPForbidden, HTTPUnauthorized
90+
from swift.common.swob import HTTPForbidden, HTTPUnauthorized
9191

9292

9393
class Authorization(object):
@@ -127,7 +127,7 @@ then swift.authorize will be called once more. These are called delay_denial
127127
requests and currently include container read requests and object read and
128128
write requests. For these requests, the read or write access control string
129129
(X-Container-Read and X-Container-Write) will be fetched and set as the 'acl'
130-
attribute in the webob.Request passed to swift.authorize.
130+
attribute in the Request passed to swift.authorize.
131131

132132
The delay_denial procedures allow skipping possibly expensive access control
133133
string retrievals for requests that can be approved without that information,
@@ -138,7 +138,7 @@ control string set to same value as the authenticated user string. Note that
138138
you probably wouldn't do this exactly as the access control string represents a
139139
list rather than a single user, but it'll suffice for this example::
140140

141-
from webob.exc import HTTPForbidden, HTTPUnauthorized
141+
from swift.common.swob import HTTPForbidden, HTTPUnauthorized
142142

143143

144144
class Authorization(object):
@@ -185,7 +185,7 @@ Let's continue our example to use parse_acl and referrer_allowed. Now we'll
185185
only allow GETs after a referrer check and any requests after a group check::
186186

187187
from swift.common.middleware.acl import parse_acl, referrer_allowed
188-
from webob.exc import HTTPForbidden, HTTPUnauthorized
188+
from swift.common.swob import HTTPForbidden, HTTPUnauthorized
189189

190190

191191
class Authorization(object):
@@ -235,7 +235,7 @@ standard Swift format. Let's improve our example by making use of that::
235235

236236
from swift.common.middleware.acl import \
237237
clean_acl, parse_acl, referrer_allowed
238-
from webob.exc import HTTPForbidden, HTTPUnauthorized
238+
from swift.common.swob import HTTPForbidden, HTTPUnauthorized
239239

240240

241241
class Authorization(object):
@@ -293,7 +293,7 @@ folks a start on their own code if they want to use repoze.what::
293293
from swift.common.bufferedhttp import http_connect_raw as http_connect
294294
from swift.common.middleware.acl import clean_acl, parse_acl, referrer_allowed
295295
from swift.common.utils import cache_from_env, split_path
296-
from webob.exc import HTTPForbidden, HTTPUnauthorized
296+
from swift.common.swob import HTTPForbidden, HTTPUnauthorized
297297

298298

299299
class DevAuthorization(object):

doc/source/development_saio.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ Installing dependencies and the core code
3030
#. `apt-get update`
3131
#. `apt-get install curl gcc git-core memcached python-configobj
3232
python-coverage python-dev python-nose python-setuptools python-simplejson
33-
python-xattr sqlite3 xfsprogs python-webob python-eventlet
34-
python-greenlet python-pastedeploy python-netifaces python-pip`
33+
python-xattr sqlite3 xfsprogs python-eventlet python-greenlet
34+
python-pastedeploy python-netifaces python-pip`
3535
#. `pip install mock`
3636
#. Install anything else you want, like screen, ssh, vim, etc.
3737

doc/source/getting_started.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ most Linux platforms with the following software:
1515
And the following python libraries:
1616

1717
* Eventlet 0.9.8
18-
* WebOb 0.9.8
1918
* Setuptools
2019
* Simplejson
2120
* Xattr

swift/account/server.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@
2222
from xml.sax import saxutils
2323

2424
from eventlet import Timeout
25-
from webob import Request, Response
26-
from webob.exc import HTTPAccepted, HTTPBadRequest, \
27-
HTTPCreated, HTTPForbidden, HTTPInternalServerError, \
28-
HTTPMethodNotAllowed, HTTPNoContent, HTTPNotFound, \
29-
HTTPPreconditionFailed, HTTPConflict
3025

3126
import swift.common.db
3227
from swift.common.db import AccountBroker
@@ -36,7 +31,11 @@
3631
from swift.common.constraints import ACCOUNT_LISTING_LIMIT, \
3732
check_mount, check_float, check_utf8, FORMAT2CONTENT_TYPE
3833
from swift.common.db_replicator import ReplicatorRpc
39-
from swift.common.http import HTTPInsufficientStorage
34+
from swift.common.swob import HTTPAccepted, HTTPBadRequest, \
35+
HTTPCreated, HTTPForbidden, HTTPInternalServerError, \
36+
HTTPMethodNotAllowed, HTTPNoContent, HTTPNotFound, \
37+
HTTPPreconditionFailed, HTTPConflict, Request, Response, \
38+
HTTPInsufficientStorage
4039

4140

4241
DATADIR = 'accounts'

swift/common/constraints.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from ConfigParser import ConfigParser, NoSectionError, NoOptionError, \
1818
RawConfigParser
1919

20-
from webob.exc import HTTPBadRequest, HTTPLengthRequired, \
20+
from swift.common.swob import HTTPBadRequest, HTTPLengthRequired, \
2121
HTTPRequestEntityTooLarge
2222

2323
constraints_conf = ConfigParser()

swift/common/db_replicator.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,18 @@
2626
from eventlet import GreenPool, sleep, Timeout
2727
from eventlet.green import subprocess
2828
import simplejson
29-
from webob import Response
30-
from webob.exc import HTTPNotFound, HTTPNoContent, HTTPAccepted, \
31-
HTTPInsufficientStorage, HTTPBadRequest
3229

3330
import swift.common.db
3431
from swift.common.utils import get_logger, whataremyips, storage_directory, \
3532
renamer, mkdirs, lock_parent_directory, TRUE_VALUES, unlink_older_than, \
3633
dump_recon_cache, rsync_ip
3734
from swift.common import ring
35+
from swift.common.http import HTTP_NOT_FOUND, HTTP_INSUFFICIENT_STORAGE
3836
from swift.common.bufferedhttp import BufferedHTTPConnection
3937
from swift.common.exceptions import DriveNotMounted, ConnectionTimeout
4038
from swift.common.daemon import Daemon
39+
from swift.common.swob import Response, HTTPNotFound, HTTPNoContent, \
40+
HTTPAccepted, HTTPInsufficientStorage, HTTPBadRequest
4141

4242

4343
DEBUG_TIMINGS_THRESHOLD = 10
@@ -324,11 +324,11 @@ def _repl_to_node(self, node, broker, partition, info):
324324
info['delete_timestamp'], info['metadata'])
325325
if not response:
326326
return False
327-
elif response.status == HTTPNotFound.code: # completely missing, rsync
327+
elif response.status == HTTP_NOT_FOUND: # completely missing, rsync
328328
self.stats['rsync'] += 1
329329
self.logger.increment('rsyncs')
330330
return self._rsync_db(broker, node, http, info['id'])
331-
elif response.status == HTTPInsufficientStorage.code:
331+
elif response.status == HTTP_INSUFFICIENT_STORAGE:
332332
raise DriveNotMounted()
333333
elif response.status >= 200 and response.status < 300:
334334
rinfo = simplejson.loads(response.data)

swift/common/http.py

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,40 +13,6 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
from webob.exc import HTTPClientError,\
17-
HTTPInsufficientStorage as BaseHTTPInsufficientStorage
18-
19-
20-
class HTTPClientDisconnect(HTTPClientError):
21-
"""
22-
subclass of :class:`~HTTPClientError`
23-
24-
This code is introduced to log the case when the connection is closed by
25-
client while HTTP server is processing its request
26-
27-
code: 499, title: Client Disconnect
28-
"""
29-
code = 499
30-
title = 'Client Disconnect'
31-
explanation = (
32-
'This code is introduced to log the case when the connection '
33-
'is closed by client while HTTP server is processing its request')
34-
35-
36-
class HTTPInsufficientStorage(BaseHTTPInsufficientStorage):
37-
"""
38-
subclass of :class:`~HTTPInsufficientStorage`
39-
40-
The server is unable to store the representation needed to
41-
complete the request.
42-
43-
code: 507, title: Insufficient Storage
44-
"""
45-
def __init__(self, drive=None, *args, **kwargs):
46-
if drive:
47-
self.explanation = ('%s is not mounted' % drive)
48-
super(HTTPInsufficientStorage, self).__init__(*args, **kwargs)
49-
5016

5117
def is_informational(status):
5218
"""

swift/common/internal_client.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@
1919
import struct
2020
from sys import exc_info
2121
from urllib import quote
22-
from webob import Request
2322
import zlib
2423
from zlib import compressobj
2524

26-
2725
from swift.common.http import HTTP_NOT_FOUND
26+
from swift.common.swob import Request
2827

2928

3029
class UnexpectedResponse(Exception):

swift/common/middleware/catch_errors.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@
1414
# limitations under the License.
1515

1616
from eventlet import Timeout
17-
from webob import Request
18-
from webob.exc import HTTPServerError
1917
import uuid
2018

19+
from swift.common.swob import Request, HTTPServerError
2120
from swift.common.utils import get_logger
2221

2322

swift/common/middleware/cname_lookup.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
rewritten and the request is passed further down the WSGI chain.
2828
"""
2929

30-
from webob import Request
31-
from webob.exc import HTTPBadRequest
3230
try:
3331
import dns.resolver
3432
from dns.exception import DNSException
@@ -39,6 +37,7 @@
3937
else: # executed if the try block finishes with no errors
4038
MODULE_DEPENDENCY_MET = True
4139

40+
from swift.common.swob import Request, HTTPBadRequest
4241
from swift.common.utils import cache_from_env, get_logger
4342

4443

swift/common/middleware/domain_remap.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@
4949
sync destinations.
5050
"""
5151

52-
from webob import Request
53-
from webob.exc import HTTPBadRequest
52+
from swift.common.swob import Request, HTTPBadRequest
5453

5554

5655
class DomainRemapMiddleware(object):

swift/common/middleware/healthcheck.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
from webob import Request, Response
16+
from swift.common.swob import Request, Response
1717

1818

1919
class HealthCheckMiddleware(object):

swift/common/middleware/keystoneauth.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@
1414
# License for the specific language governing permissions and limitations
1515
# under the License.
1616

17-
import webob
18-
1917
from swift.common import utils as swift_utils
2018
from swift.common.middleware import acl as swift_acl
19+
from swift.common.swob import HTTPNotFound, HTTPForbidden, HTTPUnauthorized
2120

2221

2322
class KeystoneAuth(object):
@@ -153,7 +152,7 @@ def authorize(self, req):
153152
part = swift_utils.split_path(req.path, 1, 4, True)
154153
version, account, container, obj = part
155154
except ValueError:
156-
return webob.exc.HTTPNotFound(request=req)
155+
return HTTPNotFound(request=req)
157156

158157
user_roles = env_identity.get('roles', [])
159158

@@ -226,7 +225,7 @@ def authorize_anonymous(self, req):
226225
part = swift_utils.split_path(req.path, 1, 4, True)
227226
version, account, container, obj = part
228227
except ValueError:
229-
return webob.exc.HTTPNotFound(request=req)
228+
return HTTPNotFound(request=req)
230229

231230
is_authoritative_authz = (account and
232231
account.startswith(self.reseller_prefix))
@@ -274,9 +273,9 @@ def denied_response(self, req):
274273
depending on whether the REMOTE_USER is set or not.
275274
"""
276275
if req.remote_user:
277-
return webob.exc.HTTPForbidden(request=req)
276+
return HTTPForbidden(request=req)
278277
else:
279-
return webob.exc.HTTPUnauthorized(request=req)
278+
return HTTPUnauthorized(request=req)
280279

281280

282281
def filter_factory(global_conf, **local_conf):

swift/common/middleware/name_check.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,11 @@
3838

3939
import re
4040
from swift.common.utils import get_logger
41-
from webob import Request
42-
from webob.exc import HTTPBadRequest
4341
from urllib2 import unquote
4442

43+
from swift.common.swob import Request, HTTPBadRequest
44+
45+
4546
FORBIDDEN_CHARS = "\'\"`<>"
4647
MAX_LENGTH = 255
4748
FORBIDDEN_REGEXP = "/\./|/\.\./|/\.$|/\.\.$"

swift/common/middleware/proxy_logging.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@
4040
import time
4141
from urllib import quote, unquote
4242

43-
from webob import Request
44-
43+
from swift.common.swob import Request
4544
from swift.common.utils import (get_logger, get_remote_client,
4645
get_valid_utf8_str, TRUE_VALUES)
4746

swift/common/middleware/ratelimit.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
# limitations under the License.
1414
import time
1515
import eventlet
16-
from webob import Request, Response
1716

1817
from swift.common.utils import split_path, cache_from_env, get_logger
1918
from swift.proxy.controllers.base import get_container_memcache_key
2019
from swift.common.memcached import MemcacheConnectionError
20+
from swift.common.swob import Request, Response
2121

2222

2323
class MaxSleepTimeHitError(Exception):
@@ -205,7 +205,7 @@ def handle_ratelimit(self, req, account_name, container_name, obj_name):
205205
def __call__(self, env, start_response):
206206
"""
207207
WSGI entry point.
208-
Wraps env in webob.Request object and passes it down.
208+
Wraps env in swob.Request object and passes it down.
209209
210210
:param env: WSGI environment dictionary
211211
:param start_response: WSGI callable

swift/common/middleware/recon.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import errno
1717
import os
1818

19-
from webob import Request, Response
19+
from swift.common.swob import Request, Response
2020
from swift.common.utils import split_path, get_logger, TRUE_VALUES
2121
from swift.common.constraints import check_mount
2222
from resource import getpagesize

swift/common/middleware/staticweb.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,13 @@
118118
import time
119119
from urllib import unquote, quote as urllib_quote
120120

121-
from webob import Response
122-
from webob.exc import HTTPMovedPermanently, HTTPNotFound
123121

124122
from swift.common.utils import cache_from_env, get_logger, human_readable, \
125123
split_path, TRUE_VALUES
126124
from swift.common.wsgi import make_pre_authed_env, make_pre_authed_request, \
127125
WSGIContext
128126
from swift.common.http import is_success, is_redirection, HTTP_NOT_FOUND
127+
from swift.common.swob import Response, HTTPMovedPermanently, HTTPNotFound
129128

130129

131130
def quote(value, safe='/'):

0 commit comments

Comments
 (0)