From 1adadb82fe8866cabd4d0644ac916eddd614bdd7 Mon Sep 17 00:00:00 2001 From: Bala FA Date: Tue, 10 Nov 2020 08:30:11 +0530 Subject: [PATCH] Handle response XML inside _create_multipart_upload() API (#1009) --- minio/api.py | 6 +-- minio/parsers.py | 126 ----------------------------------------------- 2 files changed, 3 insertions(+), 129 deletions(-) diff --git a/minio/api.py b/minio/api.py index a4a9b1715..c3f2e915b 100644 --- a/minio/api.py +++ b/minio/api.py @@ -61,8 +61,7 @@ from .lifecycleconfig import LifecycleConfig from .notificationconfig import NotificationConfig from .objectlockconfig import ObjectLockConfig -from .parsers import (parse_error_response, - parse_new_multipart_upload) +from .parsers import parse_error_response from .replicationconfig import ReplicationConfig from .retention import Retention from .select import SelectObjectReader @@ -1213,7 +1212,8 @@ def _create_multipart_upload(self, bucket_name, object_name, headers): headers=headers, query_params={"uploads": ""}, ) - return parse_new_multipart_upload(response.data) + element = ET.fromstring(response.data.decode()) + return findtext(element, "UploadId") def _put_object(self, bucket_name, object_name, data, headers, query_params=None): diff --git a/minio/parsers.py b/minio/parsers.py index 4bcdc195f..251a1a8b7 100644 --- a/minio/parsers.py +++ b/minio/parsers.py @@ -25,124 +25,9 @@ """ -from datetime import timezone -from urllib.parse import unquote from xml.etree import ElementTree -from xml.etree.ElementTree import ParseError from .error import S3Error -from .helpers import strptime_rfc3339 - -# dependencies. - - -_XML_NS = { - 's3': 'http://s3.amazonaws.com/doc/2006-03-01/', -} - - -class S3Element: - """S3 aware XML parsing class. Wraps a root element name and - ElementTree.Element instance. Provides S3 namespace aware parsing - functions. - - """ - - def __init__(self, root_name, element): - self.root_name = root_name - self.element = element - - @classmethod - def fromstring(cls, root_name, data): - """Initialize S3Element from name and XML string data. - - :param name: Name for XML data. Used in XML errors. - :param data: string data to be parsed. - :return: Returns an S3Element. - """ - try: - return cls(root_name, ElementTree.fromstring(data.strip())) - except (ParseError, AttributeError, ValueError, TypeError) as exc: - raise ValueError( - '"{}" XML is not parsable.'.format(root_name), - ) from exc - - def findall(self, name): - """Similar to ElementTree.Element.findall() - - """ - return [ - S3Element(self.root_name, elem) - for elem in self.element.findall('s3:{}'.format(name), _XML_NS) - ] - - def find(self, name): - """Similar to ElementTree.Element.find() - - """ - elt = self.element.find('s3:{}'.format(name), _XML_NS) - return S3Element(self.root_name, elt) if elt else None - - def get_child_text(self, name, strict=True): - """Extract text of a child element. If strict, and child element is - not present, raises ValueError and otherwise returns - None. - - """ - if strict: - try: - return self.element.find('s3:{}'.format(name), _XML_NS).text - except (ParseError, AttributeError, ValueError, TypeError) as exc: - raise ValueError( - ( - 'Invalid XML provided for "{}" - erroring tag <{}>' - ).format(self.root_name, name), - ) from exc - else: - return self.element.findtext('s3:{}'.format(name), None, _XML_NS) - - def get_urldecoded_elem_text(self, name, strict=True): - """Like self.get_child_text(), but also performs urldecode() on the - result. - - """ - text = self.get_child_text(name, strict) - # strictness is already enforced above. - return unquote(text) if text is not None else None - - def get_etag_elem(self, strict=True): - """Fetches an 'ETag' child element suitably processed. - - """ - return self.get_child_text('ETag', strict).replace('"', '') - - def get_int_elem(self, name): - """Fetches an integer type XML child element by name. - - """ - return int(self.get_child_text(name)) - - def get_time_elem(self, name): - """Parse a time XML child element. - - """ - return strptime_rfc3339( - self.get_child_text(name), - ).replace(tzinfo=timezone.utc) - - def text(self): - """Fetch the current node's text - - """ - return self.element.text - - def is_dir(self): - """Returns True if the object is a dir - ie, if an object name has `/` suffixed. - - """ - text = self.get_child_text('Key') - return text.endswith("/") def parse_error_response(response): @@ -164,14 +49,3 @@ def _get_text(name): object_name=_get_text("Key"), response=response, ) - - -def parse_new_multipart_upload(data): - """ - Parser for new multipart upload response. - - :param data: Response data for new multipart upload. - :return: Returns a upload id. - """ - root = S3Element.fromstring('InitiateMultipartUploadResult', data) - return root.get_child_text('UploadId')