Example #1
0
 def forward_local(self):
     html = gae_handler.generate_message_html(
         'Browser pass local request to proxy',
         u'您的浏览器把本地请求转发到代理上。<br>请在浏览器中设置:访问本地,不经过代理。<br><a href="https://github.com/XX-net/XX-Net/wiki/Browser-pass-localhost-request-to-proxy">帮助</a>'
     )
     gae_handler.send_response(self.wfile, 200, body=html.encode('utf-8'))
Example #2
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:
            html = generate_message_html('504 GoAgent Proxy Time out', u'翻不上去,先休息2分钟再来!')
            send_response(wfile, 504, body=html.encode('utf-8'))
            return

        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)
            direct_connect_manager.save_ssl_connection_for_reuse(response.ssl_sock, host)
            response.close()
            return

        if 'Transfer-Encoding' in response_headers:
            length = 0
            while True:
                data = response.read(8192)
                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:
                direct_connect_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

    except NetWorkIOError as e:
        if e[0] in (errno.ECONNABORTED, errno.EPIPE) or 'bad write retry' in repr(e):
            logging.warn("direct_handler err:%r %s %s", e, host, url)
        else:
            logging.exception("direct_handler except:%r %s %s", e, host, url)
    except Exception as e:
        logging.exception("direct_handler except:%r %s %s", e, host, url)
Example #3
0
 def forward_local(self):
     html = gae_handler.generate_message_html('Browser pass local request to proxy', u'您的浏览器把本地请求转发到代理上。<br>请在浏览器中设置:访问本地,不经过代理。<br><a href="https://github.com/XX-net/XX-Net/wiki/Browser-pass-localhost-request-to-proxy">帮助</a>')
     gae_handler.send_response(self.wfile, 200, body=html.encode('utf-8'))
Example #4
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:
            html = generate_message_html('504 GoAgent Proxy Time out',
                                         u'翻不上去,先休息2分钟再来!')
            send_response(wfile, 504, body=html.encode('utf-8'))
            return

        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)
            direct_connect_manager.save_ssl_connection_for_reuse(
                response.ssl_sock, host)
            response.close()
            return

        if 'Transfer-Encoding' in response_headers:
            length = 0
            while True:
                data = response.read(8192)
                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:
                direct_connect_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

    except NetWorkIOError as e:
        if e[0] in (errno.ECONNABORTED,
                    errno.EPIPE) or 'bad write retry' in repr(e):
            logging.warn("direct_handler err:%r %s %s", e, host, url)
        else:
            logging.exception("direct_handler except:%r %s %s", e, host, url)
    except Exception as e:
        logging.exception("direct_handler except:%r %s %s", e, host, url)