Merge "HTTP status value naming normalization"
This commit is contained in:
commit
96476846b6
@ -36,6 +36,7 @@ from swift.common.utils import get_logger, get_param, hash_path, \
|
||||
from swift.common.constraints import ACCOUNT_LISTING_LIMIT, \
|
||||
check_mount, check_float, check_utf8
|
||||
from swift.common.db_replicator import ReplicatorRpc
|
||||
from swift.common.http import HTTPInsufficientStorage
|
||||
|
||||
|
||||
DATADIR = 'accounts'
|
||||
@ -70,7 +71,7 @@ class AccountController(object):
|
||||
return HTTPBadRequest(body=str(err), content_type='text/plain',
|
||||
request=req)
|
||||
if self.mount_check and not check_mount(self.root, drive):
|
||||
return Response(status='507 %s is not mounted' % drive)
|
||||
return HTTPInsufficientStorage(drive=drive, request=req)
|
||||
if 'x-timestamp' not in req.headers or \
|
||||
not check_float(req.headers['x-timestamp']):
|
||||
return HTTPBadRequest(body='Missing timestamp', request=req,
|
||||
@ -90,7 +91,7 @@ class AccountController(object):
|
||||
return HTTPBadRequest(body=str(err), content_type='text/plain',
|
||||
request=req)
|
||||
if self.mount_check and not check_mount(self.root, drive):
|
||||
return Response(status='507 %s is not mounted' % drive)
|
||||
return HTTPInsufficientStorage(drive=drive, request=req)
|
||||
broker = self._get_account_broker(drive, part, account)
|
||||
if container: # put account container
|
||||
if 'x-trans-id' in req.headers:
|
||||
@ -149,7 +150,7 @@ class AccountController(object):
|
||||
return HTTPBadRequest(body=str(err), content_type='text/plain',
|
||||
request=req)
|
||||
if self.mount_check and not check_mount(self.root, drive):
|
||||
return Response(status='507 %s is not mounted' % drive)
|
||||
return HTTPInsufficientStorage(drive=drive, request=req)
|
||||
broker = self._get_account_broker(drive, part, account)
|
||||
if not container:
|
||||
broker.pending_timeout = 0.1
|
||||
@ -180,7 +181,7 @@ class AccountController(object):
|
||||
return HTTPBadRequest(body=str(err), content_type='text/plain',
|
||||
request=req)
|
||||
if self.mount_check and not check_mount(self.root, drive):
|
||||
return Response(status='507 %s is not mounted' % drive)
|
||||
return HTTPInsufficientStorage(drive=drive, request=req)
|
||||
broker = self._get_account_broker(drive, part, account)
|
||||
broker.pending_timeout = 0.1
|
||||
broker.stale_reads_ok = True
|
||||
@ -274,7 +275,7 @@ class AccountController(object):
|
||||
request=req)
|
||||
drive, partition, hash = post_args
|
||||
if self.mount_check and not check_mount(self.root, drive):
|
||||
return Response(status='507 %s is not mounted' % drive)
|
||||
return HTTPInsufficientStorage(drive=drive, request=req)
|
||||
try:
|
||||
args = simplejson.load(req.environ['wsgi.input'])
|
||||
except ValueError, err:
|
||||
@ -295,7 +296,7 @@ class AccountController(object):
|
||||
return HTTPBadRequest(body='Missing or bad timestamp',
|
||||
request=req, content_type='text/plain')
|
||||
if self.mount_check and not check_mount(self.root, drive):
|
||||
return Response(status='507 %s is not mounted' % drive)
|
||||
return HTTPInsufficientStorage(drive=drive, request=req)
|
||||
broker = self._get_account_broker(drive, part, account)
|
||||
if broker.is_deleted():
|
||||
return HTTPNotFound(request=req)
|
||||
|
@ -24,6 +24,7 @@ from eventlet.green.httplib import CannotSendRequest
|
||||
from swift.common.utils import TRUE_VALUES
|
||||
from swift.common import client
|
||||
from swift.common import direct_client
|
||||
from swift.common.http import HTTP_CONFLICT
|
||||
|
||||
|
||||
class ConnectionPool(eventlet.pools.Pool):
|
||||
@ -152,7 +153,7 @@ class BenchDELETE(Bench):
|
||||
try:
|
||||
client.delete_container(self.url, self.token, container)
|
||||
except client.ClientException, e:
|
||||
if e.http_status != 409:
|
||||
if e.http_status != HTTP_CONFLICT:
|
||||
self._log_status("Unable to delete container '%s'. " \
|
||||
"Got http status '%d'." % (container, e.http_status))
|
||||
|
||||
|
@ -28,6 +28,8 @@ from eventlet import sleep, Timeout
|
||||
from swift.common.bufferedhttp import http_connect
|
||||
from swift.common.client import ClientException, json_loads
|
||||
from swift.common.utils import normalize_timestamp
|
||||
from swift.common.http import HTTP_NO_CONTENT, HTTP_INSUFFICIENT_STORAGE, \
|
||||
is_success, is_server_error
|
||||
|
||||
|
||||
def quote(value, safe='/'):
|
||||
@ -69,7 +71,7 @@ def direct_get_account(node, part, account, marker=None, limit=None,
|
||||
'GET', path, query_string=qs)
|
||||
with Timeout(response_timeout):
|
||||
resp = conn.getresponse()
|
||||
if resp.status < 200 or resp.status >= 300:
|
||||
if not is_success(resp.status):
|
||||
resp.read()
|
||||
raise ClientException(
|
||||
'Account server %s:%s direct GET %s gave status %s' % (node['ip'],
|
||||
@ -81,7 +83,7 @@ def direct_get_account(node, part, account, marker=None, limit=None,
|
||||
resp_headers = {}
|
||||
for header, value in resp.getheaders():
|
||||
resp_headers[header.lower()] = value
|
||||
if resp.status == 204:
|
||||
if resp.status == HTTP_NO_CONTENT:
|
||||
resp.read()
|
||||
return resp_headers, []
|
||||
return resp_headers, json_loads(resp.read())
|
||||
@ -108,7 +110,7 @@ def direct_head_container(node, part, account, container, conn_timeout=5,
|
||||
with Timeout(response_timeout):
|
||||
resp = conn.getresponse()
|
||||
resp.read()
|
||||
if resp.status < 200 or resp.status >= 300:
|
||||
if not is_success(resp.status):
|
||||
raise ClientException(
|
||||
'Container server %s:%s direct HEAD %s gave status %s' %
|
||||
(node['ip'], node['port'],
|
||||
@ -157,7 +159,7 @@ def direct_get_container(node, part, account, container, marker=None,
|
||||
'GET', path, query_string=qs)
|
||||
with Timeout(response_timeout):
|
||||
resp = conn.getresponse()
|
||||
if resp.status < 200 or resp.status >= 300:
|
||||
if not is_success(resp.status):
|
||||
resp.read()
|
||||
raise ClientException(
|
||||
'Container server %s:%s direct GET %s gave stats %s' % (node['ip'],
|
||||
@ -169,7 +171,7 @@ def direct_get_container(node, part, account, container, marker=None,
|
||||
resp_headers = {}
|
||||
for header, value in resp.getheaders():
|
||||
resp_headers[header.lower()] = value
|
||||
if resp.status == 204:
|
||||
if resp.status == HTTP_NO_CONTENT:
|
||||
resp.read()
|
||||
return resp_headers, []
|
||||
return resp_headers, json_loads(resp.read())
|
||||
@ -185,7 +187,7 @@ def direct_delete_container(node, part, account, container, conn_timeout=5,
|
||||
with Timeout(response_timeout):
|
||||
resp = conn.getresponse()
|
||||
resp.read()
|
||||
if resp.status < 200 or resp.status >= 300:
|
||||
if not is_success(resp.status):
|
||||
raise ClientException(
|
||||
'Container server %s:%s direct DELETE %s gave status %s' %
|
||||
(node['ip'], node['port'],
|
||||
@ -218,7 +220,7 @@ def direct_head_object(node, part, account, container, obj, conn_timeout=5,
|
||||
with Timeout(response_timeout):
|
||||
resp = conn.getresponse()
|
||||
resp.read()
|
||||
if resp.status < 200 or resp.status >= 300:
|
||||
if not is_success(resp.status):
|
||||
raise ClientException(
|
||||
'Object server %s:%s direct HEAD %s gave status %s' %
|
||||
(node['ip'], node['port'],
|
||||
@ -256,7 +258,7 @@ def direct_get_object(node, part, account, container, obj, conn_timeout=5,
|
||||
'GET', path, headers=headers)
|
||||
with Timeout(response_timeout):
|
||||
resp = conn.getresponse()
|
||||
if resp.status < 200 or resp.status >= 300:
|
||||
if not is_success(resp.status):
|
||||
resp.read()
|
||||
raise ClientException(
|
||||
'Object server %s:%s direct GET %s gave status %s' %
|
||||
@ -326,7 +328,7 @@ def direct_put_object(node, part, account, container, name, contents,
|
||||
with Timeout(response_timeout):
|
||||
resp = conn.getresponse()
|
||||
resp.read()
|
||||
if resp.status < 200 or resp.status >= 300:
|
||||
if not is_success(resp.status):
|
||||
raise ClientException(
|
||||
'Object server %s:%s direct PUT %s gave status %s' %
|
||||
(node['ip'], node['port'],
|
||||
@ -361,7 +363,7 @@ def direct_post_object(node, part, account, container, name, headers,
|
||||
with Timeout(response_timeout):
|
||||
resp = conn.getresponse()
|
||||
resp.read()
|
||||
if resp.status < 200 or resp.status >= 300:
|
||||
if not is_success(resp.status):
|
||||
raise ClientException(
|
||||
'Object server %s:%s direct POST %s gave status %s' %
|
||||
(node['ip'], node['port'],
|
||||
@ -394,7 +396,7 @@ def direct_delete_object(node, part, account, container, obj,
|
||||
with Timeout(response_timeout):
|
||||
resp = conn.getresponse()
|
||||
resp.read()
|
||||
if resp.status < 200 or resp.status >= 300:
|
||||
if not is_success(resp.status):
|
||||
raise ClientException(
|
||||
'Object server %s:%s direct DELETE %s gave status %s' %
|
||||
(node['ip'], node['port'],
|
||||
@ -440,8 +442,8 @@ def retry(func, *args, **kwargs):
|
||||
except ClientException, err:
|
||||
if error_log:
|
||||
error_log(err)
|
||||
if attempts > retries or err.http_status < 500 or \
|
||||
err.http_status == 507 or err.http_status > 599:
|
||||
if attempts > retries or not is_server_error(err.http_status) or \
|
||||
err.http_status == HTTP_INSUFFICIENT_STORAGE:
|
||||
raise
|
||||
sleep(backoff)
|
||||
backoff *= 2
|
||||
|
193
swift/common/http.py
Normal file
193
swift/common/http.py
Normal file
@ -0,0 +1,193 @@
|
||||
# Copyright (c) 2010-2012 OpenStack, LLC.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from webob.exc import HTTPClientError,\
|
||||
HTTPInsufficientStorage as BaseHTTPInsufficientStorage
|
||||
|
||||
|
||||
class HTTPClientDisconnect(HTTPClientError):
|
||||
"""
|
||||
subclass of :class:`~HTTPClientError`
|
||||
|
||||
This code is introduced to log the case when the connection is closed by
|
||||
client while HTTP server is processing its request
|
||||
|
||||
code: 499, title: Client Disconnect
|
||||
"""
|
||||
code = 499
|
||||
title = 'Client Disconnect'
|
||||
explanation = (
|
||||
'This code is introduced to log the case when the connection '
|
||||
'is closed by client while HTTP server is processing its request')
|
||||
|
||||
|
||||
class HTTPInsufficientStorage(BaseHTTPInsufficientStorage):
|
||||
"""
|
||||
subclass of :class:`~HTTPInsufficientStorage`
|
||||
|
||||
The server is unable to store the representation needed to
|
||||
complete the request.
|
||||
|
||||
code: 507, title: Insufficient Storage
|
||||
"""
|
||||
def __init__(self, drive=None, *args, **kwargs):
|
||||
if drive:
|
||||
self.explanation = ('%s is not mounted' % drive)
|
||||
super(HTTPInsufficientStorage, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
def is_informational(status):
|
||||
"""
|
||||
Check if HTTP status code is informational.
|
||||
|
||||
:param status: http status code
|
||||
:returns: True if status is successful, else False
|
||||
"""
|
||||
return 100 <= status and status <= 199
|
||||
|
||||
|
||||
def is_success(status):
|
||||
"""
|
||||
Check if HTTP status code is successful.
|
||||
|
||||
:param status: http status code
|
||||
:returns: True if status is successful, else False
|
||||
"""
|
||||
return 200 <= status and status <= 299
|
||||
|
||||
|
||||
def is_redirection(status):
|
||||
"""
|
||||
Check if HTTP status code is redirection.
|
||||
|
||||
:param status: http status code
|
||||
:returns: True if status is redirection, else False
|
||||
"""
|
||||
return 300 <= status and status <= 399
|
||||
|
||||
|
||||
def is_client_error(status):
|
||||
"""
|
||||
Check if HTTP status code is client error.
|
||||
|
||||
:param status: http status code
|
||||
:returns: True if status is client error, else False
|
||||
"""
|
||||
return 400 <= status and status <= 499
|
||||
|
||||
|
||||
def is_server_error(status):
|
||||
"""
|
||||
Check if HTTP status code is server error.
|
||||
|
||||
:param status: http status code
|
||||
:returns: True if status is server error, else False
|
||||
"""
|
||||
return 500 <= status and status <= 599
|
||||
|
||||
|
||||
# List of HTTP status codes
|
||||
|
||||
###############################################################################
|
||||
## 1xx Informational
|
||||
###############################################################################
|
||||
|
||||
HTTP_CONTINUE = 100
|
||||
HTTP_SWITCHING_PROTOCOLS = 101
|
||||
HTTP_PROCESSING = 102 # WebDAV
|
||||
HTTP_CHECKPOINT = 103
|
||||
HTTP_REQUEST_URI_TOO_LONG = 122
|
||||
|
||||
###############################################################################
|
||||
## 2xx Success
|
||||
###############################################################################
|
||||
|
||||
HTTP_OK = 200
|
||||
HTTP_CREATED = 201
|
||||
HTTP_ACCEPTED = 202
|
||||
HTTP_NON_AUTHORITATIVE_INFORMATION = 203
|
||||
HTTP_NO_CONTENT = 204
|
||||
HTTP_RESET_CONTENT = 205
|
||||
HTTP_PARTIAL_CONTENT = 206
|
||||
HTTP_MULTI_STATUS = 207 # WebDAV
|
||||
HTTP_IM_USED = 226
|
||||
|
||||
###############################################################################
|
||||
## 3xx Redirection
|
||||
###############################################################################
|
||||
|
||||
HTTP_MULTIPLE_CHOICES = 300
|
||||
HTTP_MOVED_PERMANENTLY = 301
|
||||
HTTP_FOUND = 302
|
||||
HTTP_SEE_OTHER = 303
|
||||
HTTP_NOT_MODIFIED = 304
|
||||
HTTP_USE_PROXY = 305
|
||||
HTTP_SWITCH_PROXY = 306
|
||||
HTTP_TEMPORARY_REDIRECT = 307
|
||||
HTTP_RESUME_INCOMPLETE = 308
|
||||
|
||||
###############################################################################
|
||||
## 4xx Client Error
|
||||
###############################################################################
|
||||
|
||||
HTTP_BAD_REQUEST = 400
|
||||
HTTP_UNAUTHORIZED = 401
|
||||
HTTP_PAYMENT_REQUIRED = 402
|
||||
HTTP_FORBIDDEN = 403
|
||||
HTTP_NOT_FOUND = 404
|
||||
HTTP_METHOD_NOT_ALLOWED = 405
|
||||
HTTP_NOT_ACCEPTABLE = 406
|
||||
HTTP_PROXY_AUTHENTICATION_REQUIRED = 407
|
||||
HTTP_REQUEST_TIMEOUT = 408
|
||||
HTTP_CONFLICT = 409
|
||||
HTTP_GONE = 410
|
||||
HTTP_LENGTH_REQUIRED = 411
|
||||
HTTP_PRECONDITION_FAILED = 412
|
||||
HTTP_REQUEST_ENTITY_TOO_LARGE = 413
|
||||
HTTP_REQUEST_URI_TOO_LONG = 414
|
||||
HTTP_UNSUPPORTED_MEDIA_TYPE = 415
|
||||
HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416
|
||||
HTTP_EXPECTATION_FAILED = 417
|
||||
HTTP_IM_A_TEAPOT = 418
|
||||
HTTP_UNPROCESSABLE_ENTITY = 422 # WebDAV
|
||||
HTTP_LOCKED = 423 # WebDAV
|
||||
HTTP_FAILED_DEPENDENCY = 424 # WebDAV
|
||||
HTTP_UNORDERED_COLLECTION = 425
|
||||
HTTP_UPGRADE_REQUIED = 426
|
||||
HTTP_PRECONDITION_REQUIRED = 428
|
||||
HTTP_TOO_MANY_REQUESTS = 429
|
||||
HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
|
||||
HTTP_NO_RESPONSE = 444
|
||||
HTTP_RETRY_WITH = 449
|
||||
HTTP_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS = 450
|
||||
HTTP_CLIENT_CLOSED_REQUEST = 499
|
||||
|
||||
###############################################################################
|
||||
## 5xx Server Error
|
||||
###############################################################################
|
||||
|
||||
HTTP_INTERNAL_SERVER_ERROR = 500
|
||||
HTTP_NOT_IMPLEMENTED = 501
|
||||
HTTP_BAD_GATEWAY = 502
|
||||
HTTP_SERVICE_UNAVAILABLE = 503
|
||||
HTTP_GATEWAY_TIMEOUT = 504
|
||||
HTTP_VERSION_NOT_SUPPORTED = 505
|
||||
HTTP_VARIANT_ALSO_NEGOTIATES = 506
|
||||
HTTP_INSUFFICIENT_STORAGE = 507 # WebDAV
|
||||
HTTP_BANDWIDTH_LIMIT_EXCEEDED = 509
|
||||
HTTP_NOT_EXTENDED = 510
|
||||
HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511
|
||||
HTTP_NETWORK_READ_TIMEOUT_ERROR = 598 # not used in RFC
|
||||
HTTP_NETWORK_CONNECT_TIMEOUT_ERROR = 599 # not used in RFC
|
@ -112,6 +112,7 @@ from urllib import quote, unquote
|
||||
|
||||
from swift.common.utils import get_logger, streq_const_time
|
||||
from swift.common.wsgi import make_pre_authed_env
|
||||
from swift.common.http import HTTP_BAD_REQUEST
|
||||
|
||||
|
||||
#: The size of data to read from the form at any given time.
|
||||
@ -324,7 +325,7 @@ class FormPost(object):
|
||||
return self._translate_form(env, start_response,
|
||||
attrs['boundary'])
|
||||
except (FormInvalid, EOFError), err:
|
||||
self._log_request(env, 400)
|
||||
self._log_request(env, HTTP_BAD_REQUEST)
|
||||
body = 'FormPost: %s' % err
|
||||
start_response('400 Bad Request',
|
||||
(('Content-Type', 'text/plain'),
|
||||
|
@ -125,6 +125,7 @@ from swift.common.utils import cache_from_env, get_logger, human_readable, \
|
||||
split_path, TRUE_VALUES
|
||||
from swift.common.wsgi import make_pre_authed_env, make_pre_authed_request, \
|
||||
WSGIContext
|
||||
from swift.common.http import is_success, is_redirection, HTTP_NOT_FOUND
|
||||
|
||||
|
||||
def quote(value, safe='/'):
|
||||
@ -183,7 +184,7 @@ class _StaticWebContext(WSGIContext):
|
||||
'/%s/%s/%s/%s%s' % (self.version, self.account, self.container,
|
||||
self._get_status_int(), self._error),
|
||||
self.agent))
|
||||
if self._get_status_int() // 100 == 2:
|
||||
if is_success(self._get_status_int()):
|
||||
start_response(save_response_status, self._response_headers,
|
||||
self._response_exc_info)
|
||||
return resp
|
||||
@ -213,7 +214,7 @@ class _StaticWebContext(WSGIContext):
|
||||
resp = make_pre_authed_request(env, 'HEAD',
|
||||
'/%s/%s/%s' % (self.version, self.account, self.container),
|
||||
agent=self.agent).get_response(self.app)
|
||||
if resp.status_int // 100 == 2:
|
||||
if is_success(resp.status_int):
|
||||
self._index = \
|
||||
resp.headers.get('x-container-meta-web-index', '').strip()
|
||||
self._error = \
|
||||
@ -249,7 +250,7 @@ class _StaticWebContext(WSGIContext):
|
||||
else:
|
||||
prefix = ''
|
||||
resp = self._app_call(tmp_env)
|
||||
if self._get_status_int() // 100 != 2:
|
||||
if not is_success(self._get_status_int()):
|
||||
return self._error_response(resp, env, start_response)
|
||||
listing = None
|
||||
body = ''.join(resp)
|
||||
@ -363,9 +364,10 @@ class _StaticWebContext(WSGIContext):
|
||||
tmp_env['PATH_INFO'] += self._index
|
||||
resp = self._app_call(tmp_env)
|
||||
status_int = self._get_status_int()
|
||||
if status_int == 404:
|
||||
if status_int == HTTP_NOT_FOUND:
|
||||
return self._listing(env, start_response)
|
||||
elif self._get_status_int() // 100 not in (2, 3):
|
||||
elif not is_success(self._get_status_int()) or \
|
||||
not is_redirection(self._get_status_int()):
|
||||
return self._error_response(resp, env, start_response)
|
||||
start_response(self._response_status, self._response_headers,
|
||||
self._response_exc_info)
|
||||
@ -384,16 +386,16 @@ class _StaticWebContext(WSGIContext):
|
||||
'%s StaticWeb' % env.get('HTTP_USER_AGENT')
|
||||
resp = self._app_call(tmp_env)
|
||||
status_int = self._get_status_int()
|
||||
if status_int // 100 in (2, 3):
|
||||
if is_success(status_int) or is_redirection(status_int):
|
||||
start_response(self._response_status, self._response_headers,
|
||||
self._response_exc_info)
|
||||
return resp
|
||||
if status_int != 404:
|
||||
if status_int != HTTP_NOT_FOUND:
|
||||
return self._error_response(resp, env, start_response)
|
||||
self._get_container_info(env)
|
||||
if not self._listings and not self._index:
|
||||
return self.app(env, start_response)
|
||||
status_int = 404
|
||||
status_int = HTTP_NOT_FOUND
|
||||
if self._index:
|
||||
tmp_env = dict(env)
|
||||
tmp_env['HTTP_USER_AGENT'] = \
|
||||
@ -403,7 +405,7 @@ class _StaticWebContext(WSGIContext):
|
||||
tmp_env['PATH_INFO'] += self._index
|
||||
resp = self._app_call(tmp_env)
|
||||
status_int = self._get_status_int()
|
||||
if status_int // 100 in (2, 3):
|
||||
if is_success(status_int) or is_redirection(status_int):
|
||||
if env['PATH_INFO'][-1] != '/':
|
||||
resp = HTTPMovedPermanently(
|
||||
location=env['PATH_INFO'] + '/')
|
||||
@ -412,7 +414,7 @@ class _StaticWebContext(WSGIContext):
|
||||
start_response(self._response_status, self._response_headers,
|
||||
self._response_exc_info)
|
||||
return resp
|
||||
if status_int == 404:
|
||||
if status_int == HTTP_NOT_FOUND:
|
||||
if env['PATH_INFO'][-1] != '/':
|
||||
tmp_env = make_pre_authed_env(env, 'GET',
|
||||
'/%s/%s/%s' % (self.version, self.account,
|
||||
@ -422,7 +424,7 @@ class _StaticWebContext(WSGIContext):
|
||||
'=/&limit=1&prefix=%s' % quote(self.obj + '/')
|
||||
resp = self._app_call(tmp_env)
|
||||
body = ''.join(resp)
|
||||
if self._get_status_int() // 100 != 2 or not body or \
|
||||
if not is_success(self._get_status_int()) or not body or \
|
||||
not json.loads(body):
|
||||
resp = HTTPNotFound()(env, self._start_response)
|
||||
return self._error_response(resp, env, start_response)
|
||||
|
@ -60,6 +60,9 @@ from simplejson import loads
|
||||
|
||||
from swift.common.utils import split_path
|
||||
from swift.common.wsgi import WSGIContext
|
||||
from swift.common.http import HTTP_OK, HTTP_CREATED, HTTP_ACCEPTED, \
|
||||
HTTP_NO_CONTENT, HTTP_BAD_REQUEST, HTTP_UNAUTHORIZED, HTTP_FORBIDDEN, \
|
||||
HTTP_NOT_FOUND, HTTP_CONFLICT, is_success
|
||||
|
||||
|
||||
MAX_BUCKET_LISTING = 1000
|
||||
@ -74,24 +77,24 @@ def get_err_response(code):
|
||||
"""
|
||||
error_table = {
|
||||
'AccessDenied':
|
||||
(403, 'Access denied'),
|
||||
(HTTP_FORBIDDEN, 'Access denied'),
|
||||
'BucketAlreadyExists':
|
||||
(409, 'The requested bucket name is not available'),
|
||||
(HTTP_CONFLICT, 'The requested bucket name is not available'),
|
||||
'BucketNotEmpty':
|
||||
(409, 'The bucket you tried to delete is not empty'),
|
||||
(HTTP_CONFLICT, 'The bucket you tried to delete is not empty'),
|
||||
'InvalidArgument':
|
||||
(400, 'Invalid Argument'),
|
||||
(HTTP_BAD_REQUEST, 'Invalid Argument'),
|
||||
'InvalidBucketName':
|
||||
(400, 'The specified bucket is not valid'),
|
||||
(HTTP_BAD_REQUEST, 'The specified bucket is not valid'),
|
||||
'InvalidURI':
|
||||
(400, 'Could not parse the specified URI'),
|
||||
(HTTP_BAD_REQUEST, 'Could not parse the specified URI'),
|
||||
'NoSuchBucket':
|
||||
(404, 'The specified bucket does not exist'),
|
||||
(HTTP_NOT_FOUND, 'The specified bucket does not exist'),
|
||||
'SignatureDoesNotMatch':
|
||||
(403, 'The calculated request signature does not match '\
|
||||
'your provided one'),
|
||||
(HTTP_FORBIDDEN, 'The calculated request signature does not '\
|
||||
'match your provided one'),
|
||||
'NoSuchKey':
|
||||
(404, 'The resource you requested does not exist')}
|
||||
(HTTP_NOT_FOUND, 'The resource you requested does not exist')}
|
||||
|
||||
resp = Response(content_type='text/xml')
|
||||
resp.status = error_table[code][0]
|
||||
@ -169,8 +172,8 @@ class ServiceController(WSGIContext):
|
||||
body_iter = self._app_call(env)
|
||||
status = self._get_status_int()
|
||||
|
||||
if status != 200:
|
||||
if status == 401:
|
||||
if status != HTTP_OK:
|
||||
if status == HTTP_UNAUTHORIZED:
|
||||
return get_err_response('AccessDenied')
|
||||
else:
|
||||
return get_err_response('InvalidURI')
|
||||
@ -186,7 +189,8 @@ class ServiceController(WSGIContext):
|
||||
% ("".join(['<Bucket><Name>%s</Name><CreationDate>' \
|
||||
'2009-02-03T16:45:09.000Z</CreationDate></Bucket>' %
|
||||
xml_escape(i['name']) for i in containers]))
|
||||
resp = Response(status=200, content_type='application/xml', body=body)
|
||||
resp = Response(status=HTTP_OK, content_type='application/xml',
|
||||
body=body)
|
||||
return resp
|
||||
|
||||
|
||||
@ -222,10 +226,10 @@ class BucketController(WSGIContext):
|
||||
body_iter = self._app_call(env)
|
||||
status = self._get_status_int()
|
||||
|
||||
if status != 200:
|
||||
if status == 401:
|
||||
if status != HTTP_OK:
|
||||
if status == HTTP_UNAUTHORIZED:
|
||||
return get_err_response('AccessDenied')
|
||||
elif status == 404:
|
||||
elif status == HTTP_NOT_FOUND:
|
||||
return get_err_response('NoSuchBucket')
|
||||
else:
|
||||
return get_err_response('InvalidURI')
|
||||
@ -271,17 +275,17 @@ class BucketController(WSGIContext):
|
||||
body_iter = self._app_call(env)
|
||||
status = self._get_status_int()
|
||||
|
||||
if status != 201:
|
||||
if status == 401:
|
||||
if status != HTTP_CREATED:
|
||||
if status == HTTP_UNAUTHORIZED:
|
||||
return get_err_response('AccessDenied')
|
||||
elif status == 202:
|
||||
elif status == HTTP_ACCEPTED:
|
||||
return get_err_response('BucketAlreadyExists')
|
||||
else:
|
||||
return get_err_response('InvalidURI')
|
||||
|
||||
resp = Response()
|
||||
resp.headers.add('Location', self.container_name)
|
||||
resp.status = 200
|
||||
resp.status = HTTP_OK
|
||||
return resp
|
||||
|
||||
def DELETE(self, env, start_response):
|
||||
@ -291,18 +295,18 @@ class BucketController(WSGIContext):
|
||||
body_iter = self._app_call(env)
|
||||
status = self._get_status_int()
|
||||
|
||||
if status != 204:
|
||||
if status == 401:
|
||||
if status != HTTP_NO_CONTENT:
|
||||
if status == HTTP_UNAUTHORIZED:
|
||||
return get_err_response('AccessDenied')
|
||||
elif status == 404:
|
||||
elif status == HTTP_NOT_FOUND:
|
||||
return get_err_response('NoSuchBucket')
|
||||
elif status == 409:
|
||||
elif status == HTTP_CONFLICT:
|
||||
return get_err_response('BucketNotEmpty')
|
||||
else:
|
||||
return get_err_response('InvalidURI')
|
||||
|
||||
resp = Response()
|
||||
resp.status = 204
|
||||
resp.status = HTTP_NO_CONTENT
|
||||
return resp
|
||||
|
||||
|
||||
@ -324,7 +328,7 @@ class ObjectController(WSGIContext):
|
||||
status = self._get_status_int()
|
||||
headers = dict(self._response_headers)
|
||||
|
||||
if 200 <= status < 300:
|
||||
if is_success(status):
|
||||
if 'QUERY_STRING' in env:
|
||||
args = dict(urlparse.parse_qsl(env['QUERY_STRING'], 1))
|
||||
else:
|
||||
@ -342,9 +346,9 @@ class ObjectController(WSGIContext):
|
||||
'etag', 'last-modified'):
|
||||
new_hdrs[key] = val
|
||||
return Response(status=status, headers=new_hdrs, app_iter=app_iter)
|
||||
elif status == 401:
|
||||
elif status == HTTP_UNAUTHORIZED:
|
||||
return get_err_response('AccessDenied')
|
||||
elif status == 404:
|
||||
elif status == HTTP_NOT_FOUND:
|
||||
return get_err_response('NoSuchKey')
|
||||
else:
|
||||
return get_err_response('InvalidURI')
|
||||
@ -377,10 +381,10 @@ class ObjectController(WSGIContext):
|
||||
body_iter = self._app_call(env)
|
||||
status = self._get_status_int()
|
||||
|
||||
if status != 201:
|
||||
if status == 401:
|
||||
if status != HTTP_CREATED:
|
||||
if status == HTTP_UNAUTHORIZED:
|
||||
return get_err_response('AccessDenied')
|
||||
elif status == 404:
|
||||
elif status == HTTP_NOT_FOUND:
|
||||
return get_err_response('NoSuchBucket')
|
||||
else:
|
||||
return get_err_response('InvalidURI')
|
||||
@ -389,7 +393,7 @@ class ObjectController(WSGIContext):
|
||||
body = '<CopyObjectResult>' \
|
||||
'<ETag>"%s"</ETag>' \
|
||||
'</CopyObjectResult>' % self._response_header_value('etag')
|
||||
return Response(status=200, body=body)
|
||||
return Response(status=HTTP_OK, body=body)
|
||||
|
||||
return Response(status=200, etag=self._response_header_value('etag'))
|
||||
|
||||
@ -400,16 +404,16 @@ class ObjectController(WSGIContext):
|
||||
body_iter = self._app_call(env)
|
||||
status = self._get_status_int()
|
||||
|
||||
if status != 204:
|
||||
if status == 401:
|
||||
if status != HTTP_NO_CONTENT:
|
||||
if status == HTTP_UNAUTHORIZED:
|
||||
return get_err_response('AccessDenied')
|
||||
elif status == 404:
|
||||
elif status == HTTP_NOT_FOUND:
|
||||
return get_err_response('NoSuchKey')
|
||||
else:
|
||||
return get_err_response('InvalidURI')
|
||||
|
||||
resp = Response()
|
||||
resp.status = 204
|
||||
resp.status = HTTP_NO_CONTENT
|
||||
return resp
|
||||
|
||||
|
||||
|
@ -29,6 +29,7 @@ from webob.exc import HTTPBadRequest, HTTPForbidden, HTTPNotFound, \
|
||||
from swift.common.middleware.acl import clean_acl, parse_acl, referrer_allowed
|
||||
from swift.common.utils import cache_from_env, get_logger, get_remote_client, \
|
||||
split_path, TRUE_VALUES
|
||||
from swift.common.http import HTTP_CLIENT_CLOSED_REQUEST
|
||||
|
||||
|
||||
class TempAuth(object):
|
||||
@ -458,7 +459,7 @@ class TempAuth(object):
|
||||
status_int = response.status_int
|
||||
if getattr(req, 'client_disconnect', False) or \
|
||||
getattr(response, 'client_disconnect', False):
|
||||
status_int = 499
|
||||
status_int = HTTP_CLIENT_CLOSED_REQUEST
|
||||
self.logger.info(' '.join(quote(str(x)) for x in (client or '-',
|
||||
req.remote_addr or '-', strftime('%d/%b/%Y/%H/%M/%S', gmtime()),
|
||||
req.method, the_request, req.environ['SERVER_PROTOCOL'],
|
||||
|
@ -88,6 +88,7 @@ from urlparse import parse_qs
|
||||
|
||||
from swift.common.utils import get_logger
|
||||
from swift.common.wsgi import make_pre_authed_env
|
||||
from swift.common.http import HTTP_UNAUTHORIZED
|
||||
|
||||
|
||||
#: Default headers to remove from incoming requests. Simply a whitespace
|
||||
@ -376,7 +377,7 @@ class TempURL(object):
|
||||
:param start_response: The WSGI start_response hook.
|
||||
:returns: 401 response as per WSGI.
|
||||
"""
|
||||
self._log_request(env, 401)
|
||||
self._log_request(env, HTTP_UNAUTHORIZED)
|
||||
body = '401 Unauthorized: Temp URL invalid\n'
|
||||
start_response('401 Unauthorized',
|
||||
[('Content-Type', 'text/plain'),
|
||||
|
@ -39,6 +39,8 @@ from swift.common.constraints import CONTAINER_LISTING_LIMIT, \
|
||||
from swift.common.bufferedhttp import http_connect
|
||||
from swift.common.exceptions import ConnectionTimeout
|
||||
from swift.common.db_replicator import ReplicatorRpc
|
||||
from swift.common.http import HTTP_NOT_FOUND, is_success, \
|
||||
HTTPInsufficientStorage
|
||||
|
||||
DATADIR = 'containers'
|
||||
|
||||
@ -119,10 +121,9 @@ class ContainerController(object):
|
||||
with Timeout(self.node_timeout):
|
||||
account_response = conn.getresponse()
|
||||
account_response.read()
|
||||
if account_response.status == 404:
|
||||
if account_response.status == HTTP_NOT_FOUND:
|
||||
return HTTPNotFound(request=req)
|
||||
elif account_response.status < 200 or \
|
||||
account_response.status > 299:
|
||||
elif not is_success(account_response.status):
|
||||
self.logger.error(_('ERROR Account update failed '
|
||||
'with %(ip)s:%(port)s/%(device)s (will retry '
|
||||
'later): Response %(status)s %(reason)s'),
|
||||
@ -150,7 +151,7 @@ class ContainerController(object):
|
||||
return HTTPBadRequest(body='Missing timestamp', request=req,
|
||||
content_type='text/plain')
|
||||
if self.mount_check and not check_mount(self.root, drive):
|
||||
return Response(status='507 %s is not mounted' % drive)
|
||||
return HTTPInsufficientStorage(drive=drive, request=req)
|
||||
broker = self._get_container_broker(drive, part, account, container)
|
||||
if account.startswith(self.auto_create_account_prefix) and obj and \
|
||||
not os.path.exists(broker.db_file):
|
||||
@ -195,7 +196,7 @@ class ContainerController(object):
|
||||
if err:
|
||||
return HTTPBadRequest(err)
|
||||
if self.mount_check and not check_mount(self.root, drive):
|
||||
return Response(status='507 %s is not mounted' % drive)
|
||||
return HTTPInsufficientStorage(drive=drive, request=req)
|
||||
timestamp = normalize_timestamp(req.headers['x-timestamp'])
|
||||
broker = self._get_container_broker(drive, part, account, container)
|
||||
if obj: # put container object
|
||||
@ -245,7 +246,7 @@ class ContainerController(object):
|
||||
return HTTPBadRequest(body=str(err), content_type='text/plain',
|
||||
request=req)
|
||||
if self.mount_check and not check_mount(self.root, drive):
|
||||
return Response(status='507 %s is not mounted' % drive)
|
||||
return HTTPInsufficientStorage(drive=drive, request=req)
|
||||
broker = self._get_container_broker(drive, part, account, container)
|
||||
broker.pending_timeout = 0.1
|
||||
broker.stale_reads_ok = True
|
||||
@ -273,7 +274,7 @@ class ContainerController(object):
|
||||
return HTTPBadRequest(body=str(err), content_type='text/plain',
|
||||
request=req)
|
||||
if self.mount_check and not check_mount(self.root, drive):
|
||||
return Response(status='507 %s is not mounted' % drive)
|
||||
return HTTPInsufficientStorage(drive=drive, request=req)
|
||||
broker = self._get_container_broker(drive, part, account, container)
|
||||
broker.pending_timeout = 0.1
|
||||
broker.stale_reads_ok = True
|
||||
@ -388,7 +389,7 @@ class ContainerController(object):
|
||||
request=req)
|
||||
drive, partition, hash = post_args
|
||||
if self.mount_check and not check_mount(self.root, drive):
|
||||
return Response(status='507 %s is not mounted' % drive)
|
||||
return HTTPInsufficientStorage(drive=drive, request=req)
|
||||
try:
|
||||
args = simplejson.load(req.environ['wsgi.input'])
|
||||
except ValueError, err:
|
||||
@ -414,7 +415,7 @@ class ContainerController(object):
|
||||
if err:
|
||||
return HTTPBadRequest(err)
|
||||
if self.mount_check and not check_mount(self.root, drive):
|
||||
return Response(status='507 %s is not mounted' % drive)
|
||||
return HTTPInsufficientStorage(drive=drive, request=req)
|
||||
broker = self._get_container_broker(drive, part, account, container)
|
||||
if broker.is_deleted():
|
||||
return HTTPNotFound(request=req)
|
||||
|
@ -29,6 +29,7 @@ from swift.common.db import ContainerBroker
|
||||
from swift.common.utils import audit_location_generator, get_logger, \
|
||||
hash_path, TRUE_VALUES, validate_sync_to, whataremyips
|
||||
from swift.common.daemon import Daemon
|
||||
from swift.common.http import HTTP_UNAUTHORIZED, HTTP_NOT_FOUND
|
||||
|
||||
|
||||
class _Iter2FileLikeObject(object):
|
||||
@ -349,7 +350,7 @@ class ContainerSync(Daemon):
|
||||
'x-container-sync-key': sync_key},
|
||||
proxy=self.proxy)
|
||||
except ClientException, err:
|
||||
if err.http_status != 404:
|
||||
if err.http_status != HTTP_NOT_FOUND:
|
||||
raise
|
||||
self.container_deletes += 1
|
||||
else:
|
||||
@ -376,7 +377,7 @@ class ContainerSync(Daemon):
|
||||
# non-404 one. We don't want to mistakenly assume the
|
||||
# object no longer exists just because one says so and
|
||||
# the others errored for some other reason.
|
||||
if not exc or exc.http_status == 404:
|
||||
if not exc or exc.http_status == HTTP_NOT_FOUND:
|
||||
exc = err
|
||||
if timestamp < looking_for_timestamp:
|
||||
if exc:
|
||||
@ -398,13 +399,13 @@ class ContainerSync(Daemon):
|
||||
contents=_Iter2FileLikeObject(body), proxy=self.proxy)
|
||||
self.container_puts += 1
|
||||
except ClientException, err:
|
||||
if err.http_status == 401:
|
||||
if err.http_status == HTTP_UNAUTHORIZED:
|
||||
self.logger.info(_('Unauth %(sync_from)r '
|
||||
'=> %(sync_to)r'),
|
||||
{'sync_from': '%s/%s' %
|
||||
(quote(info['account']), quote(info['container'])),
|
||||
'sync_to': sync_to})
|
||||
elif err.http_status == 404:
|
||||
elif err.http_status == HTTP_NOT_FOUND:
|
||||
self.logger.info(_('Not found %(sync_from)r '
|
||||
'=> %(sync_to)r'),
|
||||
{'sync_from': '%s/%s' %
|
||||
|
@ -31,6 +31,7 @@ from swift.common.exceptions import ConnectionTimeout
|
||||
from swift.common.ring import Ring
|
||||
from swift.common.utils import get_logger, TRUE_VALUES
|
||||
from swift.common.daemon import Daemon
|
||||
from swift.common.http import is_success, HTTP_INTERNAL_SERVER_ERROR
|
||||
|
||||
|
||||
class ContainerUpdater(Daemon):
|
||||
@ -214,7 +215,7 @@ class ContainerUpdater(Daemon):
|
||||
successes = 0
|
||||
failures = 0
|
||||
for event in events:
|
||||
if 200 <= event.wait() < 300:
|
||||
if is_success(event.wait()):
|
||||
successes += 1
|
||||
else:
|
||||
failures += 1
|
||||
@ -265,7 +266,7 @@ class ContainerUpdater(Daemon):
|
||||
except (Exception, Timeout):
|
||||
self.logger.exception(_('ERROR account update failed with '
|
||||
'%(ip)s:%(port)s/%(device)s (will retry later): '), node)
|
||||
return 500
|
||||
return HTTP_INTERNAL_SERVER_ERROR
|
||||
with Timeout(self.node_timeout):
|
||||
try:
|
||||
resp = conn.getresponse()
|
||||
@ -275,4 +276,4 @@ class ContainerUpdater(Daemon):
|
||||
if self.logger.getEffectiveLevel() <= logging.DEBUG:
|
||||
self.logger.exception(
|
||||
_('Exception with %(ip)s:%(port)s/%(device)s'), node)
|
||||
return 500
|
||||
return HTTP_INTERNAL_SERVER_ERROR
|
||||
|
@ -24,6 +24,8 @@ from webob import Request
|
||||
|
||||
from swift.common.daemon import Daemon
|
||||
from swift.common.utils import get_logger
|
||||
from swift.common.http import HTTP_NO_CONTENT, HTTP_NOT_FOUND, HTTP_CONFLICT, \
|
||||
HTTP_PRECONDITION_FAILED
|
||||
|
||||
try:
|
||||
import simplejson as json
|
||||
@ -161,8 +163,9 @@ class ObjectExpirer(Daemon):
|
||||
the hidden expiration account.
|
||||
"""
|
||||
resp = self.get_response('HEAD',
|
||||
'/v1/' + quote(self.expiring_objects_account), {}, (2, 404))
|
||||
if resp.status_int == 404:
|
||||
'/v1/' + quote(self.expiring_objects_account), {},
|
||||
(2, HTTP_NOT_FOUND))
|
||||
if resp.status_int == HTTP_NOT_FOUND:
|
||||
return (0, 0)
|
||||
return (int(resp.headers['x-account-container-count']),
|
||||
int(resp.headers['x-account-object-count']))
|
||||
@ -176,8 +179,8 @@ class ObjectExpirer(Daemon):
|
||||
marker = ''
|
||||
while True:
|
||||
resp = self.get_response('GET', path + '&marker=' + quote(marker),
|
||||
{}, (2, 404))
|
||||
if resp.status_int in (204, 404):
|
||||
{}, (2, HTTP_NOT_FOUND))
|
||||
if resp.status_int in (HTTP_NO_CONTENT, HTTP_NOT_FOUND):
|
||||
break
|
||||
data = json.loads(resp.body)
|
||||
if not data:
|
||||
@ -198,8 +201,8 @@ class ObjectExpirer(Daemon):
|
||||
marker = ''
|
||||
while True:
|
||||
resp = self.get_response('GET', path + '&marker=' + quote(marker),
|
||||
{}, (2, 404))
|
||||
if resp.status_int in (204, 404):
|
||||
{}, (2, HTTP_NOT_FOUND))
|
||||
if resp.status_int in (HTTP_NO_CONTENT, HTTP_NOT_FOUND):
|
||||
break
|
||||
data = json.loads(resp.body)
|
||||
if not data:
|
||||
@ -220,7 +223,8 @@ class ObjectExpirer(Daemon):
|
||||
perform the actual delete.
|
||||
"""
|
||||
self.get_response('DELETE', '/v1/%s' % (quote(actual_obj),),
|
||||
{'X-If-Delete-At': str(timestamp)}, (2, 404, 412))
|
||||
{'X-If-Delete-At': str(timestamp)},
|
||||
(2, HTTP_NOT_FOUND, HTTP_PRECONDITION_FAILED))
|
||||
|
||||
def delete_object(self, container, obj):
|
||||
"""
|
||||
@ -232,7 +236,7 @@ class ObjectExpirer(Daemon):
|
||||
self.get_response('DELETE',
|
||||
'/v1/%s/%s/%s' % (quote(self.expiring_objects_account),
|
||||
quote(container), quote(obj)),
|
||||
{}, (2, 404))
|
||||
{}, (2, HTTP_NOT_FOUND))
|
||||
|
||||
def delete_container(self, container):
|
||||
"""
|
||||
@ -243,4 +247,4 @@ class ObjectExpirer(Daemon):
|
||||
self.get_response('DELETE',
|
||||
'/v1/%s/%s' % (quote(self.expiring_objects_account),
|
||||
quote(container)),
|
||||
{}, (2, 404, 409))
|
||||
{}, (2, HTTP_NOT_FOUND, HTTP_CONFLICT))
|
||||
|
@ -36,6 +36,7 @@ from swift.common.utils import whataremyips, unlink_older_than, lock_path, \
|
||||
TRUE_VALUES
|
||||
from swift.common.bufferedhttp import http_connect
|
||||
from swift.common.daemon import Daemon
|
||||
from swift.common.http import HTTP_OK, HTTP_INSUFFICIENT_STORAGE
|
||||
|
||||
hubs.use_hub('poll')
|
||||
|
||||
@ -408,12 +409,12 @@ class ObjectReplicator(Daemon):
|
||||
resp = http_connect(node['ip'], node['port'],
|
||||
node['device'], job['partition'], 'REPLICATE',
|
||||
'', headers={'Content-Length': '0'}).getresponse()
|
||||
if resp.status == 507:
|
||||
if resp.status == HTTP_INSUFFICIENT_STORAGE:
|
||||
self.logger.error(_('%(ip)s/%(device)s responded'
|
||||
' as unmounted'), node)
|
||||
attempts_left += 1
|
||||
continue
|
||||
if resp.status != 200:
|
||||
if resp.status != HTTP_OK:
|
||||
self.logger.error(_("Invalid response %(resp)s "
|
||||
"from %(ip)s"),
|
||||
{'resp': resp.status, 'ip': node['ip']})
|
||||
|
@ -45,6 +45,8 @@ from swift.common.exceptions import ConnectionTimeout, DiskFileError, \
|
||||
DiskFileNotExist
|
||||
from swift.obj.replicator import tpooled_get_hashes, invalidate_hash, \
|
||||
quarantine_renamer
|
||||
from swift.common.http import is_success, HTTPInsufficientStorage, \
|
||||
HTTPClientDisconnect
|
||||
|
||||
|
||||
DATADIR = 'objects'
|
||||
@ -404,7 +406,7 @@ class ObjectController(object):
|
||||
with Timeout(self.node_timeout):
|
||||
response = conn.getresponse()
|
||||
response.read()
|
||||
if 200 <= response.status < 300:
|
||||
if is_success(response.status):
|
||||
return
|
||||
else:
|
||||
self.logger.error(_('ERROR Container update failed '
|
||||
@ -492,7 +494,7 @@ class ObjectController(object):
|
||||
return HTTPBadRequest(body='X-Delete-At in past', request=request,
|
||||
content_type='text/plain')
|
||||
if self.mount_check and not check_mount(self.devices, device):
|
||||
return Response(status='507 %s is not mounted' % device)
|
||||
return HTTPInsufficientStorage(drive=device, request=request)
|
||||
file = DiskFile(self.devices, device, partition, account, container,
|
||||
obj, self.logger, disk_chunk_size=self.disk_chunk_size)
|
||||
|
||||
@ -536,7 +538,7 @@ class ObjectController(object):
|
||||
return HTTPBadRequest(body=str(err), request=request,
|
||||
content_type='text/plain')
|
||||
if self.mount_check and not check_mount(self.devices, device):
|
||||
return Response(status='507 %s is not mounted' % device)
|
||||
return HTTPInsufficientStorage(drive=device, request=request)
|
||||
if 'x-timestamp' not in request.headers or \
|
||||
not check_float(request.headers['x-timestamp']):
|
||||
return HTTPBadRequest(body='Missing timestamp', request=request,
|
||||
@ -575,7 +577,7 @@ class ObjectController(object):
|
||||
|
||||
if 'content-length' in request.headers and \
|
||||
int(request.headers['content-length']) != upload_size:
|
||||
return Response(status='499 Client Disconnect')
|
||||
return HTTPClientDisconnect(request=request)
|
||||
etag = etag.hexdigest()
|
||||
if 'etag' in request.headers and \
|
||||
request.headers['etag'].lower() != etag:
|
||||
@ -625,7 +627,7 @@ class ObjectController(object):
|
||||
return HTTPBadRequest(body=str(err), request=request,
|
||||
content_type='text/plain')
|
||||
if self.mount_check and not check_mount(self.devices, device):
|
||||
return Response(status='507 %s is not mounted' % device)
|
||||
return HTTPInsufficientStorage(drive=device, request=request)
|
||||
file = DiskFile(self.devices, device, partition, account, container,
|
||||
obj, self.logger, keep_data_fp=True,
|
||||
disk_chunk_size=self.disk_chunk_size)
|
||||
@ -701,7 +703,7 @@ class ObjectController(object):
|
||||
resp.body = str(err)
|
||||
return resp
|
||||
if self.mount_check and not check_mount(self.devices, device):
|
||||
return Response(status='507 %s is not mounted' % device)
|
||||
return HTTPInsufficientStorage(drive=device, request=request)
|
||||
file = DiskFile(self.devices, device, partition, account, container,
|
||||
obj, self.logger, disk_chunk_size=self.disk_chunk_size)
|
||||
if file.is_deleted() or ('X-Delete-At' in file.metadata and
|
||||
@ -742,7 +744,7 @@ class ObjectController(object):
|
||||
return HTTPBadRequest(body='Missing timestamp', request=request,
|
||||
content_type='text/plain')
|
||||
if self.mount_check and not check_mount(self.devices, device):
|
||||
return Response(status='507 %s is not mounted' % device)
|
||||
return HTTPInsufficientStorage(drive=device, request=request)
|
||||
response_class = HTTPNoContent
|
||||
file = DiskFile(self.devices, device, partition, account, container,
|
||||
obj, self.logger, disk_chunk_size=self.disk_chunk_size)
|
||||
@ -785,7 +787,7 @@ class ObjectController(object):
|
||||
return HTTPBadRequest(body=str(e), request=request,
|
||||
content_type='text/plain')
|
||||
if self.mount_check and not check_mount(self.devices, device):
|
||||
return Response(status='507 %s is not mounted' % device)
|
||||
return HTTPInsufficientStorage(drive=device, request=request)
|
||||
path = os.path.join(self.devices, device, DATADIR, partition)
|
||||
if not os.path.exists(path):
|
||||
mkdirs(path)
|
||||
|
@ -28,6 +28,8 @@ from swift.common.ring import Ring
|
||||
from swift.common.utils import get_logger, renamer, write_pickle
|
||||
from swift.common.daemon import Daemon
|
||||
from swift.obj.server import ASYNCDIR
|
||||
from swift.common.http import is_success, HTTP_NOT_FOUND, \
|
||||
HTTP_INTERNAL_SERVER_ERROR
|
||||
|
||||
|
||||
class ObjectUpdater(Daemon):
|
||||
@ -178,7 +180,7 @@ class ObjectUpdater(Daemon):
|
||||
if node['id'] not in successes:
|
||||
status = self.object_update(node, part, update['op'], obj,
|
||||
update['headers'])
|
||||
if not (200 <= status < 300) and status != 404:
|
||||
if not is_success(status) and status != HTTP_NOT_FOUND:
|
||||
success = False
|
||||
else:
|
||||
successes.append(node['id'])
|
||||
@ -217,4 +219,4 @@ class ObjectUpdater(Daemon):
|
||||
except (Exception, Timeout):
|
||||
self.logger.exception(_('ERROR with remote server '
|
||||
'%(ip)s:%(port)s/%(device)s'), node)
|
||||
return 500
|
||||
return HTTP_INTERNAL_SERVER_ERROR
|
||||
|
@ -61,6 +61,12 @@ from swift.common.constraints import check_metadata, check_object_creation, \
|
||||
from swift.common.exceptions import ChunkReadTimeout, \
|
||||
ChunkWriteTimeout, ConnectionTimeout, ListingIterNotFound, \
|
||||
ListingIterNotAuthorized, ListingIterError
|
||||
from swift.common.http import is_informational, is_success, is_redirection, \
|
||||
is_client_error, is_server_error, HTTP_CONTINUE, HTTP_OK, HTTP_CREATED, \
|
||||
HTTP_ACCEPTED, HTTP_PARTIAL_CONTENT, HTTP_MULTIPLE_CHOICES, \
|
||||
HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_REQUESTED_RANGE_NOT_SATISFIABLE, \
|
||||
HTTP_CLIENT_CLOSED_REQUEST, HTTP_INTERNAL_SERVER_ERROR, \
|
||||
HTTP_SERVICE_UNAVAILABLE, HTTP_INSUFFICIENT_STORAGE, HTTPClientDisconnect
|
||||
|
||||
|
||||
def update_headers(response, headers):
|
||||
@ -181,7 +187,7 @@ class SegmentedIterable(object):
|
||||
self.controller.iter_nodes(partition, nodes,
|
||||
self.controller.app.object_ring), path,
|
||||
self.controller.app.object_ring.replica_count)
|
||||
if resp.status_int // 100 != 2:
|
||||
if not is_success(resp.status_int):
|
||||
raise Exception(_('Could not load object segment %(path)s:' \
|
||||
' %(status)s') % {'path': path, 'status': resp.status_int})
|
||||
self.segment_iter = resp.app_iter
|
||||
@ -197,7 +203,7 @@ class SegmentedIterable(object):
|
||||
'cont': self.controller.container_name,
|
||||
'obj': self.controller.object_name})
|
||||
err.swift_logged = True
|
||||
self.response.status_int = 503
|
||||
self.response.status_int = HTTP_SERVICE_UNAVAILABLE
|
||||
raise
|
||||
|
||||
def next(self):
|
||||
@ -230,7 +236,7 @@ class SegmentedIterable(object):
|
||||
'cont': self.controller.container_name,
|
||||
'obj': self.controller.object_name})
|
||||
err.swift_logged = True
|
||||
self.response.status_int = 503
|
||||
self.response.status_int = HTTP_SERVICE_UNAVAILABLE
|
||||
raise
|
||||
|
||||
def app_iter_range(self, start, stop):
|
||||
@ -291,7 +297,7 @@ class SegmentedIterable(object):
|
||||
'cont': self.controller.container_name,
|
||||
'obj': self.controller.object_name})
|
||||
err.swift_logged = True
|
||||
self.response.status_int = 503
|
||||
self.response.status_int = HTTP_SERVICE_UNAVAILABLE
|
||||
raise
|
||||
|
||||
|
||||
@ -402,9 +408,9 @@ class Controller(object):
|
||||
else:
|
||||
result_code = cache_value['status']
|
||||
container_count = cache_value['container_count']
|
||||
if result_code == 200:
|
||||
if result_code == HTTP_OK:
|
||||
return partition, nodes, container_count
|
||||
elif result_code == 404 and not autocreate:
|
||||
elif result_code == HTTP_NOT_FOUND and not autocreate:
|
||||
return None, None, None
|
||||
result_code = 0
|
||||
container_count = 0
|
||||
@ -419,17 +425,17 @@ class Controller(object):
|
||||
with Timeout(self.app.node_timeout):
|
||||
resp = conn.getresponse()
|
||||
body = resp.read()
|
||||
if 200 <= resp.status <= 299:
|
||||
result_code = 200
|
||||
if is_success(resp.status):
|
||||
result_code = HTTP_OK
|
||||
container_count = int(
|
||||
resp.getheader('x-account-container-count') or 0)
|
||||
break
|
||||
elif resp.status == 404:
|
||||
elif resp.status == HTTP_NOT_FOUND:
|
||||
if result_code == 0:
|
||||
result_code = 404
|
||||
elif result_code != 404:
|
||||
result_code = HTTP_NOT_FOUND
|
||||
elif result_code != HTTP_NOT_FOUND:
|
||||
result_code = -1
|
||||
elif resp.status == 507:
|
||||
elif resp.status == HTTP_INSUFFICIENT_STORAGE:
|
||||
self.error_limit(node)
|
||||
continue
|
||||
else:
|
||||
@ -440,7 +446,7 @@ class Controller(object):
|
||||
except (Exception, Timeout):
|
||||
self.exception_occurred(node, _('Account'),
|
||||
_('Trying to get account info for %s') % path)
|
||||
if result_code == 404 and autocreate:
|
||||
if result_code == HTTP_NOT_FOUND and autocreate:
|
||||
if len(account) > MAX_ACCOUNT_NAME_LENGTH:
|
||||
return None, None, None
|
||||
headers = {'X-Timestamp': normalize_timestamp(time.time()),
|
||||
@ -449,18 +455,18 @@ class Controller(object):
|
||||
resp = self.make_requests(Request.blank('/v1' + path),
|
||||
self.app.account_ring, partition, 'PUT',
|
||||
path, [headers] * len(nodes))
|
||||
if resp.status_int // 100 != 2:
|
||||
if not is_success(resp.status_int):
|
||||
raise Exception('Could not autocreate account %r' % path)
|
||||
result_code = 200
|
||||
if self.app.memcache and result_code in (200, 404):
|
||||
if result_code == 200:
|
||||
result_code = HTTP_OK
|
||||
if self.app.memcache and result_code in (HTTP_OK, HTTP_NOT_FOUND):
|
||||
if result_code == HTTP_OK:
|
||||
cache_timeout = self.app.recheck_account_existence
|
||||
else:
|
||||
cache_timeout = self.app.recheck_account_existence * 0.1
|
||||
self.app.memcache.set(cache_key,
|
||||
{'status': result_code, 'container_count': container_count},
|
||||
timeout=cache_timeout)
|
||||
if result_code == 200:
|
||||
if result_code == HTTP_OK:
|
||||
return partition, nodes, container_count
|
||||
return None, None, None
|
||||
|
||||
@ -488,10 +494,10 @@ class Controller(object):
|
||||
write_acl = cache_value['write_acl']
|
||||
sync_key = cache_value.get('sync_key')
|
||||
versions = cache_value.get('versions')
|
||||
if status == 200:
|
||||
if status == HTTP_OK:
|
||||
return partition, nodes, read_acl, write_acl, sync_key, \
|
||||
versions
|
||||
elif status == 404:
|
||||
elif status == HTTP_NOT_FOUND:
|
||||
return None, None, None, None, None, None
|
||||
if not self.account_info(account, autocreate=account_autocreate)[1]:
|
||||
return None, None, None, None, None, None
|
||||
@ -511,8 +517,8 @@ class Controller(object):
|
||||
with Timeout(self.app.node_timeout):
|
||||
resp = conn.getresponse()
|
||||
body = resp.read()
|
||||
if 200 <= resp.status <= 299:
|
||||
result_code = 200
|
||||
if is_success(resp.status):
|
||||
result_code = HTTP_OK
|
||||
read_acl = resp.getheader('x-container-read')
|
||||
write_acl = resp.getheader('x-container-write')
|
||||
sync_key = resp.getheader('x-container-sync-key')
|
||||
@ -520,12 +526,12 @@ class Controller(object):
|
||||
resp.getheader('X-Container-Object-Count')
|
||||
versions = resp.getheader('x-versions-location')
|
||||
break
|
||||
elif resp.status == 404:
|
||||
elif resp.status == HTTP_NOT_FOUND:
|
||||
if result_code == 0:
|
||||
result_code = 404
|
||||
elif result_code != 404:
|
||||
result_code = HTTP_NOT_FOUND
|
||||
elif result_code != HTTP_NOT_FOUND:
|
||||
result_code = -1
|
||||
elif resp.status == 507:
|
||||
elif resp.status == HTTP_INSUFFICIENT_STORAGE:
|
||||
self.error_limit(node)
|
||||
continue
|
||||
else:
|
||||
@ -536,8 +542,8 @@ class Controller(object):
|
||||
except (Exception, Timeout):
|
||||
self.exception_occurred(node, _('Container'),
|
||||
_('Trying to get container info for %s') % path)
|
||||
if self.app.memcache and result_code in (200, 404):
|
||||
if result_code == 200:
|
||||
if self.app.memcache and result_code in (HTTP_OK, HTTP_NOT_FOUND):
|
||||
if result_code == HTTP_OK:
|
||||
cache_timeout = self.app.recheck_container_existence
|
||||
else:
|
||||
cache_timeout = self.app.recheck_container_existence * 0.1
|
||||
@ -549,7 +555,7 @@ class Controller(object):
|
||||
'container_size': container_size,
|
||||
'versions': versions},
|
||||
timeout=cache_timeout)
|
||||
if result_code == 200:
|
||||
if result_code == HTTP_OK:
|
||||
return partition, nodes, read_acl, write_acl, sync_key, versions
|
||||
return None, None, None, None, None, None
|
||||
|
||||
@ -579,9 +585,10 @@ class Controller(object):
|
||||
conn.node = node
|
||||
with Timeout(self.app.node_timeout):
|
||||
resp = conn.getresponse()
|
||||
if 200 <= resp.status < 500:
|
||||
if not is_informational(resp.status) and \
|
||||
not is_server_error(resp.status):
|
||||
return resp.status, resp.reason, resp.read()
|
||||
elif resp.status == 507:
|
||||
elif resp.status == HTTP_INSUFFICIENT_STORAGE:
|
||||
self.error_limit(node)
|
||||
except (Exception, Timeout):
|
||||
self.exception_occurred(node, self.server_type,
|
||||
@ -606,7 +613,7 @@ class Controller(object):
|
||||
head, query_string)
|
||||
response = [resp for resp in pile if resp]
|
||||
while len(response) < ring.replica_count:
|
||||
response.append((503, '', ''))
|
||||
response.append((HTTP_SERVICE_UNAVAILABLE, '', ''))
|
||||
statuses, reasons, bodies = zip(*response)
|
||||
return self.best_response(req, statuses, reasons, bodies,
|
||||
'%s %s' % (self.server_type, req.method))
|
||||
@ -627,7 +634,7 @@ class Controller(object):
|
||||
"""
|
||||
resp = Response(request=req)
|
||||
if len(statuses):
|
||||
for hundred in (200, 300, 400):
|
||||
for hundred in (HTTP_OK, HTTP_MULTIPLE_CHOICES, HTTP_BAD_REQUEST):
|
||||
hstatuses = \
|
||||
[s for s in statuses if hundred <= s < hundred + 100]
|
||||
if len(hstatuses) > len(statuses) / 2:
|
||||
@ -782,13 +789,14 @@ class Controller(object):
|
||||
_('Trying to %(method)s %(path)s') %
|
||||
{'method': req.method, 'path': req.path})
|
||||
continue
|
||||
if possible_source.status == 507:
|
||||
if possible_source.status == HTTP_INSUFFICIENT_STORAGE:
|
||||
self.error_limit(node)
|
||||
continue
|
||||
if 200 <= possible_source.status <= 399:
|
||||
if is_success(possible_source.status) or \
|
||||
is_redirection(possible_source.status):
|
||||
# 404 if we know we don't have a synced copy
|
||||
if not float(possible_source.getheader('X-PUT-Timestamp', 1)):
|
||||
statuses.append(404)
|
||||
statuses.append(HTTP_NOT_FOUND)
|
||||
reasons.append('')
|
||||
bodies.append('')
|
||||
possible_source.read()
|
||||
@ -811,13 +819,14 @@ class Controller(object):
|
||||
statuses.append(possible_source.status)
|
||||
reasons.append(possible_source.reason)
|
||||
bodies.append(possible_source.read())
|
||||
if possible_source.status >= 500:
|
||||
if is_server_error(possible_source.status):
|
||||
self.error_occurred(node, _('ERROR %(status)d %(body)s ' \
|
||||
'From %(type)s Server') %
|
||||
{'status': possible_source.status,
|
||||
'body': bodies[-1][:1024], 'type': server_type})
|
||||
if source:
|
||||
if req.method == 'GET' and source.status in (200, 206):
|
||||
if req.method == 'GET' and \
|
||||
source.status in (HTTP_OK, HTTP_PARTIAL_CONTENT):
|
||||
res = Response(request=req, conditional_response=True)
|
||||
res.bytes_transferred = 0
|
||||
res.app_iter = self._make_app_iter(node, source, res)
|
||||
@ -834,7 +843,7 @@ class Controller(object):
|
||||
res.charset = None
|
||||
res.content_type = source.getheader('Content-Type')
|
||||
return res
|
||||
elif 200 <= source.status <= 399:
|
||||
elif is_success(source.status) or is_redirection(source.status):
|
||||
res = status_map[source.status](request=req)
|
||||
update_headers(res, source.getheaders())
|
||||
# Used by container sync feature
|
||||
@ -883,9 +892,9 @@ class ObjectController(Controller):
|
||||
aresp = env['swift.authorize'](lreq)
|
||||
if aresp:
|
||||
raise ListingIterNotAuthorized(aresp)
|
||||
if lresp.status_int == 404:
|
||||
if lresp.status_int == HTTP_NOT_FOUND:
|
||||
raise ListingIterNotFound()
|
||||
elif lresp.status_int // 100 != 2:
|
||||
elif not is_success(lresp.status_int):
|
||||
raise ListingIterError()
|
||||
if not lresp.body:
|
||||
break
|
||||
@ -914,7 +923,7 @@ class ObjectController(Controller):
|
||||
# If we get a 416 Requested Range Not Satisfiable we have to check if
|
||||
# we were actually requesting a manifest and then redo
|
||||
# the range request on the whole object.
|
||||
if resp.status_int == 416:
|
||||
if resp.status_int == HTTP_REQUESTED_RANGE_NOT_SATISFIABLE:
|
||||
req_range = req.range
|
||||
req.range = None
|
||||
resp2 = self.GETorHEAD_base(req, _('Object'), partition,
|
||||
@ -1022,7 +1031,7 @@ class ObjectController(Controller):
|
||||
# Older editions returned 202 Accepted on object POSTs, so we'll
|
||||
# convert any 201 Created responses to that for compatibility with
|
||||
# picky clients.
|
||||
if resp.status_int != 201:
|
||||
if resp.status_int != HTTP_CREATED:
|
||||
return resp
|
||||
return HTTPAccepted(request=req)
|
||||
else:
|
||||
@ -1098,10 +1107,10 @@ class ObjectController(Controller):
|
||||
node['device'], part, 'PUT', path, headers)
|
||||
with Timeout(self.app.node_timeout):
|
||||
resp = conn.getexpect()
|
||||
if resp.status == 100:
|
||||
if resp.status == HTTP_CONTINUE:
|
||||
conn.node = node
|
||||
return conn
|
||||
elif resp.status == 507:
|
||||
elif resp.status == HTTP_INSUFFICIENT_STORAGE:
|
||||
self.error_limit(node)
|
||||
except:
|
||||
self.exception_occurred(node, _('Object'),
|
||||
@ -1183,7 +1192,7 @@ class ObjectController(Controller):
|
||||
if object_versions and not req.environ.get('swift_versioned_copy'):
|
||||
is_manifest = 'x-object-manifest' in req.headers or \
|
||||
'x-object-manifest' in hresp.headers
|
||||
if hresp.status_int != 404 and not is_manifest:
|
||||
if hresp.status_int != HTTP_NOT_FOUND and not is_manifest:
|
||||
# This is a version manifest and needs to be handled
|
||||
# differently. First copy the existing data to a new object,
|
||||
# then write the data from this request to the version manifest
|
||||
@ -1206,10 +1215,10 @@ class ObjectController(Controller):
|
||||
copy_req = Request.blank(req.path_info, headers=copy_headers,
|
||||
environ=copy_environ)
|
||||
copy_resp = self.COPY(copy_req)
|
||||
if copy_resp.status_int // 100 == 4:
|
||||
if is_client_error(copy_resp.status_int):
|
||||
# missing container or bad permissions
|
||||
return HTTPPreconditionFailed(request=req)
|
||||
elif copy_resp.status_int // 100 != 2:
|
||||
elif not is_success(copy_resp.status_int):
|
||||
# could not copy the data, bail
|
||||
return HTTPServiceUnavailable(request=req)
|
||||
|
||||
@ -1238,7 +1247,7 @@ class ObjectController(Controller):
|
||||
self.object_name = src_obj_name
|
||||
self.container_name = src_container_name
|
||||
source_resp = self.GET(source_req)
|
||||
if source_resp.status_int >= 300:
|
||||
if source_resp.status_int >= HTTP_MULTIPLE_CHOICES:
|
||||
return source_resp
|
||||
self.object_name = orig_obj_name
|
||||
self.container_name = orig_container_name
|
||||
@ -1332,12 +1341,12 @@ class ObjectController(Controller):
|
||||
req.client_disconnect = True
|
||||
self.app.logger.exception(
|
||||
_('ERROR Exception causing client disconnect'))
|
||||
return Response(status='499 Client Disconnect')
|
||||
return HTTPClientDisconnect(request=req)
|
||||
if req.content_length and req.bytes_transferred < req.content_length:
|
||||
req.client_disconnect = True
|
||||
self.app.logger.warn(
|
||||
_('Client disconnected without sending enough data'))
|
||||
return Response(status='499 Client Disconnect')
|
||||
return HTTPClientDisconnect(request=req)
|
||||
statuses = []
|
||||
reasons = []
|
||||
bodies = []
|
||||
@ -1349,12 +1358,12 @@ class ObjectController(Controller):
|
||||
statuses.append(response.status)
|
||||
reasons.append(response.reason)
|
||||
bodies.append(response.read())
|
||||
if response.status >= 500:
|
||||
if response.status >= HTTP_INTERNAL_SERVER_ERROR:
|
||||
self.error_occurred(conn.node,
|
||||
_('ERROR %(status)d %(body)s From Object Server ' \
|
||||
're: %(path)s') % {'status': response.status,
|
||||
'body': bodies[-1][:1024], 'path': req.path})
|
||||
elif 200 <= response.status < 300:
|
||||
elif is_success(response.status):
|
||||
etags.add(response.getheader('etag').strip('"'))
|
||||
except (Exception, Timeout):
|
||||
self.exception_occurred(conn.node, _('Object'),
|
||||
@ -1365,7 +1374,7 @@ class ObjectController(Controller):
|
||||
return HTTPServerError(request=req)
|
||||
etag = len(etags) and etags.pop() or None
|
||||
while len(statuses) < len(nodes):
|
||||
statuses.append(503)
|
||||
statuses.append(HTTP_SERVICE_UNAVAILABLE)
|
||||
reasons.append('')
|
||||
bodies.append('')
|
||||
resp = self.best_response(req, statuses, reasons, bodies,
|
||||
@ -1426,10 +1435,10 @@ class ObjectController(Controller):
|
||||
creq = Request.blank(copy_path, headers=copy_headers,
|
||||
environ=copy_environ)
|
||||
copy_resp = self.COPY(creq)
|
||||
if copy_resp.status_int // 100 == 4:
|
||||
if is_client_error(copy_resp.status_int):
|
||||
# some user error, maybe permissions
|
||||
return HTTPPreconditionFailed(request=req)
|
||||
elif copy_resp.status_int // 100 != 2:
|
||||
elif not is_success(copy_resp.status_int):
|
||||
# could not copy the data, bail
|
||||
return HTTPServiceUnavailable(request=req)
|
||||
# reset these because the COPY changed them
|
||||
@ -1666,7 +1675,8 @@ class ContainerController(Controller):
|
||||
self.app.memcache.delete(cache_key)
|
||||
resp = self.make_requests(req, self.app.container_ring,
|
||||
container_partition, 'DELETE', req.path_info, headers)
|
||||
if resp.status_int == 202: # Indicates no server had the container
|
||||
# Indicates no server had the container
|
||||
if resp.status_int == HTTP_ACCEPTED:
|
||||
return HTTPNotFound(request=req)
|
||||
return resp
|
||||
|
||||
@ -1685,7 +1695,7 @@ class AccountController(Controller):
|
||||
shuffle(nodes)
|
||||
resp = self.GETorHEAD_base(req, _('Account'), partition, nodes,
|
||||
req.path_info.rstrip('/'), self.app.account_ring.replica_count)
|
||||
if resp.status_int == 404 and self.app.account_autocreate:
|
||||
if resp.status_int == HTTP_NOT_FOUND and self.app.account_autocreate:
|
||||
if len(self.account_name) > MAX_ACCOUNT_NAME_LENGTH:
|
||||
resp = HTTPBadRequest(request=req)
|
||||
resp.body = 'Account name length of %d longer than %d' % \
|
||||
@ -1698,7 +1708,7 @@ class AccountController(Controller):
|
||||
Request.blank('/v1/' + self.account_name),
|
||||
self.app.account_ring, partition, 'PUT',
|
||||
'/' + self.account_name, [headers] * len(nodes))
|
||||
if resp.status_int // 100 != 2:
|
||||
if not is_success(resp.status_int):
|
||||
raise Exception('Could not autocreate account %r' %
|
||||
self.account_name)
|
||||
resp = self.GETorHEAD_base(req, _('Account'), partition, nodes,
|
||||
@ -1746,7 +1756,7 @@ class AccountController(Controller):
|
||||
resp = self.make_requests(req, self.app.account_ring,
|
||||
account_partition, 'POST', req.path_info,
|
||||
[headers] * len(accounts))
|
||||
if resp.status_int == 404 and self.app.account_autocreate:
|
||||
if resp.status_int == HTTP_NOT_FOUND and self.app.account_autocreate:
|
||||
if len(self.account_name) > MAX_ACCOUNT_NAME_LENGTH:
|
||||
resp = HTTPBadRequest(request=req)
|
||||
resp.body = 'Account name length of %d longer than %d' % \
|
||||
@ -1756,7 +1766,7 @@ class AccountController(Controller):
|
||||
Request.blank('/v1/' + self.account_name),
|
||||
self.app.account_ring, account_partition, 'PUT',
|
||||
'/' + self.account_name, [headers] * len(accounts))
|
||||
if resp.status_int // 100 != 2:
|
||||
if not is_success(resp.status_int):
|
||||
raise Exception('Could not autocreate account %r' %
|
||||
self.account_name)
|
||||
return resp
|
||||
@ -1996,7 +2006,7 @@ class Application(BaseApplication):
|
||||
status_int = response.status_int
|
||||
if getattr(req, 'client_disconnect', False) or \
|
||||
getattr(response, 'client_disconnect', False):
|
||||
status_int = 499
|
||||
status_int = HTTP_CLIENT_CLOSED_REQUEST
|
||||
self.access_logger.info(' '.join(quote(str(x)) for x in (
|
||||
client or '-',
|
||||
req.remote_addr or '-',
|
||||
|
Loading…
Reference in New Issue
Block a user