在套接字内正确处理分块的HTTP响应 [英] Proper handling of chuncked Http Response within Socket

查看:116
本文介绍了在套接字内正确处理分块的HTTP响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在检测Socket中HTTP响应的真实结尾时遇到了一些主要问题(我必须按要求使用套接字).我们正在与发送分块响应的Web服务进行通信.如果返回一个响应,我没有任何问题.但是,当拆分时,所有地狱都会变得松散:). 例如:

I have some major problem detecting the true end of a http response within Socket (I have to use sockets as it was requested). We're communicating with a webservice that sends chuncked responses. I have no problems reading a response if it returns in one piece. However when it's being split all hell breaks loose :). For example:

UserA -> RequestA -> Response[1] -> Processed
UserA -> RequestA -> Response[1] -> Processed
UserB -> RequestB -> a)Response[0,1] -> Processed[a.0]
UserB -> RequestB -> b)Response[0,1] -> Processed[a.1] <- From the previous line. And thus the true response to request B have to be processed again.

处理这种情况的首选方法是什么?顺便说一句,WS还返回Content-Length标头属性,但说实话,我在处理该标头方面有头痛.为此,似乎我必须读取ByteArrayOutputStream的标头字段,并检查它是否包含Content-Length信息.然后检索实际长度,并等待is.available()达到此值.由于可用方法会返回估算值,因此我不信任该估算值.那么正确的方法是什么?

What is the preferred way to handle this kind of situation? Btw, the WS also returns the Content-Length header attribute, but honestly I have a head-ache from handling that. For that it seems like I have to read the headers fields to a ByteArrayOutputStream and check if it contains the Content-Length information. Then retrieve the actual length and wait until the is.available() reaches this value. Since the available method returns an estimation I do not trust it. So what would be the proper way?

推荐答案

正确的答案应该是:

private static byte[] convert(final InputStream is) throws IOException {
    final byte[] END_SIG = new byte[]{"\r".getBytes()[0], "\n".getBytes()[0]};
    final List<Byte> streamBytes = new ArrayList<Byte>();
    int readByte;
    byte[] bytes;

    // Read HTTP header:
    while ((readByte = is.read()) != -1) {
        streamBytes.add((byte) readByte);
        if (streamBytes.size() > 4) {
            int sbsize = streamBytes.size();

            int rp = sbsize - 4;
            int np = sbsize - 2;
            int rn = sbsize - 3;
            int nn = sbsize - 1;

            if (END_SIG[0] == streamBytes.get(rp) && END_SIG[0] == streamBytes.get(np) && END_SIG[1] == streamBytes.get(rn) && END_SIG[1] == streamBytes.get(nn)) {
                break;
            }
        }
    }

    // Convert to byte[]
    bytes = new byte[streamBytes.size()];
    for (int i = 0, iMAX = bytes.length; i < iMAX; ++i) {
        bytes[i] = streamBytes.get(i);
    }

    // drop header
    streamBytes.clear();

    // Convert byte[] to String & retrieve the content-length:
    final String HEADER = new String(bytes);
    int startIndex = HEADER.indexOf("Content-Length:") + "Content-Length:".length() + 1;
    int length = 0;
    int I = startIndex;
    while (Character.isDigit(HEADER.charAt(I++))) {
        ++length;
    }
    final String CL = HEADER.substring(startIndex, startIndex + length);

    // Determine the number of bytes to read from now on:
    int ContentLength = Integer.parseInt(CL);
    while (streamBytes.size() < ContentLength) {
        byte[] buffer = new byte[256];

        int rc = is.read(buffer);
        for (int irc = 0; irc < rc; ++irc) {
            streamBytes.add(buffer[irc]);
        }
    }

    // Convert to byte[]
    bytes = new byte[streamBytes.size()];
    for (int i = 0, iMAX = bytes.length; i < iMAX; ++i) {
        bytes[i] = streamBytes.get(i);
    }

    return bytes;
}

在一个地方,这是一个问题的答案.

And in one place this is the answer to a question.

这篇关于在套接字内正确处理分块的HTTP响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆