Ejemplo n.º 1
0
def handler(method, host, url, headers, body, wfile):
    time_request = time.time()

    errors = []
    response = None
    while True:
        if time.time() - time_request > 30:
            return return_fail_message(wfile)

        try:
            response = fetch(method, host, url, headers, body)
            if response:
                break
        except OpenSSL.SysCallError as e:
            errors.append(e)
            logging.warn("direct_handler.handler err:%r %s/%s", e, host, url)
        except Exception as e:
            errors.append(e)
            logging.exception('direct_handler.handler %r %s %s , retry...', e, host, url)

    try:
        send_to_browser = True
        try:
            wfile.write("HTTP/1.1 %d %s\r\n" % (response.status, response.reason))
            response_headers = dict((k.title(), v) for k, v in response.getheaders())
            for key, value in response.getheaders():
                send_header(wfile, key, value)
            wfile.write("\r\n")
        except Exception as e:
            send_to_browser = False
            wait_time = time.time()-time_request
            logging.warn("direct_handler.handler send response fail. t:%d e:%r %s%s", wait_time, e, host, url)


        if method == 'HEAD' or response.status in (204, 304):
            logging.info("DIRECT t:%d %d %s %s", (time.time()-time_request)*1000, response.status, host, url)
            https_manager.save_ssl_connection_for_reuse(response.ssl_sock, host)
            response.close()
            return

        if 'Transfer-Encoding' in response_headers:
            length = 0
            while True:
                try:
                    data = response.read(8192)
                except httplib.IncompleteRead, e:
                    data = e.partial

                if send_to_browser:
                    try:
                        if not data:
                            wfile.write('0\r\n\r\n')
                            break
                        length += len(data)
                        wfile.write('%x\r\n' % len(data))
                        wfile.write(data)
                        wfile.write('\r\n')
                    except Exception as e:
                        send_to_browser = False
                        logging.warn("direct_handler.handler send Transfer-Encoding t:%d e:%r %s/%s", time.time()-time_request, e, host, url)
                else:
                    if not data:
                        break

            response.close()
            logging.info("DIRECT chucked t:%d s:%d %d %s %s", (time.time()-time_request)*1000, length, response.status, host, url)
            return

        content_length = int(response.getheader('Content-Length', 0))
        content_range = response.getheader('Content-Range', '')
        if content_range:
            start, end, length = tuple(int(x) for x in re.search(r'bytes (\d+)-(\d+)/(\d+)', content_range).group(1, 2, 3))
        else:
            start, end, length = 0, content_length-1, content_length

        time_last_read = time.time()
        while True:
            if start > end:
                https_manager.save_ssl_connection_for_reuse(response.ssl_sock, host)
                logging.info("DIRECT t:%d s:%d %d %s %s", (time.time()-time_request)*1000, length, response.status, host, url)
                return

            data = response.read(config.AUTORANGE_BUFSIZE)
            if not data:
                if time.time() - time_last_read > 20:
                    response.close()
                    logging.warn("read timeout t:%d len:%d left:%d %s %s", (time.time()-time_request)*1000, length, (end-start), host, url)
                    return
                else:
                    time.sleep(0.1)
                    continue

            time_last_read = time.time()
            data_len = len(data)
            start += data_len
            if send_to_browser:
                try:
                    ret = wfile.write(data)
                    if ret == ssl.SSL_ERROR_WANT_WRITE or ret == ssl.SSL_ERROR_WANT_READ:
                        logging.debug("send to browser wfile.write ret:%d", ret)
                        ret = wfile.write(data)
                except Exception as e_b:
                    if e_b[0] in (errno.ECONNABORTED, errno.EPIPE, errno.ECONNRESET) or 'bad write retry' in repr(e_b):
                        logging.warn('direct_handler send to browser return %r %s %r', e_b, host, url)
                    else:
                        logging.warn('direct_handler send to browser return %r %s %r', e_b, host, url)
                    send_to_browser = False
Ejemplo n.º 2
0
def handler(method, host, url, headers, body, wfile):
    time_request = time.time()

    errors = []
    response = None
    while True:
        if time.time() - time_request > 30:
            return return_fail_message(wfile)

        try:
            response = fetch(method, host, url, headers, body)
            if response:
                break
        except OpenSSL.SysCallError as e:
            errors.append(e)
            xlog.warn("direct_handler.handler err:%r %s/%s", e, host, url)
        except Exception as e:
            errors.append(e)
            xlog.exception("direct_handler.handler %r %s %s , retry...", e, host, url)

    try:
        send_to_browser = True
        try:
            response_headers = dict((k.title(), v) for k, v in response.getheaders())
            wfile.write("HTTP/1.1 %d %s\r\n" % (response.status, response.reason))
            for key, value in response.getheaders():
                send_header(wfile, key, value)
            wfile.write("\r\n")
        except Exception as e:
            send_to_browser = False
            wait_time = time.time() - time_request
            xlog.warn("direct_handler.handler send response fail. t:%d e:%r %s%s", wait_time, e, host, url)

        if method == "HEAD" or response.status in (204, 304):
            xlog.info("DIRECT t:%d %d %s %s", (time.time() - time_request) * 1000, response.status, host, url)
            https_manager.save_ssl_connection_for_reuse(response.ssl_sock, host)
            response.close()
            return

        if "Transfer-Encoding" in response_headers:
            length = 0
            while True:
                try:
                    data = response.read(8192)
                except httplib.IncompleteRead, e:
                    data = e.partial

                if send_to_browser:
                    try:
                        if not data:
                            wfile.write("0\r\n\r\n")
                            break
                        length += len(data)
                        wfile.write("%x\r\n" % len(data))
                        wfile.write(data)
                        wfile.write("\r\n")
                    except Exception as e:
                        send_to_browser = False
                        xlog.warn(
                            "direct_handler.handler send Transfer-Encoding t:%d e:%r %s/%s",
                            time.time() - time_request,
                            e,
                            host,
                            url,
                        )
                else:
                    if not data:
                        break

            response.close()
            xlog.info(
                "DIRECT chucked t:%d s:%d %d %s %s",
                (time.time() - time_request) * 1000,
                length,
                response.status,
                host,
                url,
            )
            return

        content_length = int(response.getheader("Content-Length", 0))
        content_range = response.getheader("Content-Range", "")
        if content_range:
            start, end, length = tuple(
                int(x) for x in re.search(r"bytes (\d+)-(\d+)/(\d+)", content_range).group(1, 2, 3)
            )
        else:
            start, end, length = 0, content_length - 1, content_length

        time_last_read = time.time()
        while True:
            if start > end:
                https_manager.save_ssl_connection_for_reuse(response.ssl_sock, host)
                xlog.info(
                    "DIRECT t:%d s:%d %d %s %s", (time.time() - time_request) * 1000, length, response.status, host, url
                )
                return

            data = response.read(config.AUTORANGE_BUFSIZE)
            if not data:
                if time.time() - time_last_read > 20:
                    response.close()
                    xlog.warn(
                        "read timeout t:%d len:%d left:%d %s %s",
                        (time.time() - time_request) * 1000,
                        length,
                        (end - start),
                        host,
                        url,
                    )
                    return
                else:
                    time.sleep(0.1)
                    continue

            time_last_read = time.time()
            data_len = len(data)
            start += data_len
            if send_to_browser:
                try:
                    ret = wfile.write(data)
                    if ret == ssl.SSL_ERROR_WANT_WRITE or ret == ssl.SSL_ERROR_WANT_READ:
                        xlog.debug("send to browser wfile.write ret:%d", ret)
                        ret = wfile.write(data)
                except Exception as e_b:
                    if e_b[0] in (errno.ECONNABORTED, errno.EPIPE, errno.ECONNRESET) or "bad write retry" in repr(e_b):
                        xlog.warn("direct_handler send to browser return %r %s %r", e_b, host, url)
                    else:
                        xlog.warn("direct_handler send to browser return %r %s %r", e_b, host, url)
                    send_to_browser = False
Ejemplo n.º 3
0
def handler(method, host, url, headers, body, wfile):
    time_request = time.time()

    if "Connection" in headers and headers["Connection"] == "close":
        del headers["Connection"]

    errors = []
    response = None
    while True:
        if time.time() - time_request > 30:
            return return_fail_message(wfile)

        try:
            response = fetch(method, host, url, headers, body)
            if response:
                if response.status > 400:
                    server_type = response.getheader('Server', "")
                    if "gws" not in server_type and "Google Frontend" not in server_type and "GFE" not in server_type:
                        xlog.warn("IP:%s not support GAE, server type:%s status:%d", response.ssl_sock.ip, server_type, response.status)
                        google_ip.report_connect_fail(response.ssl_sock.ip, force_remove=True)
                        response.close()
                        continue
                break
        except OpenSSL.SSL.SysCallError as e:
            errors.append(e)
            xlog.warn("direct_handler.handler err:%r %s/%s", e, host, url)
        except Exception as e:
            errors.append(e)
            xlog.exception('direct_handler.handler %r %s %s , retry...', e, host, url)

    try:
        send_to_browser = True
        try:
            response_headers = dict((k.title(), v) for k, v in response.getheaders())
            wfile.write("HTTP/1.1 %d %s\r\n" % (response.status, response.reason))
            for key, value in response.getheaders():
                send_header(wfile, key, value)
            wfile.write("\r\n")
        except Exception as e:
            send_to_browser = False
            wait_time = time.time()-time_request
            xlog.warn("direct_handler.handler send response fail. t:%d e:%r %s%s", wait_time, e, host, url)


        if method == 'HEAD' or response.status in (204, 304):
            xlog.info("DIRECT t:%d %d %s %s", (time.time()-time_request)*1000, response.status, host, url)
            https_manager.save_ssl_connection_for_reuse(response.ssl_sock, host)
            response.close()
            return

        if 'Transfer-Encoding' in response_headers:
            length = 0
            while True:
                try:
                    data = response.read(8192)
                except httplib.IncompleteRead, e:
                    data = e.partial
                except Exception as e:
                    google_ip.report_connect_closed(response.ssl_sock.ip, "receive fail")
                    xlog.warn("direct_handler.handler send Transfer-Encoding t:%d e:%r %s/%s", time.time()-time_request, e, host, url)
                    response.close()
                    return

                if send_to_browser:
                    try:
                        if not data:
                            wfile.write('0\r\n\r\n')
                            break
                        length += len(data)
                        wfile.write('%x\r\n' % len(data))
                        wfile.write(data)
                        wfile.write('\r\n')
                    except Exception as e:
                        send_to_browser = False
                        xlog.warn("direct_handler.handler send Transfer-Encoding t:%d e:%r %s/%s", time.time()-time_request, e, host, url)
                else:
                    if not data:
                        break
Ejemplo n.º 4
0
def handler(method, host, path, headers, body, wfile, timeout=60):
    time_request = time.time()

    if "Connection" in headers and headers["Connection"] == "close":
        del headers["Connection"]

    errors = []
    while True:
        time_left = time_request + timeout - time.time()
        if time_left <= 0:
            return_fail_message(wfile)
            return "ok"

        try:
            response = direct_front.request(method,
                                            host,
                                            path,
                                            headers,
                                            body,
                                            timeout=time_left)
            if response:
                if response.status > 600:
                    xlog.warn("direct %s %s % status:%d", method, host, path,
                              response.status)
                    continue
                elif response.status > 400:
                    server_type = response.headers.get('Server', "")

                    if "G" not in server_type and "g" not in server_type and server_type not in google_server_types:

                        xlog.warn(
                            "IP:%s host:%s not support GAE, server type:%s status:%d",
                            response.ssl_sock.ip, host, server_type,
                            response.status)
                        direct_front.ip_manager.report_connect_fail(
                            response.ssl_sock.ip, force_remove=True)
                        response.worker.close()
                        continue
                break
        except OpenSSL.SSL.SysCallError as e:
            errors.append(e)
            xlog.warn("direct_handler.handler err:%r %s/%s", e, host, path)
        except Exception as e:
            errors.append(e)
            xlog.exception('direct_handler.handler %r %s %s , retry...', e,
                           host, path)

    response_headers = {}
    for key, value in response.headers.items():
        key = key.title()
        response_headers[key] = value

    response_headers["Persist"] = ""
    response_headers["Connection"] = "Persist"

    try:
        wfile.write("HTTP/1.1 %d %s\r\n" % (response.status, response.reason))
        for key in response_headers:
            value = response_headers[key]
            send_header(wfile, key, value)
        wfile.write("\r\n")
        wfile.flush()

        length = 0
        while True:
            data = response.task.read()
            if isinstance(data, memoryview):
                data = data.tobytes()

            data_len = len(data)
            length += data_len
            if 'Transfer-Encoding' in response.headers:
                if not data_len:
                    wfile._sock.sendall('0\r\n\r\n')
                    break
                wfile._sock.sendall('%x\r\n' % data_len)
                wfile._sock.sendall(data)
                wfile._sock.sendall('\r\n')
            else:
                if not data_len:
                    break
                wfile._sock.sendall(data)

        xlog.info("DIRECT t:%d s:%d %d %s %s",
                  (time.time() - time_request) * 1000, length, response.status,
                  host, path)
        return "ok"
    except NetWorkIOError as e:
        xlog.warn('DIRECT %s %s%s except:%r', method, host, path, e)
        if e.args[0] not in (errno.ECONNABORTED, errno.ETIMEDOUT, errno.EPIPE):
            raise
    except Exception as e:
        xlog.exception("DIRECT %s %d %s%s, t:%d send to client except:%r",
                       method, response.status, host, path,
                       (time.time() - time_request) * 1000, e)
Ejemplo n.º 5
0
def handler(method, host, url, headers, body, wfile):
    global connect_allow_time
    time_request = time.time()

    errors = []
    response = None
    while True:
        if time.time() - time_request > 30 or time.time() < connect_allow_time:
            return return_fail_message(wfile)

        try:
            response = fetch(method, host, url, headers, body)
            if response:
                break

        except Exception as e:
            errors.append(e)
            logging.exception('direct_handler.handler %r %s %s , retry...', e, host, url)

    try:
        wfile.write("HTTP/1.1 %d %s\r\n" % (response.status, response.reason))
        response_headers = dict((k.title(), v) for k, v in response.getheaders())
        for key, value in response.getheaders():
            send_header(wfile, key, value)
            #logging.debug("Head- %s: %s", key, value)
        wfile.write("\r\n")

        if method == 'HEAD' or response.status in (204, 304):
            logging.info("DIRECT t:%d %d %s %s", (time.time()-time_request)*1000, response.status, host, url)
            https_manager.save_ssl_connection_for_reuse(response.ssl_sock, host)
            response.close()
            return

        if 'Transfer-Encoding' in response_headers:
            length = 0
            while True:
                try:
                    data = response.read(8192)
                except httplib.IncompleteRead, e:
                    data = e.partial

                if not data:
                    wfile.write('0\r\n\r\n')
                    break
                length += len(data)
                wfile.write('%x\r\n' % len(data))
                wfile.write(data)
                wfile.write('\r\n')
            response.close()
            logging.info("DIRECT chucked t:%d s:%d %d %s %s", (time.time()-time_request)*1000, length, response.status, host, url)
            return

        content_length = int(response.getheader('Content-Length', 0))
        content_range = response.getheader('Content-Range', '')
        if content_range:
            start, end, length = tuple(int(x) for x in re.search(r'bytes (\d+)-(\d+)/(\d+)', content_range).group(1, 2, 3))
        else:
            start, end, length = 0, content_length-1, content_length

        time_start = time.time()
        send_to_broswer = True
        while True:
            data = response.read(config.AUTORANGE_BUFSIZE)
            if not data and time.time() - time_start > 120:
                response.close()
                logging.warn("read timeout t:%d len:%d left:%d %s %s", (time.time()-time_request)*1000, length, (end-start), host, url)
                return

            data_len = len(data)
            start += data_len
            if send_to_broswer:
                try:
                    ret = wfile.write(data)
                    if ret == ssl.SSL_ERROR_WANT_WRITE or ret == ssl.SSL_ERROR_WANT_READ:
                        logging.debug("send to browser wfile.write ret:%d", ret)
                        ret = wfile.write(data)
                except Exception as e_b:
                    if e_b[0] in (errno.ECONNABORTED, errno.EPIPE, errno.ECONNRESET) or 'bad write retry' in repr(e_b):
                        logging.warn('direct_handler send to browser return %r %s %r', e_b, host, url)
                    else:
                        logging.warn('direct_handler send to browser return %r %s %r', e_b, host, url)
                    send_to_broswer = False

            if start >= end:
                https_manager.save_ssl_connection_for_reuse(response.ssl_sock, host)
                logging.info("DIRECT t:%d s:%d %d %s %s", (time.time()-time_request)*1000, length, response.status, host, url)
                return
Ejemplo n.º 6
0
def handler(method, host, url, headers, body, wfile):
    time_request = time.time()

    if "Connection" in headers and headers["Connection"] == "close":
        del headers["Connection"]

    errors = []
    response = None
    while True:
        if time.time() - time_request > 30:
            return return_fail_message(wfile)

        try:
            response = fetch(method, host, url, headers, body)
            if response:
                if response.status > 400:
                    server_type = response.getheader('Server', "")
                    if "gws" not in server_type and "Google Frontend" not in server_type:
                        xlog.warn("IP:%s not support GAE, server type:%s status:%d", response.ssl_sock.ip, server_type, response.status)
                        google_ip.report_connect_fail(response.ssl_sock.ip, force_remove=True)
                        response.close()
                        continue
                break
        except OpenSSL.SSL.SysCallError as e:
            errors.append(e)
            xlog.warn("direct_handler.handler err:%r %s/%s", e, host, url)
        except Exception as e:
            errors.append(e)
            xlog.exception('direct_handler.handler %r %s %s , retry...', e, host, url)

    try:
        send_to_browser = True
        try:
            response_headers = dict((k.title(), v) for k, v in response.getheaders())
            wfile.write("HTTP/1.1 %d %s\r\n" % (response.status, response.reason))
            for key, value in response.getheaders():
                send_header(wfile, key, value)
            wfile.write("\r\n")
        except Exception as e:
            send_to_browser = False
            wait_time = time.time()-time_request
            xlog.warn("direct_handler.handler send response fail. t:%d e:%r %s%s", wait_time, e, host, url)


        if method == 'HEAD' or response.status in (204, 304):
            xlog.info("DIRECT t:%d %d %s %s", (time.time()-time_request)*1000, response.status, host, url)
            https_manager.save_ssl_connection_for_reuse(response.ssl_sock, host)
            response.close()
            return

        if 'Transfer-Encoding' in response_headers:
            length = 0
            while True:
                try:
                    data = response.read(8192)
                except httplib.IncompleteRead, e:
                    data = e.partial
                except Exception as e:
                    google_ip.report_connect_closed(response.ssl_sock.ip, "receive fail")
                    xlog.warn("direct_handler.handler send Transfer-Encoding t:%d e:%r %s/%s", time.time()-time_request, e, host, url)
                    response.close()
                    return

                if send_to_browser:
                    try:
                        if not data:
                            wfile.write('0\r\n\r\n')
                            break
                        length += len(data)
                        wfile.write('%x\r\n' % len(data))
                        wfile.write(data)
                        wfile.write('\r\n')
                    except Exception as e:
                        send_to_browser = False
                        xlog.warn("direct_handler.handler send Transfer-Encoding t:%d e:%r %s/%s", time.time()-time_request, e, host, url)
                else:
                    if not data:
                        break
Ejemplo n.º 7
0
def handler(method, host, path, headers, body, wfile, timeout=60):
    time_request = time.time()

    if "Connection" in headers and headers["Connection"] == "close":
        del headers["Connection"]

    errors = []
    while True:
        time_left = time_request + timeout - time.time()
        if time_left <= 0:
            return_fail_message(wfile)
            return "ok"

        try:
            response = direct_front.request(method, host, path, headers, body, timeout=time_left)
            if response:
                if response.status > 600:
                    xlog.warn("direct %s %s % status:%d", method, host, path, response.status)
                    continue
                elif response.status > 400:
                    server_type = response.headers.get('Server', "")

                    if "G" not in server_type and "g" not in server_type and server_type not in google_server_types:

                        xlog.warn("IP:%s host:%s not support GAE, server type:%s status:%d",
                                  response.ssl_sock.ip, host, server_type, response.status)
                        direct_front.ip_manager.report_connect_fail(response.ssl_sock.ip, force_remove=True)
                        response.worker.close()
                        continue
                break
        except OpenSSL.SSL.SysCallError as e:
            errors.append(e)
            xlog.warn("direct_handler.handler err:%r %s/%s", e, host, path)
        except Exception as e:
            errors.append(e)
            xlog.exception('direct_handler.handler %r %s %s , retry...', e, host, path)

    response_headers = {}
    for key, value in response.headers.items():
        key = key.title()
        response_headers[key] = value

    response_headers["Persist"] = ""
    response_headers["Connection"] = "Persist"

    try:
        wfile.write("HTTP/1.1 %d %s\r\n" % (response.status, response.reason))
        for key, value in response_headers.items():
            send_header(wfile, key, value)
        wfile.write("\r\n")

        length = 0
        while True:
            data = response.task.read()
            data_len = len(data)
            length += data_len
            if 'Transfer-Encoding' in response_headers:
                if not data_len:
                    wfile.write('0\r\n\r\n')
                    break
                wfile.write('%x\r\n' % data_len)
                wfile.write(data)
                wfile.write('\r\n')
            else:
                if not data_len:
                    break
                wfile.write(data)

        xlog.info("DIRECT t:%d s:%d %d %s %s",
                  (time.time()-time_request)*1000, length, response.status, host, path)
        if 'Content-Length' in response_headers or 'Transfer-Encoding' in response_headers:
            return "ok"
    except NetWorkIOError as e:
        xlog.warn('DIRECT %s %s%s except:%r', method, host, path, e)
        if e.args[0] not in (errno.ECONNABORTED, errno.ETIMEDOUT, errno.EPIPE):
            raise
    except Exception as e:
        xlog.exception("DIRECT %s %d %s%s, t:%d send to client except:%r",
                 method, response.status, host, path, (time.time()-time_request)*1000, e)
Ejemplo n.º 8
0
def handler(method, host, path, headers, body, wfile, timeout=30):
    time_request = time.time()

    if "Connection" in headers and headers["Connection"] == "close":
        del headers["Connection"]

    errors = []
    while True:
        time_left = time_request + timeout - time.time()
        if time_left <= 0:
            return return_fail_message(wfile)

        try:
            response = direct_front.request(method, host, path, headers, body, timeout=time_left)
            if response:
                if response.status > 400:
                    server_type = response.headers.get('Server', "")

                    if "G" not in server_type and "g" not in server_type and server_type not in google_server_types:
                        xlog.warn("IP:%s host:%s not support GAE, server type:%s status:%d",
                                  response.ssl_sock.ip, host, server_type, response.status)
                        direct_front.ip_manager.report_connect_fail(response.ssl_sock.ip, force_remove=True)
                        response.worker.close()
                        response.close()
                        continue
                break
        except OpenSSL.SSL.SysCallError as e:
            errors.append(e)
            xlog.warn("direct_handler.handler err:%r %s/%s", e, host, path)
        except Exception as e:
            errors.append(e)
            xlog.exception('direct_handler.handler %r %s %s , retry...', e, host, path)

    try:
        wfile.write("HTTP/1.1 %d %s\r\n" % (response.status, response.reason))
        for key, value in response.headers.items():
            send_header(wfile, key, value)
        wfile.write("\r\n")
        wfile.flush()

        length = 0
        while True:
            data = response.task.read()
            if isinstance(data, memoryview):
                data = data.tobytes()

            length += len(data)
            if 'Transfer-Encoding' in response.headers:
                if not data:
                    wfile.write('0\r\n\r\n')
                    break
                wfile.write('%x\r\n' % len(data))
                wfile.write(data)
                wfile.write('\r\n')
            else:
                if not data:
                    break
                wfile._sock.sendall(data)

        xlog.info("DIRECT t:%d s:%d %d %s %s",
                  (time.time()-time_request)*1000, length, response.status, host, path)
    except Exception as e:
        xlog.info("DIRECT %d %s %s, t:%d send to client except:%r",
                  response.status, host, path, (time.time()-time_request)*1000, e)