5

次の問題に直面しました:URLConnectionをプロキシ経由で使用すると、コンテンツの長さが常に に設定され-1ます。

最初に、プロキシが実際に を返すことを確認しましたContent-Length(lynxまた、wgetプロキシ経由でも動作しています。ローカル ネットワークからインターネットにアクセスする方法は他にありません)。

$ lynx -source -head ftp://ftp.wipo.int/pub/published_pct_sequences/publication/2003/1218/WO03_104476/WO2003-104476-001.zip
HTTP/1.1 200 OK
Last-Modified: Mon, 09 Jul 2007 17:02:37 GMT
Content-Type: application/x-zip-compressed
Content-Length: 30745
Connection: close
Date: Thu, 02 Feb 2012 17:18:52 GMT

$ wget -S -X HEAD ftp://ftp.wipo.int/pub/published_pct_sequences/publication/2003/1218/WO03_104476/WO2003-104476-001.zip
--2012-04-03 19:36:54--  ftp://ftp.wipo.int/pub/published_pct_sequences/publication/2003/1218/WO03_104476/WO2003-104476-001.zip
Resolving proxy... 10.10.0.12
Connecting to proxy|10.10.0.12|:8080... connected.
Proxy request sent, awaiting response...
  HTTP/1.1 200 OK
  Last-Modified: Mon, 09 Jul 2007 17:02:37 GMT
  Content-Type: application/x-zip-compressed
  Content-Length: 30745
  Connection: close
  Age: 0
  Date: Tue, 03 Apr 2012 17:36:54 GMT
Length: 30745 (30K) [application/x-zip-compressed]
Saving to: `WO2003-104476-001.zip'

Javaで私は書いた:

URL url = new URL("ftp://ftp.wipo.int/pub/published_pct_sequences/publication/2003/1218/WO03_104476/WO2003-104476-001.zip");
int length = url.openConnection().getContentLength();
logger.debug("Got length: " + length);

そして私は得る-1。デバッグを開始しFtpURLConnectionたところ、必要な情報が基礎となるフィールドにあることが判明しましたがHttpURLConnection.responses、そこから適切に入力されることはありません:

ここに画像の説明を入力Content-Length: 30745ヘッダーにあります)。ストリームの読み取りを開始したとき、またはストリームが読み取られた後でも、コンテンツの長さは更新されません。コード:

URL url = new URL("ftp://ftp.wipo.int/pub/published_pct_sequences/publication/2003/1218/WO03_104476/WO2003-104476-001.zip");
URLConnection connection = url.openConnection();

logger.debug("Got length (1): " + connection.getContentLength());

InputStream input = connection.getInputStream();

byte[] buffer = new byte[4096];
int count = 0, len;
while ((len = input.read(buffer)) > 0) {
    count += len;
}

logger.debug("Got length (2): " + connection.getContentLength() + " but wanted " + count);

出力:

Got length (1): -1
Got length (2): -1 but wanted 30745

JDK6 のバグのようですので、新しいバグ #7168608を開きました。

  • 直接 FTP 接続、プロキシ経由の FTP 接続、およびローカルfile:/URL の正しいコンテンツ長を返すコードを書くのを手伝ってくれる人がいれば、私は感謝します。
  • 特定の問題が JDK6 で回避できない場合は、私が言及したすべてのケースで確実に機能する他のライブラリを提案してください ( Apache Http Client ?)。
4

3 に答える 3

1

プロキシされた ftp 接続の処理に関連する jdk の「バグ」だと思います。プロキシが使用されている場合、FtpURLConnection は HttpURLConnection に委譲します。 ただし、この状況では、FtpURLConnection はヘッダー管理をこの HttpURLConnection に委任していないようです。したがって、ストリームを正しく取得できますが、コンテンツの長さやコンテンツの種類などの「ヘッダー」値にはアクセスできないと思います。(これは、1.6 の openjdk ソースをざっと見ただけに基づいています。何か見落としている可能性があります)。

于 2012-04-03T18:17:23.967 に答える
0

私が確認することの1つは、実際に応答を読むことです(頭のてっぺんを書き留めるので、間違いを期待してください):

URLConnection connection= url.openConnection();
InputStream input= connection.getInputStream();
byte[] buffer= new byte[4096];
while(input.read(buffer) > 0)
  ;
logger.debug("Got length: " + getContentLength());

取得しているサイズが適切な場合は、URLConnection にヘッダーを読み取らせ、データを読み取らせないようにして、応答全体を読み取らないようにする方法を探します。

于 2012-03-27T23:23:30.717 に答える