def _get_stream_length(self): file_length = 0 for k, ff in self.files.items(): field_length = len(TC.to_bytes(ff.filename)) + len(ff.content_type) +\ len(TC.to_bytes(k)) + len(self.boundary) + 78 if isinstance(ff.content, BytesIO): file_length += len(ff.content.getvalue()) + field_length else: file_length += os.path.getsize(ff.content.name) + field_length stream_length = self.str_length + file_length + len(self.boundary) + 6 return stream_length
def _build_str_forms(self): form_str = '' str_fmt = '--%s\r\nContent-Disposition: form-data; name="%s"\r\n\r\n%s\r\n' forms_list = sorted(list(self.forms)) for key in forms_list: value = self.forms[key] form_str += str_fmt % (self.boundary, key, value) self.form_str = TC.to_bytes(form_str)
def assert_as_readable(value): """ Assert a value, if it is a readable, return it, otherwise throws @return: the readable value """ if isinstance(value, TeaConverter.basestring): value = BytesIO(TeaConverter.to_bytes(value)) if not isinstance(value, READABLE): raise ValueError('The value is not a readable') return value
def get_rpcsignature(signed_params, method, secret): """ Get signature according to signedParams, method and secret @type signed_params: dict @param signed_params: params which need to be signed @type method: str @param method: http method e.g. GET @type secret: str @param secret: AccessKeySecret @return: the signature """ queries = signed_params.copy() keys = list(queries.keys()) keys.sort() canonicalized_query_string = "" for k in keys: if queries[k] is not None: canonicalized_query_string += "&" canonicalized_query_string += quote(TeaConverter.to_str(k), safe='') canonicalized_query_string += "=" canonicalized_query_string += quote(TeaConverter.to_str(queries[k]), safe='') string_to_sign = "" string_to_sign += method string_to_sign += '&' string_to_sign += quote_plus("/") string_to_sign += '&' string_to_sign += quote_plus( canonicalized_query_string[1:]) digest_maker = hmac.new(TeaConverter.to_bytes(secret + '&'), TeaConverter.to_bytes(string_to_sign), digestmod=hashlib.sha1) hash_bytes = digest_maker.digest() signed_str = TeaConverter.to_string(base64.b64encode(hash_bytes)) return signed_str
def read_as_bytes(stream): """ Read data from a readable stream, and compose it to a bytes @param stream: the readable stream @return: the bytes result """ if isinstance(stream, TeaConverter.basestring): return TeaConverter.to_bytes(stream) else: b = '' for part in Client.__read_part(stream, 1024): b += part return b
def file_str(self, size): # handle file object form_str = b'' start_fmt = '--%s\r\nContent-Disposition: form-data; name="%s";' content_fmt = b' filename="[%s]"\r\nContent-Type: [%s]\r\n\r\n[%s]' if self.file_size_left: for key in self.files_keys[:]: if size <= 0: break file_field = self.files[key] file_content = TC.to_bytes(file_field.content.read(size)) if self.file_size_left <= size: form_str += b'[%s]\r\n'.replace(FMT, file_content, 1) self.file_size_left = 0 size -= len(file_content) self.files_keys.remove(key) else: form_str += file_content self.file_size_left -= size size -= len(file_content) else: for key in self.files_keys[:]: if size <= 0: break file_field = self.files[key] if isinstance(file_field.content, BytesIO): file_size = len(file_field.content.getvalue()) else: file_size = os.path.getsize(file_field.content.name) self.file_size_left = file_size file_content = TC.to_bytes(file_field.content.read(size)) # build form_str start = start_fmt % (self.boundary, key) content = content_fmt.replace(FMT, TC.to_bytes(file_field.filename), 1)\ .replace(FMT, TC.to_bytes(file_field.content_type), 1)\ .replace(FMT, file_content, 1) if self.file_size_left < size: form_str += b'[%s][%s]\r\n'.replace(FMT, TC.to_bytes(start), 1).replace(FMT, content, 1) self.file_size_left = 0 size -= len(file_content) self.files_keys.remove(key) else: form_str += b'[%s][%s]'.replace(FMT, TC.to_bytes(start), 1).replace(FMT, content, 1) self.file_size_left -= size size -= len(file_content) return form_str
def read(self, size=None, loop=False): if not self.files_keys and not self.form_str: self.refresh() if loop: raise StopIteration else: return b'' if size is None: size = self.MAX_SIZE if self.form_str: form_str = self.form_str[:size] self.form_str = self.form_str[size:] if len(form_str) < size: form_str += self.file_str(size) else: form_str = self.file_str(size) if not self.form_str and not self.files_keys: form_str += b'--[%s]--\r\n'.replace(FMT, TC.to_bytes(self.boundary), 1) return form_str
def to_bytes(val): """ Convert a string(utf8) to bytes @return: the return bytes """ return TeaConverter.to_bytes(val)