(self, request, retries=None)
| 1691 | "region =====") |
| 1692 | |
| 1693 | def send_request(self, request, retries=None): |
| 1694 | if retries is None: |
| 1695 | retries = self.config.max_retries |
| 1696 | self.update_region_inner_request(request) |
| 1697 | |
| 1698 | request.body = encode_to_s3(request.body) |
| 1699 | headers = request.headers |
| 1700 | |
| 1701 | method_string, resource, headers = request.get_triplet() |
| 1702 | response = {} |
| 1703 | debug("Processing request, please wait...") |
| 1704 | |
| 1705 | conn = None |
| 1706 | try: |
| 1707 | conn = ConnMan.get(self.get_hostname(resource['bucket'])) |
| 1708 | # TODO: Check what was supposed to be the usage of conn.path here |
| 1709 | # Currently this is always "None" all the time as not defined in ConnMan |
| 1710 | uri = self.format_uri(resource, conn.path) |
| 1711 | debug("Sending request method_string=%r, uri=%r, headers=%r, body=(%i bytes)" % (method_string, uri, headers, len(request.body or ""))) |
| 1712 | conn.c.request(method_string, uri, request.body, headers) |
| 1713 | http_response = conn.c.getresponse() |
| 1714 | response["status"] = http_response.status |
| 1715 | response["reason"] = http_response.reason |
| 1716 | response["headers"] = convertHeaderTupleListToDict(http_response.getheaders()) |
| 1717 | response["data"] = http_response.read() |
| 1718 | if "x-amz-meta-s3cmd-attrs" in response["headers"]: |
| 1719 | attrs = parse_attrs_header(response["headers"]["x-amz-meta-s3cmd-attrs"]) |
| 1720 | response["s3cmd-attrs"] = attrs |
| 1721 | ConnMan.put(conn) |
| 1722 | except (S3SSLError, S3SSLCertificateError): |
| 1723 | # In case of failure to validate the certificate for a ssl |
| 1724 | # connection,no need to retry, abort immediately |
| 1725 | raise |
| 1726 | except (IOError, Exception) as e: |
| 1727 | debug("Response:\n" + pprint.pformat(response)) |
| 1728 | if ((hasattr(e, 'errno') and e.errno |
| 1729 | and e.errno not in (errno.EPIPE, errno.ECONNRESET, errno.ETIMEDOUT)) |
| 1730 | or "[Errno 104]" in str(e) |
| 1731 | or "[Errno 32]" in str(e) |
| 1732 | ) and not isinstance(e, SocketTimeoutException): |
| 1733 | raise |
| 1734 | # When the connection is broken, BadStatusLine is raised with py2 |
| 1735 | # and RemoteDisconnected is raised by py3 with a trap: |
| 1736 | # RemoteDisconnected has an errno field with a None value. |
| 1737 | |
| 1738 | # close the connection and re-establish |
| 1739 | ConnMan.close(conn) |
| 1740 | if retries: |
| 1741 | warning("Retrying failed request: %s (%s)" % (resource['uri'], e)) |
| 1742 | warning("Waiting %d sec..." % self._fail_wait(retries)) |
| 1743 | time.sleep(self._fail_wait(retries)) |
| 1744 | return self.send_request(request, retries - 1) |
| 1745 | else: |
| 1746 | raise S3RequestError("Request failed for: %s" % resource['uri']) |
| 1747 | |
| 1748 | except: |
| 1749 | # Only KeyboardInterrupt and SystemExit will not be covered by Exception |
| 1750 | debug("Response:\n" + pprint.pformat(response)) |
no test coverage detected