Skip to content

Commit

Permalink
Merge pull request #248 from harshavardhana/pr_out_add_simpler_code_f…
Browse files Browse the repository at this point in the history
…or_is_valid_bucket_name_is_valid_url_use_self_endpoint_url_not_self_url

Add simpler code for is_valid_bucket_name, is_valid_url, use self._endpoint_url not self._url
  • Loading branch information
Harshavardhana committed Jul 21, 2015
2 parents dc0ab38 + 0483f03 commit 6ae42a1
Show file tree
Hide file tree
Showing 18 changed files with 164 additions and 156 deletions.
19 changes: 6 additions & 13 deletions minio/_compat.py → minio/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,19 @@
import sys

try:
from urllib.parse import urlparse as compat_urllib_parse
from urllib.parse import urlsplit
except ImportError: # python 2
from urlparse import urlparse as compat_urllib_parse
from urlparse import urlsplit

try:
from urllib.request import pathname2url as compat_pathname2url
from urllib.request import pathname2url as urlencode
except ImportError: # python 2
from urllib import pathname2url as compat_pathname2url
from urllib import pathname2url as urlencode

try:
from urllib.request import url2pathname as compat_url2pathname
from urllib.request import url2pathname as urldecode
except ImportError: # python 2
from urllib import url2pathname as compat_url2pathname


def urlencode(text):
if sys.version_info < (3, 0):
return compat_url2pathname(text.encode('utf-8'))
else:
return compat_url2pathname(text)
from urllib import url2pathname as urldecode


strtype = None
Expand Down
26 changes: 24 additions & 2 deletions minio/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,33 @@
# See the License for the specific language governing permissions and
# limitations under the License.

class InvalidURLError(Exception):
def __init__(self, message, **kwargs):
self.message = message
super(InvalidURLError, self).__init__(**kwargs)

def __str__(self):
string_format = 'InvalidURLError: message: {0}'
return string_format.format(self.message)

class InvalidBucketError(Exception):
pass
def __init__(self, message, **kwargs):
self.message = message
super(InvalidBucketError, self).__init__(**kwargs)

def __str__(self):
string_format = 'InvalidBucketError: message: {0}'
return string_format.format(self.message)

class InvalidArgumentError(Exception):
pass
def __init__(self, message, **kwargs):
self.message = message
super(InvalidArgumentError, self).__init__(**kwargs)

def __str__(self):
string_format = 'InvalidArgumentError: message: {0}'
return string_format.format(self.message)


class ResponseError(Exception):
def __init__(self, code, message, request_id, host_id, resource, xml=None,
Expand Down
14 changes: 7 additions & 7 deletions minio/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ListObjectsIterator(object):
def __init__(self, client, url, bucket, prefix,
recursive, access_key, secret_key):
self._http = client
self._url = url
self._endpoint_url = url
self._bucket = bucket
self._prefix = prefix
self._recursive = recursive
Expand Down Expand Up @@ -67,7 +67,7 @@ def _fetch(self):
if self._marker is not None:
query['marker'] = self._marker

url = get_target_url(self._url, bucket=self._bucket, query=query)
url = get_target_url(self._endpoint_url, bucket=self._bucket, query=query)

method = 'GET'
headers = {}
Expand All @@ -89,7 +89,7 @@ def __init__(self, client, url, bucket, key=None,
access_key=None, secret_key=None):
# from user
self._http = client
self._url = url
self._endpoint_url = url
self._bucket = bucket
self._key = key
self._access_key = access_key
Expand Down Expand Up @@ -145,7 +145,7 @@ def _fetch(self):
if self._upload_id_marker is not None:
query['upload-id-marker'] = self._upload_id_marker

url = get_target_url(self._url, bucket=self._bucket, query=query)
url = get_target_url(self._endpoint_url, bucket=self._bucket, query=query)

method = 'GET'
headers = {}
Expand All @@ -167,7 +167,7 @@ def __init__(self, client, url, bucket, key, upload_id,
access_key=None, secret_key=None):
# from user
self._http = client
self._url = url
self._endpoint_url = url
self._bucket = bucket
self._key = key
self._upload_id = upload_id
Expand Down Expand Up @@ -218,8 +218,8 @@ def _fetch(self):
if self._part_marker is not None:
query['part-number-marker'] = self._part_marker

url = get_target_url(self._url, bucket=self._bucket, key=self._key,
query=query)
url = get_target_url(self._endpoint_url, bucket=self._bucket,
key=self._key, query=query)

method = 'GET'
headers = {}
Expand Down
83 changes: 50 additions & 33 deletions minio/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
Helper functions
"""

import cgi
import collections
import binascii
import hashlib
import re

from ._compat import strtype, compat_pathname2url
from .compat import urlsplit, strtype, urlencode
from .error import InvalidBucketError, InvalidURLError

def get_region(hostname):
"""
Expand Down Expand Up @@ -70,7 +70,7 @@ def get_target_url(url, bucket=None, key=None, query=None):
if ordered_query[component_key] is not None:
single_component.append('=')
single_component.append(
compat_pathname2url(cgi.escape(str(ordered_query[component_key]))).replace('/', '%2F'))
urlencode(str(ordered_query[component_key])).replace('/', '%2F'))
query_components.append(''.join(single_component))

query_string = '&'.join(query_components)
Expand All @@ -80,38 +80,55 @@ def get_target_url(url, bucket=None, key=None, query=None):

return ''.join(url_components)

def is_valid_url(url):
def is_valid_url(endpoint_url):
"""
validate a given url
Verify the endpoint_url is valid.
:type endpoint_url: string
:param endpoint_url: An endpoint_url. Must have at least a scheme
and a hostname.
:return: True if the endpoint url is valid. False otherwise.
"""
if not isinstance(url, strtype):
if not isinstance(endpoint_url, strtype):
raise TypeError('url')

regex = re.compile(
r'^(?:http)s?://' # http:// or https://
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' # domain...
r'localhost|' # localhost...
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|' # ...or ipv4
r'\[?[A-F0-9]*:[A-F0-9:]+\]?)' # ...or ipv6
r'(?::\d+)?' # optional port
r'(?:/?|[/?]\S+)$', re.IGNORECASE)

if not regex.match(url):
raise ValueError('url')

def is_valid_bucket_name(bucketname):
"""
validate a given bucketname
"""
is_non_empty_string(bucketname)
if len(bucketname) < 3 or len(bucketname) > 63:
raise ValueError('bucket')
if '/' in bucketname:
raise ValueError('bucket')
if not re.match("^[a-z0-9]+[a-z0-9\\-]*[a-z0-9]+$", bucketname):
raise ValueError('bucket')
if re.match("/[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+/", bucketname):
raise ValueError('bucket')
parts = urlsplit(endpoint_url)
hostname = parts.hostname
if hostname is None:
raise InvalidURLError('url')
if len(hostname) > 255:
raise InvalidURLError('url')
if hostname[-1] == ".":
hostname = hostname[:-1]
allowed = re.compile(
"^((?!-)[A-Z\d-]{1,63}(?<!-)\.)*((?!-)[A-Z\d-]{1,63}(?<!-))$",
re.IGNORECASE)
if not allowed.match(hostname):
raise InvalidURLError('url')

def is_valid_bucket_name(bucket_name):
"""
Check to see if the ``bucket_name`` complies with the
restricted DNS naming conventions necessary to allow
access via virtual-hosting style.
Even though "." characters are perfectly valid in this DNS
naming scheme, we are going to punt on any name containing a
"." character because these will cause SSL cert validation
problems if we try to use virtual-hosting style addressing.
"""
validbucket = re.compile('[a-z0-9][a-z0-9\-]*[a-z0-9]')
if '.' in bucket_name:
raise InvalidBucketError('bucket')
n = len(bucket_name)
if n < 3 or n > 63:
# Wrong length
raise InvalidBucketError('bucket')
if n == 1:
if not bucket_name.isalnum():
raise InvalidBucketError('bucket')
match = validbucket.match(bucket_name)
if match is None or match.end() != len(bucket_name):
raise InvalidBucketError('bucket')

def is_non_empty_string(input_string):
"""
Expand All @@ -127,7 +144,7 @@ def encode_object_key(key):
url encode object key
"""
is_non_empty_string(key)
return compat_pathname2url(key)
return urlencode(key)

def get_sha256(content):
"""
Expand All @@ -139,7 +156,7 @@ def get_sha256(content):
hasher.update(content)
return hasher.digest()

def get_md5(content):
def get_md5(cntoent):
"""
calculate md5 for given content
"""
Expand Down
Loading

0 comments on commit 6ae42a1

Please sign in to comment.