청크된 프록시 뒤에 있는 패키지에 문제가 있습니다.

청크된 프록시 뒤에 있는 패키지에 문제가 있습니다.

가상 머신에 FreeBSD 10.1을 새로 설치했습니다. 기업 프록시 뒤에 있기 때문에 HTTP_PROXY환경을 설정해야 했고 정상적으로 실행되기 시작했습니다.

pkg하지만 제대로 일할 방법이 없습니다 . 포트에서 설치했는데 여전히 같은 문제가 있습니다.

root@FriBi:~ # pkg update -f
Updating FreeBSD repository catalogue...
pkg: repository meta /var/db/pkg/FreeBSD.meta has wrong version or wrong format
Fetching meta.txz:   0%
pkg: No signature found
pkg: repository FreeBSD has no meta file, using default settings
Fetching packagesite.txz:   0%
pkg: No signature found
pkg: Unable to update repository FreeBSD
root@FriBi:~ #

마침내 프록시를 우회할 수 있었고...즉시 잘 작동했습니다...그래서 HTTP 대화 상자를 분석해 보았습니다. 회사 에이전트는 항상 Transfer-Encoding: chunked이유가 있다고 생각되는 응답을 보냅니다. 최소한의 Python 에이전트를 사용하여 이를 확인할 수도 있습니다.

  • readall()전체 파일을 버퍼링하여 회사 프록시로부터 응답 받기
  • 헤더와 함께 ContentLength클라이언트 에 다시 보냅니다(여기 pkg).

그러다가 다시 성공했어요(할 수 있어요 pkg install xorg...)

내 질문:

  • 청크된 프록시에 정말 적대적인가요? pkg아니면 로컬 구성 문제일 수 있나요?
  • 그렇다면 어딘가에 문서화해야합니까? (관련 정보를 찾을 수 없습니다)
  • 간단하고 유용한 기술이 있나요?공식적인프록시) 청크된 HTTP 응답을 청크되지 않은 응답으로 변환하려면 어떻게 해야 합니까?

편집하다

제안된 패치는 버전 1.5에 통합되었으며 이제 해당 버전의 pkgng에서 문제가 해결되었습니다.

답변1

이 문제에 대한 최신 업데이트:

  • FreeBSD에 버그 보고서로 제출버그 198772
  • 메일링 리스트에 제출freebsd 패키지pkg 1.4가 청크된 응답을 처리할 수 없음을 확인했습니다.
  • 패치는 곧 출시될 1.5 pkg 버전에 통합될 수 있는 것이 좋습니다.
  • (2015년 4월 25일 기준) 패치가 버전 1.5에 통합되었으며 해당 버전이 현재 FreeBSD 10.1에서 사용되는 것을 확인할 수 있습니다. 문제가 해결되었습니다.

이것은 실제로 대답은 아니지만 동일한 문제에 직면한 모든 사람에게 도움이 될 수 있습니다. 다음은 청크 모드에서 수신된 전체 파일을 대조하고 Content-Length 헤더를 사용하여 반환하는 최소 프록시에 대한 Python 코드입니다.

# -*- coding: latin1 -*-

import urllib.request
import http.server
import logging

class Handler(http.server.BaseHTTPRequestHandler):
    HEADERS = [ 'If-Modified-Since', 'Host', 'User-Agent', 'Accept',
                'Connection' ]
    def do_GET(self):
        logging.debug("Got a request %s", self.path)
        if self.server.debug >= 3:
            logging.debug("Original headers %s", self.headers.as_string())
        req = urllib.request.Request(self.path)
        for (key, value) in self.headers.items():
            if key in __class__.HEADERS:
                req.add_header(key, value)
        if self.server.debug >= 4:
            logging.debug("Send headers %s", str(req.headers))                
        r = self.server.opener.open(req)
        code = r.getcode()
        logging.debug('Code %d', code)
        if self.server.debug >= 3:
            logging.debug("Received headers %s", str(r.headers))
        if code == 200 and self.server.chunk:
            self.send_response(code)
            self.send_header('Transfer-Encoding', 'chunked')
            self.end_headers()
            while True:
                t = r.read(4095)
                logging.debug('Chunk : %d', len(t))
                self.wfile.write(("%03x\r\n" % (len(t),)).encode())
                if len(t) == 0:
                    self.wfile.write(b"\r\n")
                    break
                else:
                    self.wfile.write(t)
                    self.wfile.write(b"\r\n")
        else:
            t = r.readall()
            #print(t)
            self.send_response(code)
            logging.debug('Content-Length %d', len(t))
            self.send_header('Content-Length', len(t))
            self.end_headers()
            self.wfile.write(t)

class MiniProxy(http.server.HTTPServer):
    def __init__(self, port=8080, relay=None, chunk=False, debug=0):
        http.server.HTTPServer.__init__(self, ('', port), Handler)
        self.port = port
        self.relay = relay
        self.chunk = chunk
        self.debug= debug
        if relay is not None:
            logging.info("relay set to", relay)
            self.proxyHandler = urllib.request.ProxyHandler(
                {'http': relay})
            self.opener = urllib.request.build_opener(self.proxyHandler)
        else:
            self.opener = urllib.request.build_opener()

if __name__ == '__main__':
    import sys
    import argparse
    parser = argparse.ArgumentParser(description =
                      "Simple HTTP proxy to chunk or unchunk responses")
    parser.add_argument('-c', '--chunk', dest = 'chunk', action='store_true')
    parser.add_argument('-C', '--no-chunk', dest = 'chunk', action='store_false')
    parser.add_argument('-r', '--relay')
    parser.add_argument('-p', '--port', type=int,  default = 8080)
    parser.add_argument('-d', '--debug', type=int, default = 0)
    params = parser.parse_args()
    proxy = MiniProxy(port = params.port, relay = params.relay,
                      chunk = params.chunk, debug = params.debug)

    logging_format = '%(levelname)s:%(message)s'
    if params.debug == 1:
        logging.basicConfig(format=logging_format, level=logging.INFO)
    elif params.debug >= 2:
        logging.basicConfig(format=logging_format, level=logging.DEBUG)
    else:
        logging.basicConfig(format=logging_format)        
    try:
        print (sys.argv[0], "listen on", proxy.port)
        proxy.serve_forever()
    except KeyboardInterrupt:
        print('Stop')
        #proxy.shutdown()

관련 정보