0

我有一些代码我已经使用了一段时间来从 Web 服务器获取数据,几个月前,我添加了压缩支持,这似乎适用于整个文档所在的“常规”HTTP 响应包含在响应中。Range不过,当我使用标题时,它似乎不起作用。

这是执行实际工作的代码:

    InputStream in = null;

    int bufferSize = 4096;

    int responseCode = conn.getResponseCode();

    boolean error = 5 == responseCode / 100
        || 4 == responseCode / 100;

    int bytesRead = 0;

    try
    {
        if(error)
            in = conn.getErrorStream();
        else
            in = conn.getInputStream();

        // Buffer the input
        in = new BufferedInputStream(in);

        // Handle compressed responses
        if("gzip".equalsIgnoreCase(conn.getHeaderField("Content-Encoding")))
            in = new GZIPInputStream(in);
        else if("deflate".equalsIgnoreCase(conn.getHeaderField("Content-Encoding")))
            in = new InflaterInputStream(in, new Inflater(true));

        int n;
        byte[] buffer = new byte[bufferSize];

        // Now, just write out all the bytes
        while(-1 != (n = in.read(buffer)))
        {
            bytesRead += n;
            out.write(buffer, 0, n);
        }
    }
    catch (IOException ioe)
    {
        System.err.println("Got IOException after reading " + bytesRead + " bytes");
        throw ioe;
    }
    finally
    {
        if(null != in) try { in.close(); }
        catch (IOException ioe)
        {
            System.err.println("Could not close InputStream");
            ioe.printStackTrace();
        }
    }

用标头点击 URLAccept-Encoding: gzip,deflate,identity效果很好:我可以看到服务器以压缩格式返回数据,上面的代码很好地解压缩了它。

如果我再添加一个Range: bytes=0-50标题,我会得到以下异常:

Got IOException after reading 0 bytes
Exception in thread "main" java.io.EOFException: Unexpected end of ZLIB input stream
at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:240)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:116)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at [my code]([my code]:511)

511我的代码中的行是包含调用in.read()的行。响应包括以下标头:

Content-Type: text/html
Content-Encoding: gzip
Content-Range: bytes 0-50/751
Content-Length: 51

我已经验证,如果我不尝试解压缩响应,我实际上会在响应中得到 51 个字节......这不是服务器故障(至少我可以说)。我的服务器(Apache httpd)不支持“deflate”,所以我不能测试另一个压缩方案(至少现在不行)。

我还尝试请求更多数据(例如目标资源中总共 751 个字节中的 700 个字节),但我得到了同样的错误。

有什么我想念的吗?

更新 对不起,我忘了包括我在 Linux 上点击 Apache/2.2.22。我不知道有任何服务器错误。我在验证从服务器检索的压缩字节时会遇到一些麻烦,因为“gzip”内容编码非常简单……例如,我相信我不能只在命令行上使用“gunzip”解压缩这些字节。不过,我会试一试。

4

2 回答 2

1

您可以使用“gunzip”对其进行解压缩,但请记住前 50 个字节可能不足以让 gzip 解压缩任何内容(标题、字典等)。试试这个:wget -O- -q <URL> | head -c 50 | zcat使用你的 URL 来查看正常的 gzip 是否在你的代码失败的地方工作。

于 2013-09-13T15:31:01.547 回答
0

叹息切换到另一台服务器(恰好正在运行 Apache/2.2.25)表明我的代码确实有效。原始目标服务器似乎受到 AWS 当前在 US-EAST 可用区中断的影响。我将把它归结为网络错误并关闭这个问题。感谢那些提供建议的人。

于 2013-09-13T16:00:08.377 回答