예제 #1
0
def closeConn(conn, connHolder):
    try:
        if conn:
            conn.close()
    except Exception as ex:
        LOG(ERROR, ex)
    finally:
        if connHolder is not None:
            connHolder['lock'].acquire()
            try:
                connHolder['connSet'].remove(conn)
            except Exception as ex1:
                LOG(WARNING, ex1)
            finally:
                connHolder['lock'].release()
예제 #2
0
    def getSignature(self, method, bucket, key, args_path, headers, payload=None):
        outPut = 'AWS4-HMAC-SHA256' + '\n'
        outPut += self.longDate + '\n'
        outPut += self.getScope() + '\n'
        cannonicalRequest = self.getCanonicalRequest(method, bucket, key, args_path, headers, payload)
        LOG(DEBUG, 'v4 cannonicalRequest: %s' % cannonicalRequest)
        if IS_PYTHON2:
            stringToSign = outPut + self.__shaCannonicalRequest_python2(cannonicalRequest)
            signingKey = self.getSigningKey_python2()
        else:
            stringToSign = outPut + self.__shaCannonicalRequest_python3(cannonicalRequest)
            stringToSign = stringToSign.encode('UTF-8')
            signingKey = self.getSigningKey_python3()

        return self.hmacSha256(signingKey, stringToSign)
예제 #3
0
def doClose(result, conn, connHolder):
    if not result:
        closeConn(conn, connHolder)
    elif 'close' == result.getheader('connection', '').lower() or 'close' == result.getheader('Connection', '').lower():
        LOG(INFO, 'server inform to close connection')
        closeConn(conn, connHolder)
    elif toInt(result.status) >= 500 or connHolder is None:
        closeConn(conn, connHolder)
    else:
        if connHolder is not None:
            connHolder['lock'].acquire()
            try:
                return connHolder['connSet'].add(conn)
            finally:
                connHolder['lock'].release()
예제 #4
0
 def parse_xml(cls, conn, methodName=None, connHolder=None, readable=False):
     if not conn:
         return cls.getNoneResult('connection is null')
     result = None
     try:
         result = conn.getresponse()
         if not result:
             return cls.getNoneResult('response is null')
         return cls.__parse_xml(result, methodName, readable=readable)
     except RedirectException as ex:
         raise ex
     except Exception as e:
         LOG(ERROR, traceback.format_exc())
         raise e
     finally:
         GetResult.doClose(result, conn, connHolder)
예제 #5
0
 def parse_xml(cls, conn, methodName=None, connHolder=None):
     if not conn:
         return cls.getNoneResult('connection is null')
     result = None
     try:
         result = conn.getresponse()
         if not result:
             return cls.getNoneResult('response is null')
         return cls.__parse_xml(result, methodName)
     except RedirectException as re:
         raise re
     except Exception as e:
         LOG(ERROR, traceback.format_exc())
         return cls.getNoneResult(common_util.toString(e))
     finally:
         GetResult.doClose(result, conn, connHolder)
예제 #6
0
def doClose(result, conn, connHolder):
    if not result:
        closeConn(conn, connHolder)
    elif result.getheader('connection', '').lower() == 'close' or result.getheader('Connection', '').lower() == 'close':
        LOG(INFO, 'server inform to close connection')
        closeConn(conn, connHolder)
    elif toInt(result.status) >= 500 or connHolder is None:
        closeConn(conn, connHolder)
    elif hasattr(conn, '_redirect') and conn._redirect:
        closeConn(conn, connHolder)
    else:
        if connHolder is not None:
            connHolder['lock'].acquire()
            try:
                connHolder['connSet'].add(conn)
            finally:
                connHolder['lock'].release()
예제 #7
0
 def getSignature(self,
                  method,
                  bucket,
                  key,
                  path_args,
                  headers,
                  expires=None):
     canonical_string = self.__make_canonicalstring(method, bucket, key,
                                                    path_args, headers,
                                                    expires)
     LOG(DEBUG, 'v2 canonical_string: %s' % canonical_string)
     if IS_PYTHON2:
         hashed = hmac.new(self.sk, canonical_string, hashlib.sha1)
         encode_canonical = binascii.b2a_base64(hashed.digest())[:-1]
     else:
         hashed = hmac.new(self.sk.encode('UTF-8'),
                           canonical_string.encode('UTF-8'), hashlib.sha1)
         encode_canonical = binascii.b2a_base64(
             hashed.digest())[:-1].decode('UTF-8')
     return encode_canonical
예제 #8
0
    def parse_content(cls,
                      conn,
                      objectKey,
                      downloadPath=None,
                      chuckSize=65536,
                      loadStreamInMemory=False,
                      connHolder=None):
        if not conn:
            return cls.getNoneResult('connection is null')
        closeConn = True
        result = None
        try:
            result = conn.getresponse()
            if not result:
                return cls.getNoneResult('response is null')

            if connHolder and hasattr(connHolder, 'createTimeStamp'):
                connHolder.createTimeStamp = time.time()

            if not common_util.toInt(result.status) < 300:
                return cls.__parse_xml(result)

            if loadStreamInMemory:
                LOG(DEBUG,
                    'loadStreamInMemory is True, read stream into memory')
                buf = None
                while True:
                    chunk = result.read(chuckSize)
                    if not chunk:
                        break
                    if buf is None:
                        buf = chunk
                    else:
                        buf += chunk
                body = ObjectStream(buffer=buf,
                                    size=common_util.toLong(len(buf)))
            elif downloadPath is None or common_util.toString(
                    downloadPath).strip() == '':
                LOG(DEBUG, 'DownloadPath is null, return conn directly')
                closeConn = False
                body = ObjectStream(
                    response=ResponseWrapper(conn, result, connHolder))
            else:
                objectKey = common_util.safe_encode(objectKey)
                downloadPath = common_util.safe_encode(downloadPath)
                file_path = cls.get_data(result, downloadPath, chuckSize)
                body = ObjectStream(url=common_util.toString(file_path))
                LOG(DEBUG,
                    'DownloadPath is ' + common_util.toString(file_path))

            status = common_util.toInt(result.status)
            reason = result.reason
            headers = dict(result.getheaders())
            header = cls.__parse_headers(headers)
            requestId = headers.get('x-amz-request-id')

            convert_util.parseGetObject(dict(header), body)
            return GetResult(status=status,
                             reason=reason,
                             header=header,
                             body=body,
                             requestId=requestId)
        except RedirectException as ex:
            raise ex
        except Exception as e:
            LOG(ERROR, traceback.format_exc())
            raise e
        finally:
            if closeConn:
                GetResult.doClose(result, conn, connHolder)
예제 #9
0
    def __parse_xml(cls,
                    result,
                    methodName=None,
                    chuckSize=65536,
                    readable=False):
        status = common_util.toInt(result.status)
        reason = result.reason
        code = None
        message = None
        body = None
        requestId = None
        hostId = None
        resource = None
        headers = dict(result.getheaders())
        xml = None
        while True:
            chunk = result.read(chuckSize)
            if not chunk:
                break
            xml = chunk if xml is None else xml + chunk

        if status == 307 and not readable and ('location' in headers
                                               or 'Location' in headers):
            location = headers.get('location')
            if location is None:
                location = headers.get('Location')
            LOG(WARNING, 'http code is %d, need to redirect to %s', status,
                location)
            cls.CONTEXT.location = location
            raise RedirectException(
                'http code is {0}, need to redirect to {1}'.format(
                    status, location))
        else:
            header = cls.__parse_headers(headers)
            if status < 300:
                if methodName is not None:
                    methodName = 'parse' + methodName[:1].upper(
                    ) + methodName[1:]
                    parseMethod = getattr(convert_util, methodName)
                    if parseMethod is not None:
                        if xml:
                            xml = xml if IS_PYTHON2 else xml.decode('UTF-8')
                            LOG(DEBUG, 'recv Msg:%s', xml)
                            try:
                                search = cls.PATTERN.search(xml)
                                xml = xml if search is None else xml.replace(
                                    search.group(), '')
                                body = parseMethod(xml, dict(header))
                            except Exception as e:
                                LOG(ERROR, e)
                        else:
                            body = parseMethod(dict(header))
                requestId = headers.get('x-amz-request-id')
            elif xml:
                xml = xml if IS_PYTHON2 else xml.decode('UTF-8')
                try:
                    search = cls.PATTERN.search(xml)
                    xml = xml if search is None else xml.replace(
                        search.group(), '')
                    root = ET.fromstring(xml)
                    code = root.find('./Code')
                    code = code.text if code is not None else None
                    message = root.find('./Message')
                    message = message.text if message is not None else None
                    requestId = root.find('./RequestId')
                    requestId = requestId.text if requestId is not None else None
                    hostId = root.find('./HostId')
                    hostId = hostId.text if hostId is not None else None
                    key = root.find('./Key')
                    bucket = root.find('./BucketName')
                    resource = bucket if bucket is not None else key
                    resource = resource.text if resource is not None else None
                except Exception as ee:
                    LOG(ERROR, common_util.toString(ee))
                    LOG(ERROR, traceback.format_exc())

        LOG(
            DEBUG,
            'http response result:status:%d,reason:%s,code:%s,message:%s,headers:%s',
            status, reason, code, message, header)

        return GetResult(code=code,
                         message=message,
                         status=status,
                         reason=reason,
                         body=body,
                         requestId=requestId,
                         hostId=hostId,
                         resource=resource,
                         header=header)