仮想マシンに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()