|
35 | 35 |
|
36 | 36 | from swift.common import utils, constraints
|
37 | 37 | from swift.common.storage_policy import BindPortsCache
|
38 |
| -from swift.common.swob import Request, wsgi_unquote |
| 38 | +from swift.common.swob import Request, wsgi_quote, wsgi_unquote, \ |
| 39 | + wsgi_quote_plus, wsgi_unquote_plus, wsgi_to_bytes, bytes_to_wsgi |
39 | 40 | from swift.common.utils import capture_stdio, disable_fallocate, \
|
40 | 41 | drop_privileges, get_logger, NullLogger, config_true_value, \
|
41 | 42 | validate_configuration, get_hub, config_auto_int_value, \
|
@@ -433,6 +434,36 @@ def get_default_type(self):
|
433 | 434 | '''If the client didn't provide a content type, leave it blank.'''
|
434 | 435 | return ''
|
435 | 436 |
|
| 437 | + def parse_request(self): |
| 438 | + if not six.PY2: |
| 439 | + # request lines *should* be ascii per the RFC, but historically |
| 440 | + # we've allowed (and even have func tests that use) arbitrary |
| 441 | + # bytes. This breaks on py3 (see https://bugs.python.org/issue33973 |
| 442 | + # ) but the work-around is simple: munge the request line to be |
| 443 | + # properly quoted. py2 will do the right thing without this, but it |
| 444 | + # doesn't hurt to re-write the request line like this and it |
| 445 | + # simplifies testing. |
| 446 | + if self.raw_requestline.count(b' ') >= 2: |
| 447 | + parts = self.raw_requestline.split(b' ', 2) |
| 448 | + path, q, query = parts[1].partition(b'?') |
| 449 | + # unquote first, so we don't over-quote something |
| 450 | + # that was *correctly* quoted |
| 451 | + path = wsgi_to_bytes(wsgi_quote(wsgi_unquote( |
| 452 | + bytes_to_wsgi(path)))) |
| 453 | + query = b'&'.join( |
| 454 | + sep.join([ |
| 455 | + wsgi_to_bytes(wsgi_quote_plus(wsgi_unquote_plus( |
| 456 | + bytes_to_wsgi(key)))), |
| 457 | + wsgi_to_bytes(wsgi_quote_plus(wsgi_unquote_plus( |
| 458 | + bytes_to_wsgi(val)))) |
| 459 | + ]) |
| 460 | + for part in query.split(b'&') |
| 461 | + for key, sep, val in (part.partition(b'='), )) |
| 462 | + parts[1] = path + q + query |
| 463 | + self.raw_requestline = b' '.join(parts) |
| 464 | + # else, mangled protocol, most likely; let base class deal with it |
| 465 | + return wsgi.HttpProtocol.parse_request(self) |
| 466 | + |
436 | 467 |
|
437 | 468 | class SwiftHttpProxiedProtocol(SwiftHttpProtocol):
|
438 | 469 | """
|
|
0 commit comments