Skip to content

Commit fe0edfc

Browse files
reimannfauhlig
andauthored
req.path fails on not proper encoded URLs (#9)
See Pylons/webob#161 Recognized with Swift, when not proper encoded object names causing a HTTP 500 error Co-authored-by: Arno Uhlig <[email protected]>
1 parent 9e8a025 commit fe0edfc

File tree

1 file changed

+95
-93
lines changed

1 file changed

+95
-93
lines changed

watcher/watcher.py

Lines changed: 95 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -132,105 +132,107 @@ def __call__(self, environ, start_response):
132132

133133
# capture start timestamp
134134
start = time.time()
135+
labels = []
136+
detail_labels = []
135137

136138
req = Request(environ)
139+
try:
140+
# determine initiator based on token context
141+
initiator_project_id = self.get_safe_from_environ(environ, 'HTTP_X_PROJECT_ID')
142+
initiator_project_name = self.get_safe_from_environ(environ, 'HTTP_X_PROJECT_NAME')
143+
initiator_project_domain_id = self.get_safe_from_environ(environ, 'HTTP_X_PROJECT_DOMAIN_ID')
144+
initiator_project_domain_name = self.get_safe_from_environ(environ, 'HTTP_X_PROJECT_DOMAIN_NAME')
145+
initiator_domain_id = self.get_safe_from_environ(environ, 'HTTP_X_DOMAIN_ID')
146+
initiator_domain_name = self.get_safe_from_environ(environ, 'HTTP_X_DOMAIN_NAME')
147+
initiator_user_id = self.get_safe_from_environ(environ, 'HTTP_X_USER_ID')
148+
initiator_user_name = self.get_safe_from_environ(environ, 'HTTP_X_USER_NAME')
149+
initiator_user_domain_id = self.get_safe_from_environ(environ, 'HTTP_X_USER_DOMAIN_ID')
150+
initiator_user_domain_name = self.get_safe_from_environ(environ, 'HTTP_X_USER_DOMAIN_NAME')
151+
initiator_host_address = req.client_addr or taxonomy.UNKNOWN
152+
153+
# determine target based on request path or keystone.token_info
154+
target_project_id = taxonomy.UNKNOWN
155+
if self.is_project_id_from_path:
156+
target_project_id = self.get_target_project_uid_from_path(req.path)
157+
elif self.is_project_id_from_service_catalog:
158+
target_project_id = self.get_target_project_id_from_keystone_token_info(environ.get('keystone.token_info'))
159+
160+
# default target_project_id to initiator_project_id if still unknown
161+
if not target_project_id or target_project_id == taxonomy.UNKNOWN:
162+
target_project_id = initiator_project_id
163+
164+
# determine target.type_uri for request
165+
target_type_uri = self.determine_target_type_uri(req)
166+
167+
# determine cadf_action for request. consider custom action config.
168+
cadf_action = self.determine_cadf_action(req, target_type_uri)
169+
170+
# if authentication request consider project, domain and user in body
171+
if self.service_type == 'identity' and cadf_action == taxonomy.ACTION_AUTHENTICATE:
172+
initiator_project_id, initiator_domain_id, initiator_user_id = \
173+
self.get_project_domain_and_user_id_from_keystone_authentication_request(req)
174+
175+
# set environ for initiator
176+
environ['WATCHER.INITIATOR_PROJECT_ID'] = initiator_project_id
177+
environ['WATCHER.INITIATOR_PROJECT_NAME'] = initiator_project_name
178+
environ['WATCHER.INITIATOR_PROJECT_DOMAIN_ID'] = initiator_project_domain_id
179+
environ['WATCHER.INITIATOR_PROJECT_DOMAIN_NAME'] = initiator_project_domain_name
180+
environ['WATCHER.INITIATOR_DOMAIN_ID'] = initiator_domain_id
181+
environ['WATCHER.INITIATOR_DOMAIN_NAME'] = initiator_domain_name
182+
environ['WATCHER.INITIATOR_USER_ID'] = initiator_user_id
183+
environ['WATCHER.INITIATOR_USER_NAME'] = initiator_user_name
184+
environ['WATCHER.INITIATOR_USER_DOMAIN_ID'] = initiator_user_domain_id
185+
environ['WATCHER.INITIATOR_USER_DOMAIN_NAME'] = initiator_user_domain_name
186+
environ['WATCHER.INITIATOR_HOST_ADDRESS'] = initiator_host_address
187+
188+
# set environ for target
189+
environ['WATCHER.TARGET_PROJECT_ID'] = target_project_id
190+
environ['WATCHER.TARGET_TYPE_URI'] = target_type_uri
191+
192+
# general cadf attributes
193+
environ['WATCHER.ACTION'] = cadf_action
194+
environ['WATCHER.SERVICE_TYPE'] = self.service_type
195+
environ['WATCHER.CADF_SERVICE_NAME'] = self.strategy.get_cadf_service_name()
196+
197+
# labels applied to all metrics emitted by this middleware
198+
labels.append("service_name:{0}".format(self.strategy.get_cadf_service_name()))
199+
labels.append("service:{0}".format(self.service_type))
200+
labels.append("action:{0}".format(cadf_action))
201+
labels.append("target_type_uri:{0}".format(target_type_uri))
202+
203+
# additional labels not needed in all metrics
204+
detail_labels.append("initiator_project_id:{0}".format(initiator_project_id))
205+
detail_labels.append("initiator_domain_id:{0}".format(initiator_domain_id))
206+
detail_labels = labels + detail_labels
207+
208+
# include the target project id in metric
209+
if self.is_include_target_project_id_in_metric:
210+
detail_labels.append(
211+
"target_project_id:{0}".format(target_project_id)
212+
)
137213

138-
# determine initiator based on token context
139-
initiator_project_id = self.get_safe_from_environ(environ, 'HTTP_X_PROJECT_ID')
140-
initiator_project_name = self.get_safe_from_environ(environ, 'HTTP_X_PROJECT_NAME')
141-
initiator_project_domain_id = self.get_safe_from_environ(environ, 'HTTP_X_PROJECT_DOMAIN_ID')
142-
initiator_project_domain_name = self.get_safe_from_environ(environ, 'HTTP_X_PROJECT_DOMAIN_NAME')
143-
initiator_domain_id = self.get_safe_from_environ(environ, 'HTTP_X_DOMAIN_ID')
144-
initiator_domain_name = self.get_safe_from_environ(environ, 'HTTP_X_DOMAIN_NAME')
145-
initiator_user_id = self.get_safe_from_environ(environ, 'HTTP_X_USER_ID')
146-
initiator_user_name = self.get_safe_from_environ(environ, 'HTTP_X_USER_NAME')
147-
initiator_user_domain_id = self.get_safe_from_environ(environ, 'HTTP_X_USER_DOMAIN_ID')
148-
initiator_user_domain_name = self.get_safe_from_environ(environ, 'HTTP_X_USER_DOMAIN_NAME')
149-
initiator_host_address = req.client_addr or taxonomy.UNKNOWN
150-
151-
# determine target based on request path or keystone.token_info
152-
target_project_id = taxonomy.UNKNOWN
153-
if self.is_project_id_from_path:
154-
target_project_id = self.get_target_project_uid_from_path(req.path)
155-
elif self.is_project_id_from_service_catalog:
156-
target_project_id = self.get_target_project_id_from_keystone_token_info(environ.get('keystone.token_info'))
157-
158-
# default target_project_id to initiator_project_id if still unknown
159-
if not target_project_id or target_project_id == taxonomy.UNKNOWN:
160-
target_project_id = initiator_project_id
161-
162-
# determine target.type_uri for request
163-
target_type_uri = self.determine_target_type_uri(req)
164-
165-
# determine cadf_action for request. consider custom action config.
166-
cadf_action = self.determine_cadf_action(req, target_type_uri)
167-
168-
# if authentication request consider project, domain and user in body
169-
if self.service_type == 'identity' and cadf_action == taxonomy.ACTION_AUTHENTICATE:
170-
initiator_project_id, initiator_domain_id, initiator_user_id = \
171-
self.get_project_domain_and_user_id_from_keystone_authentication_request(req)
172-
173-
# set environ for initiator
174-
environ['WATCHER.INITIATOR_PROJECT_ID'] = initiator_project_id
175-
environ['WATCHER.INITIATOR_PROJECT_NAME'] = initiator_project_name
176-
environ['WATCHER.INITIATOR_PROJECT_DOMAIN_ID'] = initiator_project_domain_id
177-
environ['WATCHER.INITIATOR_PROJECT_DOMAIN_NAME'] = initiator_project_domain_name
178-
environ['WATCHER.INITIATOR_DOMAIN_ID'] = initiator_domain_id
179-
environ['WATCHER.INITIATOR_DOMAIN_NAME'] = initiator_domain_name
180-
environ['WATCHER.INITIATOR_USER_ID'] = initiator_user_id
181-
environ['WATCHER.INITIATOR_USER_NAME'] = initiator_user_name
182-
environ['WATCHER.INITIATOR_USER_DOMAIN_ID'] = initiator_user_domain_id
183-
environ['WATCHER.INITIATOR_USER_DOMAIN_NAME'] = initiator_user_domain_name
184-
environ['WATCHER.INITIATOR_HOST_ADDRESS'] = initiator_host_address
185-
186-
# set environ for target
187-
environ['WATCHER.TARGET_PROJECT_ID'] = target_project_id
188-
environ['WATCHER.TARGET_TYPE_URI'] = target_type_uri
189-
190-
# general cadf attributes
191-
environ['WATCHER.ACTION'] = cadf_action
192-
environ['WATCHER.SERVICE_TYPE'] = self.service_type
193-
environ['WATCHER.CADF_SERVICE_NAME'] = self.strategy.get_cadf_service_name()
194-
195-
# labels applied to all metrics emitted by this middleware
196-
labels = [
197-
"service_name:{0}".format(self.strategy.get_cadf_service_name()),
198-
"service:{0}".format(self.service_type),
199-
"action:{0}".format(cadf_action),
200-
"target_type_uri:{0}".format(target_type_uri),
201-
]
202-
203-
# additional labels not needed in all metrics
204-
detail_labels = [
205-
"initiator_project_id:{0}".format(initiator_project_id),
206-
"initiator_domain_id:{0}".format(initiator_domain_id),
207-
]
208-
detail_labels = labels + detail_labels
209-
210-
# include the target project id in metric
211-
if self.is_include_target_project_id_in_metric:
212-
detail_labels.append(
213-
"target_project_id:{0}".format(target_project_id)
214-
)
215-
216-
# include initiator user id
217-
if self.is_include_initiator_user_id_in_metric:
218-
detail_labels.append(
219-
"initiator_user_id:{0}".format(initiator_user_id)
220-
)
214+
# include initiator user id
215+
if self.is_include_initiator_user_id_in_metric:
216+
detail_labels.append(
217+
"initiator_user_id:{0}".format(initiator_user_id)
218+
)
221219

222-
# if swift request: determine target.container_id based on request path
223-
if common.is_swift_request(req.path) or self.service_type == 'object-store':
224-
_, target_container_id = self.get_target_account_container_id_from_request(req)
225-
environ['WATCHER.TARGET_CONTAINER_ID'] = target_container_id
220+
# if swift request: determine target.container_id based on request path
221+
if common.is_swift_request(req.path) or self.service_type == 'object-store':
222+
_, target_container_id = self.get_target_account_container_id_from_request(req)
223+
environ['WATCHER.TARGET_CONTAINER_ID'] = target_container_id
226224

227-
self.logger.debug(
228-
'got request with initiator_project_id: {0}, initiator_domain_id: {1}, initiator_user_id: {2}, '
229-
'target_project_id: {3}, action: {4}, target_type_uri: {5}'.format(
230-
initiator_project_id, initiator_domain_id, initiator_user_id, target_project_id,
231-
cadf_action, target_type_uri
225+
self.logger.debug(
226+
'got request with initiator_project_id: {0}, initiator_domain_id: {1}, initiator_user_id: {2}, '
227+
'target_project_id: {3}, action: {4}, target_type_uri: {5}'.format(
228+
initiator_project_id, initiator_domain_id, initiator_user_id, target_project_id,
229+
cadf_action, target_type_uri
230+
)
232231
)
233-
)
232+
except UnicodeDecodeError:
233+
# https://github.com/Pylons/webob/issues/161
234+
# accessing req.path on not correct encoded request path causing this
235+
self.logger.debug("failed to determine CADF attributes: UnicodeDecodeError")
234236

235237
# capture the response status
236238
response_wrapper = {}

0 commit comments

Comments
 (0)