def submit(method, uri, body, headers):
    """ Submit one HTTP request.
    """
    for key, value in headers.items():
        del headers[key]
        headers[xstr(key)] = xstr(value)
    headers["Host"] = xstr(uri.host_port)
    if uri.user_info:
        credentials = uri.user_info.encode("UTF-8")
        value = "Basic " + b64encode(credentials).decode("ASCII")
        headers["Authorization"] = value
    try:
        http = ConnectionPool.acquire(uri.scheme, uri.host_port)
    except KeyError:
        raise ValueError("Unsupported URI scheme " + repr(uri.scheme))

    def send(reconnect=None):
        if reconnect:
            log.info("~ Reconnecting (%s)", reconnect)
            http.close()
            http.connect()
        if (method == "GET" or method == "DELETE") and not body:
            log.info("> %s %s", method, uri.string)
        elif body:
            log.info("> %s %s [%s]", method, uri.string, len(body))
        else:
            log.info("> %s %s [%s]", method, uri.string, 0)
        for key, value in headers.items():
            log.debug("> %s: %s", key, value)
        http.request(xstr(method), xstr(uri.absolute_path_reference), body, headers)
        return http.getresponse(**getresponse_args)

    try:
        try:
            response = send()
        except BadStatusLine as err:
            if err.line == "''":
                response = send("peer closed connection")
            else:
                raise
        except ResponseNotReady:
            response = send("response not ready")
        except timeout:
            response = send("timeout")
        except error as err:
            if isinstance(err.args[0], tuple):
                code = err.args[0][0]
            else:
                code = err.args[0]
            if code in retry_codes:
                response = send(retry_codes[code])
            else:
                raise
    except (gaierror, herror) as err:
        raise NetworkAddressError(err.args[1], host_port=uri.host_port)
    except error as err:
        if isinstance(err.args[0], tuple):
            code, description = err.args[0]
        elif isinstance(err.args[0], int):
            code = err.args[0]
            try:
                description = strerror(code)
            except __HOLE__:
                description = None
        else:
            code, description = None, err.args[0]
        if code == 2:
            # Workaround for Linux bug with incorrect error message on
            # host resolution
            # ----
            # https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/1154599
            raise NetworkAddressError("Name or service not known",
                                      host_port=uri.host_port)
        else:
            raise SocketError(code, description, host_port=uri.host_port)
    else:
        return http, response
dataset/ETHPy150Open nigelsmall/httpstream/httpstream/http.py/submit