swift 2.23.2__py3-none-any.whl → 2.35.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. swift/__init__.py +29 -50
  2. swift/account/auditor.py +21 -118
  3. swift/account/backend.py +33 -28
  4. swift/account/reaper.py +37 -28
  5. swift/account/replicator.py +22 -0
  6. swift/account/server.py +60 -26
  7. swift/account/utils.py +28 -11
  8. swift-2.23.2.data/scripts/swift-account-audit → swift/cli/account_audit.py +23 -13
  9. swift-2.23.2.data/scripts/swift-config → swift/cli/config.py +2 -2
  10. swift/cli/container_deleter.py +5 -11
  11. swift-2.23.2.data/scripts/swift-dispersion-populate → swift/cli/dispersion_populate.py +8 -7
  12. swift/cli/dispersion_report.py +10 -9
  13. swift-2.23.2.data/scripts/swift-drive-audit → swift/cli/drive_audit.py +63 -21
  14. swift/cli/form_signature.py +3 -7
  15. swift-2.23.2.data/scripts/swift-get-nodes → swift/cli/get_nodes.py +8 -2
  16. swift/cli/info.py +183 -29
  17. swift/cli/manage_shard_ranges.py +708 -37
  18. swift-2.23.2.data/scripts/swift-oldies → swift/cli/oldies.py +25 -14
  19. swift-2.23.2.data/scripts/swift-orphans → swift/cli/orphans.py +7 -3
  20. swift/cli/recon.py +196 -67
  21. swift-2.23.2.data/scripts/swift-recon-cron → swift/cli/recon_cron.py +17 -20
  22. swift-2.23.2.data/scripts/swift-reconciler-enqueue → swift/cli/reconciler_enqueue.py +2 -3
  23. swift/cli/relinker.py +807 -126
  24. swift/cli/reload.py +135 -0
  25. swift/cli/ringbuilder.py +217 -20
  26. swift/cli/ringcomposer.py +0 -1
  27. swift/cli/shard-info.py +4 -3
  28. swift/common/base_storage_server.py +9 -20
  29. swift/common/bufferedhttp.py +48 -74
  30. swift/common/constraints.py +20 -15
  31. swift/common/container_sync_realms.py +9 -11
  32. swift/common/daemon.py +25 -8
  33. swift/common/db.py +198 -127
  34. swift/common/db_auditor.py +168 -0
  35. swift/common/db_replicator.py +95 -55
  36. swift/common/digest.py +141 -0
  37. swift/common/direct_client.py +144 -33
  38. swift/common/error_limiter.py +93 -0
  39. swift/common/exceptions.py +25 -1
  40. swift/common/header_key_dict.py +2 -9
  41. swift/common/http_protocol.py +373 -0
  42. swift/common/internal_client.py +129 -59
  43. swift/common/linkat.py +3 -4
  44. swift/common/manager.py +284 -67
  45. swift/common/memcached.py +396 -147
  46. swift/common/middleware/__init__.py +4 -0
  47. swift/common/middleware/account_quotas.py +211 -46
  48. swift/common/middleware/acl.py +3 -8
  49. swift/common/middleware/backend_ratelimit.py +230 -0
  50. swift/common/middleware/bulk.py +22 -34
  51. swift/common/middleware/catch_errors.py +1 -3
  52. swift/common/middleware/cname_lookup.py +6 -11
  53. swift/common/middleware/container_quotas.py +1 -1
  54. swift/common/middleware/container_sync.py +39 -17
  55. swift/common/middleware/copy.py +12 -0
  56. swift/common/middleware/crossdomain.py +22 -9
  57. swift/common/middleware/crypto/__init__.py +2 -1
  58. swift/common/middleware/crypto/crypto_utils.py +11 -15
  59. swift/common/middleware/crypto/decrypter.py +28 -11
  60. swift/common/middleware/crypto/encrypter.py +12 -17
  61. swift/common/middleware/crypto/keymaster.py +8 -15
  62. swift/common/middleware/crypto/kms_keymaster.py +2 -1
  63. swift/common/middleware/dlo.py +15 -11
  64. swift/common/middleware/domain_remap.py +5 -4
  65. swift/common/middleware/etag_quoter.py +128 -0
  66. swift/common/middleware/formpost.py +73 -70
  67. swift/common/middleware/gatekeeper.py +8 -1
  68. swift/common/middleware/keystoneauth.py +33 -3
  69. swift/common/middleware/list_endpoints.py +4 -4
  70. swift/common/middleware/listing_formats.py +85 -49
  71. swift/common/middleware/memcache.py +4 -81
  72. swift/common/middleware/name_check.py +3 -2
  73. swift/common/middleware/proxy_logging.py +160 -92
  74. swift/common/middleware/ratelimit.py +17 -10
  75. swift/common/middleware/read_only.py +6 -4
  76. swift/common/middleware/recon.py +59 -22
  77. swift/common/middleware/s3api/acl_handlers.py +25 -3
  78. swift/common/middleware/s3api/acl_utils.py +6 -1
  79. swift/common/middleware/s3api/controllers/__init__.py +6 -0
  80. swift/common/middleware/s3api/controllers/acl.py +3 -2
  81. swift/common/middleware/s3api/controllers/bucket.py +242 -137
  82. swift/common/middleware/s3api/controllers/logging.py +2 -2
  83. swift/common/middleware/s3api/controllers/multi_delete.py +43 -20
  84. swift/common/middleware/s3api/controllers/multi_upload.py +219 -133
  85. swift/common/middleware/s3api/controllers/obj.py +112 -8
  86. swift/common/middleware/s3api/controllers/object_lock.py +44 -0
  87. swift/common/middleware/s3api/controllers/s3_acl.py +2 -2
  88. swift/common/middleware/s3api/controllers/tagging.py +57 -0
  89. swift/common/middleware/s3api/controllers/versioning.py +36 -7
  90. swift/common/middleware/s3api/etree.py +22 -9
  91. swift/common/middleware/s3api/exception.py +0 -4
  92. swift/common/middleware/s3api/s3api.py +113 -41
  93. swift/common/middleware/s3api/s3request.py +384 -218
  94. swift/common/middleware/s3api/s3response.py +126 -23
  95. swift/common/middleware/s3api/s3token.py +16 -17
  96. swift/common/middleware/s3api/schema/delete.rng +1 -1
  97. swift/common/middleware/s3api/subresource.py +7 -10
  98. swift/common/middleware/s3api/utils.py +27 -10
  99. swift/common/middleware/slo.py +665 -358
  100. swift/common/middleware/staticweb.py +64 -37
  101. swift/common/middleware/symlink.py +52 -19
  102. swift/common/middleware/tempauth.py +76 -58
  103. swift/common/middleware/tempurl.py +192 -174
  104. swift/common/middleware/versioned_writes/__init__.py +51 -0
  105. swift/common/middleware/{versioned_writes.py → versioned_writes/legacy.py} +27 -26
  106. swift/common/middleware/versioned_writes/object_versioning.py +1482 -0
  107. swift/common/middleware/x_profile/exceptions.py +1 -4
  108. swift/common/middleware/x_profile/html_viewer.py +18 -19
  109. swift/common/middleware/x_profile/profile_model.py +1 -2
  110. swift/common/middleware/xprofile.py +10 -10
  111. swift-2.23.2.data/scripts/swift-container-server → swift/common/recon.py +13 -8
  112. swift/common/registry.py +147 -0
  113. swift/common/request_helpers.py +324 -57
  114. swift/common/ring/builder.py +67 -25
  115. swift/common/ring/composite_builder.py +1 -1
  116. swift/common/ring/ring.py +177 -51
  117. swift/common/ring/utils.py +1 -1
  118. swift/common/splice.py +10 -6
  119. swift/common/statsd_client.py +205 -0
  120. swift/common/storage_policy.py +49 -44
  121. swift/common/swob.py +86 -102
  122. swift/common/{utils.py → utils/__init__.py} +2191 -2762
  123. swift/common/utils/base.py +131 -0
  124. swift/common/utils/config.py +433 -0
  125. swift/common/utils/ipaddrs.py +256 -0
  126. swift/common/utils/libc.py +345 -0
  127. swift/common/utils/logs.py +859 -0
  128. swift/common/utils/timestamp.py +412 -0
  129. swift/common/wsgi.py +555 -536
  130. swift/container/auditor.py +14 -100
  131. swift/container/backend.py +552 -227
  132. swift/container/reconciler.py +126 -37
  133. swift/container/replicator.py +96 -22
  134. swift/container/server.py +397 -176
  135. swift/container/sharder.py +1580 -639
  136. swift/container/sync.py +94 -88
  137. swift/container/updater.py +53 -32
  138. swift/obj/auditor.py +153 -35
  139. swift/obj/diskfile.py +466 -217
  140. swift/obj/expirer.py +406 -124
  141. swift/obj/mem_diskfile.py +7 -4
  142. swift/obj/mem_server.py +1 -0
  143. swift/obj/reconstructor.py +523 -262
  144. swift/obj/replicator.py +249 -188
  145. swift/obj/server.py +213 -122
  146. swift/obj/ssync_receiver.py +145 -85
  147. swift/obj/ssync_sender.py +113 -54
  148. swift/obj/updater.py +653 -139
  149. swift/obj/watchers/__init__.py +0 -0
  150. swift/obj/watchers/dark_data.py +213 -0
  151. swift/proxy/controllers/account.py +11 -11
  152. swift/proxy/controllers/base.py +848 -604
  153. swift/proxy/controllers/container.py +452 -86
  154. swift/proxy/controllers/info.py +3 -2
  155. swift/proxy/controllers/obj.py +1009 -490
  156. swift/proxy/server.py +185 -112
  157. swift-2.35.0.dist-info/AUTHORS +501 -0
  158. swift-2.35.0.dist-info/LICENSE +202 -0
  159. {swift-2.23.2.dist-info → swift-2.35.0.dist-info}/METADATA +52 -61
  160. swift-2.35.0.dist-info/RECORD +201 -0
  161. {swift-2.23.2.dist-info → swift-2.35.0.dist-info}/WHEEL +1 -1
  162. {swift-2.23.2.dist-info → swift-2.35.0.dist-info}/entry_points.txt +43 -0
  163. swift-2.35.0.dist-info/pbr.json +1 -0
  164. swift/locale/de/LC_MESSAGES/swift.po +0 -1216
  165. swift/locale/en_GB/LC_MESSAGES/swift.po +0 -1207
  166. swift/locale/es/LC_MESSAGES/swift.po +0 -1085
  167. swift/locale/fr/LC_MESSAGES/swift.po +0 -909
  168. swift/locale/it/LC_MESSAGES/swift.po +0 -894
  169. swift/locale/ja/LC_MESSAGES/swift.po +0 -965
  170. swift/locale/ko_KR/LC_MESSAGES/swift.po +0 -964
  171. swift/locale/pt_BR/LC_MESSAGES/swift.po +0 -881
  172. swift/locale/ru/LC_MESSAGES/swift.po +0 -891
  173. swift/locale/tr_TR/LC_MESSAGES/swift.po +0 -832
  174. swift/locale/zh_CN/LC_MESSAGES/swift.po +0 -833
  175. swift/locale/zh_TW/LC_MESSAGES/swift.po +0 -838
  176. swift-2.23.2.data/scripts/swift-account-auditor +0 -23
  177. swift-2.23.2.data/scripts/swift-account-info +0 -51
  178. swift-2.23.2.data/scripts/swift-account-reaper +0 -23
  179. swift-2.23.2.data/scripts/swift-account-replicator +0 -34
  180. swift-2.23.2.data/scripts/swift-account-server +0 -23
  181. swift-2.23.2.data/scripts/swift-container-auditor +0 -23
  182. swift-2.23.2.data/scripts/swift-container-info +0 -51
  183. swift-2.23.2.data/scripts/swift-container-reconciler +0 -21
  184. swift-2.23.2.data/scripts/swift-container-replicator +0 -34
  185. swift-2.23.2.data/scripts/swift-container-sharder +0 -33
  186. swift-2.23.2.data/scripts/swift-container-sync +0 -23
  187. swift-2.23.2.data/scripts/swift-container-updater +0 -23
  188. swift-2.23.2.data/scripts/swift-dispersion-report +0 -24
  189. swift-2.23.2.data/scripts/swift-form-signature +0 -20
  190. swift-2.23.2.data/scripts/swift-init +0 -119
  191. swift-2.23.2.data/scripts/swift-object-auditor +0 -29
  192. swift-2.23.2.data/scripts/swift-object-expirer +0 -33
  193. swift-2.23.2.data/scripts/swift-object-info +0 -60
  194. swift-2.23.2.data/scripts/swift-object-reconstructor +0 -33
  195. swift-2.23.2.data/scripts/swift-object-relinker +0 -41
  196. swift-2.23.2.data/scripts/swift-object-replicator +0 -37
  197. swift-2.23.2.data/scripts/swift-object-server +0 -27
  198. swift-2.23.2.data/scripts/swift-object-updater +0 -23
  199. swift-2.23.2.data/scripts/swift-proxy-server +0 -23
  200. swift-2.23.2.data/scripts/swift-recon +0 -24
  201. swift-2.23.2.data/scripts/swift-ring-builder +0 -24
  202. swift-2.23.2.data/scripts/swift-ring-builder-analyzer +0 -22
  203. swift-2.23.2.data/scripts/swift-ring-composer +0 -22
  204. swift-2.23.2.dist-info/DESCRIPTION.rst +0 -166
  205. swift-2.23.2.dist-info/RECORD +0 -220
  206. swift-2.23.2.dist-info/metadata.json +0 -1
  207. swift-2.23.2.dist-info/pbr.json +0 -1
  208. {swift-2.23.2.dist-info → swift-2.35.0.dist-info}/top_level.txt +0 -0
@@ -19,27 +19,36 @@ Logging middleware for the Swift proxy.
19
19
  This serves as both the default logging implementation and an example of how
20
20
  to plug in your own logging format/method.
21
21
 
22
- The logging format implemented below is as follows:
22
+ The logging format implemented below is as follows::
23
23
 
24
- client_ip remote_addr end_time.datetime method path protocol
25
- status_int referer user_agent auth_token bytes_recvd bytes_sent
26
- client_etag transaction_id headers request_time source log_info
27
- start_time end_time policy_index
24
+ client_ip remote_addr end_time.datetime method path protocol
25
+ status_int referer user_agent auth_token bytes_recvd bytes_sent
26
+ client_etag transaction_id headers request_time source log_info
27
+ start_time end_time policy_index
28
28
 
29
29
  These values are space-separated, and each is url-encoded, so that they can
30
- be separated with a simple .split()
31
-
32
- * remote_addr is the contents of the REMOTE_ADDR environment variable, while
33
- client_ip is swift's best guess at the end-user IP, extracted variously
34
- from the X-Forwarded-For header, X-Cluster-Ip header, or the REMOTE_ADDR
35
- environment variable.
36
-
37
- * source (swift.source in the WSGI environment) indicates the code
30
+ be separated with a simple ``.split()``.
31
+
32
+ * ``remote_addr`` is the contents of the REMOTE_ADDR environment variable,
33
+ while ``client_ip`` is swift's best guess at the end-user IP, extracted
34
+ variously from the X-Forwarded-For header, X-Cluster-Ip header, or the
35
+ REMOTE_ADDR environment variable.
36
+
37
+ * ``status_int`` is the integer part of the ``status`` string passed to this
38
+ middleware's start_response function, unless the WSGI environment has an item
39
+ with key ``swift.proxy_logging_status``, in which case the value of that item
40
+ is used. Other middleware's may set ``swift.proxy_logging_status`` to
41
+ override the logging of ``status_int``. In either case, the logged
42
+ ``status_int`` value is forced to 499 if a client disconnect is detected
43
+ while this middleware is handling a request, or 500 if an exception is caught
44
+ while handling a request.
45
+
46
+ * ``source`` (``swift.source`` in the WSGI environment) indicates the code
38
47
  that generated the request, such as most middleware. (See below for
39
48
  more detail.)
40
49
 
41
- * log_info (swift.log_info in the WSGI environment) is for additional
42
- information that could prove quite useful, such as any x-delete-at
50
+ * ``log_info`` (``swift.log_info`` in the WSGI environment) is for additional
51
+ information that could prove quite useful, such as any ``x-delete-at``
43
52
  value or other "behind the scenes" activity that might not
44
53
  otherwise be detectable from the plain log information. Code that
45
54
  wishes to add additional log information should use code like
@@ -49,6 +58,11 @@ be separated with a simple .split()
49
58
  * Values that are missing (e.g. due to a header not being present) or zero
50
59
  are generally represented by a single hyphen ('-').
51
60
 
61
+ .. note::
62
+ The message format may be configured using the ``log_msg_template`` option,
63
+ allowing fields to be added, removed, re-ordered, and even anonymized. For
64
+ more information, see https://docs.openstack.org/swift/latest/logs.html
65
+
52
66
  The proxy-logging can be used twice in the proxy server's pipeline when there
53
67
  is middleware installed that can return custom responses that don't follow the
54
68
  standard pipeline to the proxy server.
@@ -57,30 +71,37 @@ For example, with staticweb, the middleware might intercept a request to
57
71
  /v1/AUTH_acc/cont/, make a subrequest to the proxy to retrieve
58
72
  /v1/AUTH_acc/cont/index.html and, in effect, respond to the client's original
59
73
  request using the 2nd request's body. In this instance the subrequest will be
60
- logged by the rightmost middleware (with a swift.source set) and the outgoing
61
- request (with body overridden) will be logged by leftmost middleware.
74
+ logged by the rightmost middleware (with a ``swift.source`` set) and the
75
+ outgoing request (with body overridden) will be logged by leftmost middleware.
62
76
 
63
77
  Requests that follow the normal pipeline (use the same wsgi environment
64
78
  throughout) will not be double logged because an environment variable
65
- (swift.proxy_access_log_made) is checked/set when a log is made.
79
+ (``swift.proxy_access_log_made``) is checked/set when a log is made.
66
80
 
67
- All middleware making subrequests should take care to set swift.source when
81
+ All middleware making subrequests should take care to set ``swift.source`` when
68
82
  needed. With the doubled proxy logs, any consumer/processor of swift's proxy
69
- logs should look at the swift.source field, the rightmost log value, to decide
70
- if this is a middleware subrequest or not. A log processor calculating
71
- bandwidth usage will want to only sum up logs with no swift.source.
83
+ logs should look at the ``swift.source`` field, the rightmost log value, to
84
+ decide if this is a middleware subrequest or not. A log processor calculating
85
+ bandwidth usage will want to only sum up logs with no ``swift.source``.
72
86
  """
73
87
 
88
+ import os
74
89
  import time
75
90
 
91
+ from swift.common.constraints import valid_api_version
92
+ from swift.common.middleware.catch_errors import enforce_byte_count
93
+ from swift.common.request_helpers import get_log_info
76
94
  from swift.common.swob import Request
77
95
  from swift.common.utils import (get_logger, get_remote_client,
78
- config_true_value,
96
+ config_true_value, reiterate,
97
+ close_if_possible, cap_length,
79
98
  InputProxy, list_from_csv, get_policy_index,
80
99
  split_path, StrAnonymizer, StrFormatTime,
81
100
  LogStringFormatter)
82
101
 
83
102
  from swift.common.storage_policy import POLICIES
103
+ from swift.common.registry import get_sensitive_headers, \
104
+ get_sensitive_params, register_sensitive_header
84
105
 
85
106
 
86
107
  class ProxyLoggingMiddleware(object):
@@ -90,6 +111,7 @@ class ProxyLoggingMiddleware(object):
90
111
 
91
112
  def __init__(self, app, conf, logger=None):
92
113
  self.app = app
114
+ self.pid = os.getpid()
93
115
  self.log_formatter = LogStringFormatter(default='-', quote=True)
94
116
  self.log_msg_template = conf.get(
95
117
  'log_msg_template', (
@@ -115,7 +137,7 @@ class ProxyLoggingMiddleware(object):
115
137
  self.valid_methods = conf.get(
116
138
  'access_log_statsd_valid_http_methods',
117
139
  conf.get('log_statsd_valid_http_methods',
118
- 'GET,HEAD,POST,PUT,DELETE,COPY,OPTIONS'))
140
+ 'GET,HEAD,POST,PUT,DELETE,COPY,OPTIONS,UPDATE'))
119
141
  self.valid_methods = [m.strip().upper() for m in
120
142
  self.valid_methods.split(',') if m.strip()]
121
143
  access_log_conf = {}
@@ -127,9 +149,10 @@ class ProxyLoggingMiddleware(object):
127
149
  value = conf.get('access_' + key, conf.get(key, None))
128
150
  if value:
129
151
  access_log_conf[key] = value
130
- self.access_logger = logger or get_logger(access_log_conf,
131
- log_route='proxy-access')
132
- self.access_logger.set_statsd_prefix('proxy-server')
152
+ self.access_logger = logger or get_logger(
153
+ access_log_conf,
154
+ log_route=conf.get('access_log_route', 'proxy-access'),
155
+ statsd_tail_prefix='proxy-server')
133
156
  self.reveal_sensitive_prefix = int(
134
157
  conf.get('reveal_sensitive_prefix', 16))
135
158
  self.check_log_msg_template_validity()
@@ -144,6 +167,8 @@ class ProxyLoggingMiddleware(object):
144
167
  self.anonymization_salt),
145
168
  'remote_addr': StrAnonymizer('4.3.2.1', self.anonymization_method,
146
169
  self.anonymization_salt),
170
+ 'domain': StrAnonymizer('', self.anonymization_method,
171
+ self.anonymization_salt),
147
172
  'path': StrAnonymizer('/', self.anonymization_method,
148
173
  self.anonymization_salt),
149
174
  'referer': StrAnonymizer('ref', self.anonymization_method,
@@ -171,7 +196,10 @@ class ProxyLoggingMiddleware(object):
171
196
  'request_time': '0.05',
172
197
  'source': '',
173
198
  'log_info': '',
174
- 'policy_index': ''
199
+ 'policy_index': '',
200
+ 'ttfb': '0.05',
201
+ 'pid': '42',
202
+ 'wire_status_int': '200',
175
203
  }
176
204
  try:
177
205
  self.log_formatter.format(self.log_msg_template, **replacements)
@@ -188,12 +216,29 @@ class ProxyLoggingMiddleware(object):
188
216
  env['swift.proxy_access_log_made'] = True
189
217
 
190
218
  def obscure_sensitive(self, value):
191
- if value and len(value) > self.reveal_sensitive_prefix:
192
- return value[:self.reveal_sensitive_prefix] + '...'
193
- return value
219
+ return cap_length(value, self.reveal_sensitive_prefix)
220
+
221
+ def obscure_req(self, req):
222
+ for header in get_sensitive_headers():
223
+ if header in req.headers:
224
+ req.headers[header] = \
225
+ self.obscure_sensitive(req.headers[header])
226
+
227
+ obscure_params = get_sensitive_params()
228
+ new_params = []
229
+ any_obscured = False
230
+ for k, v in req.params.items():
231
+ if k in obscure_params:
232
+ new_params.append((k, self.obscure_sensitive(v)))
233
+ any_obscured = True
234
+ else:
235
+ new_params.append((k, v))
236
+ if any_obscured:
237
+ req.params = new_params
194
238
 
195
239
  def log_request(self, req, status_int, bytes_received, bytes_sent,
196
- start_time, end_time, resp_headers=None):
240
+ start_time, end_time, resp_headers=None, ttfb=0,
241
+ wire_status_int=None):
197
242
  """
198
243
  Log a request.
199
244
 
@@ -204,7 +249,14 @@ class ProxyLoggingMiddleware(object):
204
249
  :param start_time: timestamp request started
205
250
  :param end_time: timestamp request completed
206
251
  :param resp_headers: dict of the response headers
252
+ :param ttfb: time to first byte
253
+ :param wire_status_int: the on the wire status int
207
254
  """
255
+ self.obscure_req(req)
256
+ domain = req.environ.get('HTTP_HOST',
257
+ req.environ.get('SERVER_NAME', None))
258
+ if ':' in domain:
259
+ domain, port = domain.rsplit(':', 1)
208
260
  resp_headers = resp_headers or {}
209
261
  logged_headers = None
210
262
  if self.log_hdrs:
@@ -220,9 +272,8 @@ class ProxyLoggingMiddleware(object):
220
272
  duration_time_str = "%.4f" % (end_time - start_time)
221
273
  policy_index = get_policy_index(req.headers, resp_headers)
222
274
 
223
- acc, cont, obj = None, None, None
224
- if req.path.startswith('/v1/'):
225
- _, acc, cont, obj = split_path(req.path, 1, 4, True)
275
+ swift_path = req.environ.get('swift.backend_path', req.path)
276
+ acc, cont, obj = self.get_aco_from_path(swift_path)
226
277
 
227
278
  replacements = {
228
279
  # Time information
@@ -235,6 +286,8 @@ class ProxyLoggingMiddleware(object):
235
286
  'remote_addr': StrAnonymizer(req.remote_addr,
236
287
  self.anonymization_method,
237
288
  self.anonymization_salt),
289
+ 'domain': StrAnonymizer(domain, self.anonymization_method,
290
+ self.anonymization_salt),
238
291
  'path': StrAnonymizer(req.path_qs, self.anonymization_method,
239
292
  self.anonymization_salt),
240
293
  'referer': StrAnonymizer(req.referer, self.anonymization_method,
@@ -259,16 +312,17 @@ class ProxyLoggingMiddleware(object):
259
312
  req.environ.get('SERVER_PROTOCOL'),
260
313
  'status_int': status_int,
261
314
  'auth_token':
262
- self.obscure_sensitive(
263
- req.headers.get('x-auth-token')),
315
+ req.headers.get('x-auth-token'),
264
316
  'bytes_recvd': bytes_received,
265
317
  'bytes_sent': bytes_sent,
266
318
  'transaction_id': req.environ.get('swift.trans_id'),
267
319
  'request_time': duration_time_str,
268
320
  'source': req.environ.get('swift.source'),
269
- 'log_info':
270
- ','.join(req.environ.get('swift.log_info', '')),
321
+ 'log_info': get_log_info(req.environ),
271
322
  'policy_index': policy_index,
323
+ 'ttfb': ttfb,
324
+ 'pid': self.pid,
325
+ 'wire_status_int': wire_status_int or status_int,
272
326
  }
273
327
  self.access_logger.info(
274
328
  self.log_formatter.format(self.log_msg_template,
@@ -293,21 +347,28 @@ class ProxyLoggingMiddleware(object):
293
347
  self.access_logger.update_stats(metric_name_policy + '.xfer',
294
348
  bytes_received + bytes_sent)
295
349
 
350
+ def get_aco_from_path(self, swift_path):
351
+ try:
352
+ version, acc, cont, obj = split_path(swift_path, 1, 4, True)
353
+ if not valid_api_version(version):
354
+ raise ValueError
355
+ except ValueError:
356
+ acc, cont, obj = None, None, None
357
+ return acc, cont, obj
358
+
296
359
  def get_metric_name_type(self, req):
297
- if req.path.startswith('/v1/'):
298
- try:
299
- stat_type = [None, 'account', 'container',
300
- 'object'][req.path.strip('/').count('/')]
301
- except IndexError:
302
- stat_type = 'object'
303
- else:
304
- stat_type = req.environ.get('swift.source')
305
- return stat_type
360
+ swift_path = req.environ.get('swift.backend_path', req.path)
361
+ acc, cont, obj = self.get_aco_from_path(swift_path)
362
+ if obj:
363
+ return 'object'
364
+ if cont:
365
+ return 'container'
366
+ if acc:
367
+ return 'account'
368
+ return req.environ.get('swift.source') or 'UNKNOWN'
306
369
 
307
370
  def statsd_metric_name(self, req, status_int, method):
308
371
  stat_type = self.get_metric_name_type(req)
309
- if stat_type is None:
310
- return None
311
372
  stat_method = method if method in self.valid_methods \
312
373
  else 'BAD_METHOD'
313
374
  return '.'.join((stat_type, stat_method, str(status_int)))
@@ -343,79 +404,80 @@ class ProxyLoggingMiddleware(object):
343
404
  def my_start_response(status, headers, exc_info=None):
344
405
  start_response_args[0] = (status, list(headers), exc_info)
345
406
 
346
- def status_int_for_logging(client_disconnect=False, start_status=None):
407
+ def status_int_for_logging():
347
408
  # log disconnected clients as '499' status code
348
- if client_disconnect or input_proxy.client_disconnect:
349
- ret_status_int = 499
350
- elif start_status is None:
351
- ret_status_int = int(
352
- start_response_args[0][0].split(' ', 1)[0])
353
- else:
354
- ret_status_int = start_status
355
- return ret_status_int
409
+ if input_proxy.client_disconnect:
410
+ return 499
411
+ return env.get('swift.proxy_logging_status')
356
412
 
357
413
  def iter_response(iterable):
358
- iterator = iter(iterable)
359
- try:
360
- chunk = next(iterator)
361
- while not chunk:
362
- chunk = next(iterator)
363
- except StopIteration:
364
- chunk = ''
414
+ iterator = reiterate(iterable)
415
+ content_length = None
365
416
  for h, v in start_response_args[0][1]:
366
- if h.lower() in ('content-length', 'transfer-encoding'):
417
+ if h.lower() == 'content-length':
418
+ content_length = int(v)
419
+ break
420
+ elif h.lower() == 'transfer-encoding':
367
421
  break
368
422
  else:
369
- if not chunk:
370
- start_response_args[0][1].append(('Content-Length', '0'))
371
- elif isinstance(iterable, list):
423
+ if isinstance(iterator, list):
424
+ content_length = sum(len(i) for i in iterator)
372
425
  start_response_args[0][1].append(
373
- ('Content-Length', str(sum(len(i) for i in iterable))))
426
+ ('Content-Length', str(content_length)))
427
+
428
+ req = Request(env)
429
+ method = self.method_from_req(req)
430
+ if method == 'HEAD':
431
+ content_length = 0
432
+ if content_length is not None:
433
+ iterator = enforce_byte_count(iterator, content_length)
434
+
435
+ wire_status_int = int(start_response_args[0][0].split(' ', 1)[0])
374
436
  resp_headers = dict(start_response_args[0][1])
375
437
  start_response(*start_response_args[0])
376
- req = Request(env)
377
438
 
378
439
  # Log timing information for time-to-first-byte (GET requests only)
379
- method = self.method_from_req(req)
440
+ ttfb = 0.0
380
441
  if method == 'GET':
381
- status_int = status_int_for_logging()
382
442
  policy_index = get_policy_index(req.headers, resp_headers)
383
- metric_name = self.statsd_metric_name(req, status_int, method)
443
+ metric_name = self.statsd_metric_name(
444
+ req, wire_status_int, method)
384
445
  metric_name_policy = self.statsd_metric_name_policy(
385
- req, status_int, method, policy_index)
446
+ req, wire_status_int, method, policy_index)
447
+ ttfb = time.time() - start_time
386
448
  if metric_name:
387
- self.access_logger.timing_since(
388
- metric_name + '.first-byte.timing', start_time)
449
+ self.access_logger.timing(
450
+ metric_name + '.first-byte.timing', ttfb * 1000)
389
451
  if metric_name_policy:
390
- self.access_logger.timing_since(
391
- metric_name_policy + '.first-byte.timing', start_time)
452
+ self.access_logger.timing(
453
+ metric_name_policy + '.first-byte.timing', ttfb * 1000)
392
454
 
393
455
  bytes_sent = 0
394
- client_disconnect = False
395
456
  try:
396
- while chunk:
457
+ for chunk in iterator:
397
458
  bytes_sent += len(chunk)
398
459
  yield chunk
399
- chunk = next(iterator)
400
- except StopIteration: # iterator was depleted
401
- return
402
460
  except GeneratorExit: # generator was closed before we finished
403
- client_disconnect = True
461
+ env['swift.proxy_logging_status'] = 499
462
+ raise
463
+ except Exception:
464
+ env['swift.proxy_logging_status'] = 500
404
465
  raise
405
466
  finally:
406
- status_int = status_int_for_logging(client_disconnect)
467
+ env.setdefault('swift.proxy_logging_status', wire_status_int)
468
+ status_int = status_int_for_logging()
407
469
  self.log_request(
408
470
  req, status_int, input_proxy.bytes_received, bytes_sent,
409
- start_time, time.time(), resp_headers=resp_headers)
410
- close_method = getattr(iterable, 'close', None)
411
- if callable(close_method):
412
- close_method()
471
+ start_time, time.time(), resp_headers=resp_headers,
472
+ ttfb=ttfb, wire_status_int=wire_status_int)
473
+ close_if_possible(iterator)
413
474
 
414
475
  try:
415
476
  iterable = self.app(env, my_start_response)
416
477
  except Exception:
417
478
  req = Request(env)
418
- status_int = status_int_for_logging(start_status=500)
479
+ env['swift.proxy_logging_status'] = 500
480
+ status_int = status_int_for_logging()
419
481
  self.log_request(
420
482
  req, status_int, input_proxy.bytes_received, 0, start_time,
421
483
  time.time())
@@ -428,6 +490,12 @@ def filter_factory(global_conf, **local_conf):
428
490
  conf = global_conf.copy()
429
491
  conf.update(local_conf)
430
492
 
493
+ # Normally it would be the middleware that uses the header that
494
+ # would register it, but because there could be 3rd party auth middlewares
495
+ # that use 'x-auth-token' or 'x-storage-token' we special case it here.
496
+ register_sensitive_header('x-auth-token')
497
+ register_sensitive_header('x-storage-token')
498
+
431
499
  def proxy_logger(app):
432
500
  return ProxyLoggingMiddleware(app, conf)
433
501
  return proxy_logger
@@ -13,11 +13,11 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  import time
16
- from swift import gettext_ as _
17
16
 
18
17
  import eventlet
19
18
 
20
- from swift.common.utils import cache_from_env, get_logger, register_swift_info
19
+ from swift.common.utils import cache_from_env, get_logger
20
+ from swift.common.registry import register_swift_info
21
21
  from swift.proxy.controllers.base import get_account_info, get_container_info
22
22
  from swift.common.constraints import valid_api_version
23
23
  from swift.common.memcached import MemcacheConnectionError
@@ -242,6 +242,10 @@ class RateLimitMiddleware(object):
242
242
  if not self.memcache_client:
243
243
  return None
244
244
 
245
+ if req.environ.get('swift.ratelimit.handled'):
246
+ return None
247
+ req.environ['swift.ratelimit.handled'] = True
248
+
245
249
  try:
246
250
  account_info = get_account_info(req.environ, self.app,
247
251
  swift_source='RL')
@@ -256,7 +260,7 @@ class RateLimitMiddleware(object):
256
260
 
257
261
  if account_name in self.ratelimit_blacklist or \
258
262
  account_global_ratelimit == 'BLACKLIST':
259
- self.logger.error(_('Returning 497 because of blacklisting: %s'),
263
+ self.logger.error('Returning 497 because of blacklisting: %s',
260
264
  account_name)
261
265
  eventlet.sleep(self.BLACK_LIST_SLEEP)
262
266
  return Response(status='497 Blacklisted',
@@ -271,18 +275,21 @@ class RateLimitMiddleware(object):
271
275
  if self.log_sleep_time_seconds and \
272
276
  need_to_sleep > self.log_sleep_time_seconds:
273
277
  self.logger.warning(
274
- _("Ratelimit sleep log: %(sleep)s for "
275
- "%(account)s/%(container)s/%(object)s"),
278
+ "Ratelimit sleep log: %(sleep)s for "
279
+ "%(account)s/%(container)s/%(object)s",
276
280
  {'sleep': need_to_sleep, 'account': account_name,
277
281
  'container': container_name, 'object': obj_name})
278
282
  if need_to_sleep > 0:
279
283
  eventlet.sleep(need_to_sleep)
280
284
  except MaxSleepTimeHitError as e:
285
+ if obj_name:
286
+ path = '/'.join((account_name, container_name, obj_name))
287
+ else:
288
+ path = '/'.join((account_name, container_name))
281
289
  self.logger.error(
282
- _('Returning 498 for %(meth)s to %(acc)s/%(cont)s/%(obj)s '
283
- '. Ratelimit (Max Sleep) %(e)s'),
284
- {'meth': req.method, 'acc': account_name,
285
- 'cont': container_name, 'obj': obj_name, 'e': str(e)})
290
+ 'Returning 498 for %(meth)s to %(path)s. '
291
+ 'Ratelimit (Max Sleep) %(e)s',
292
+ {'meth': req.method, 'path': path, 'e': str(e)})
286
293
  error_resp = Response(status='498 Rate Limited',
287
294
  body='Slow down', request=req)
288
295
  return error_resp
@@ -301,7 +308,7 @@ class RateLimitMiddleware(object):
301
308
  self.memcache_client = cache_from_env(env)
302
309
  if not self.memcache_client:
303
310
  self.logger.warning(
304
- _('Warning: Cannot ratelimit without a memcached client'))
311
+ 'Warning: Cannot ratelimit without a memcached client')
305
312
  return self.app(env, start_response)
306
313
  try:
307
314
  version, account, container, obj = req.split_path(1, 4, True)
@@ -12,10 +12,10 @@
12
12
  # implied.
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
- from swift.common.constraints import check_account_format
15
+ from swift.common.constraints import check_account_format, valid_api_version
16
16
  from swift.common.swob import HTTPMethodNotAllowed, Request
17
- from swift.common.utils import get_logger, config_true_value, \
18
- register_swift_info
17
+ from swift.common.utils import get_logger, config_true_value
18
+ from swift.common.registry import register_swift_info
19
19
  from swift.proxy.controllers.base import get_info
20
20
 
21
21
  """
@@ -79,7 +79,9 @@ class ReadOnlyMiddleware(object):
79
79
  return self.app(env, start_response)
80
80
 
81
81
  try:
82
- version, account, container, obj = req.split_path(1, 4, True)
82
+ version, account, container, obj = req.split_path(2, 4, True)
83
+ if not valid_api_version(version):
84
+ raise ValueError
83
85
  except ValueError:
84
86
  return self.app(env, start_response)
85
87