HTTP-заголовки для неизвестной Довольной Длины

Я в настоящее время пытаюсь передать содержание потоком к сети после процесса транскодирования. Это обычно хорошо работает путем выписывания двоичного файла к моему веб-потоку, но некоторым браузерам (конкретно IE7, IE8) не нравится не определять Довольную Длину в HTTP-заголовке. Я полагаю, что "действительные" заголовки, как предполагается, имеют этот набор.

Что надлежащий путь состоит в том, чтобы передать содержание потоком к сети, когда у Вас есть неизвестная Довольная Длина? Процесс транскодирования может взять некоторое время, таким образом, я хочу начать передавать его потоком, как он завершается.

23
задан BalusC 8 March 2010 в 00:38
поделиться

2 ответа

Попробуйте отправить их по частям вместе с Transfer-Encoding: chunked . Подробнее в википедии .

Обновите в соответствии с комментариями, вот пример того, как "ChunkedOutputStream" в Java может выглядеть так:

package com.stackoverflow.q2395192;

import java.io.IOException;
import java.io.OutputStream;

public class ChunkedOutputStream extends OutputStream {

    private static final byte[] CRLF = "\r\n".getBytes();
    private OutputStream output = null;

    public ChunkedOutputStream(OutputStream output) {
        this.output = output;
    }

    @Override
    public void write(int i) throws IOException {
        write(new byte[] { (byte) i }, 0, 1);
    }

    @Override
    public void write(byte[] b, int offset, int length) throws IOException {
        writeHeader(length);
        output.write(CRLF, 0, CRLF.length);
        output.write(b, offset, length);
        output.write(CRLF, 0, CRLF.length);
    }

    @Override
    public void flush() throws IOException {
        output.flush();
    }

    @Override
    public void close() throws IOException {
        writeHeader(0);
        output.write(CRLF, 0, CRLF.length);
        output.write(CRLF, 0, CRLF.length);
        output.close();
    }

    private void writeHeader(int length) throws IOException {
        byte[] header = Integer.toHexString(length).getBytes();
        output.write(header, 0, header.length);
    }

}

... который можно в основном использовать как:

OutputStream output = new ChunkedOutputStream(response.getOutputStream());
output.write(....);

Вы видите в исходном коде каждый фрагмент of data существуют заголовок, который представляет длину данных в шестнадцатеричном формате, CRLF, фактические данные и CRLF. Конец потока представлен заголовком, обозначающим длину 0 и два CRLF.

Примечание: несмотря на пример, вам действительно не он нужен в веб-приложении на основе JSP / сервлета. Если для ответа не задана длина содержимого, веб-контейнер автоматически передает его фрагментами.

19
ответ дан 29 November 2019 в 02:56
поделиться

В продолжение отличного сообщения BalusC, вот код, который я использую в C#. Я выгружаю данные вручную непосредственно в выходной поток HTTP, после получения данных из STDOUT процесса.

int buffSize = 16384;
byte[] buffer = new byte[buffSize];
byte[] hexBuff;
byte[] CRLF = Encoding.UTF8.GetBytes("\r\n");

br = new BinaryReader(transcoder.StandardOutput.BaseStream);

//Begin chunking...
int ret = 0;
while (!transcoder.HasExited && (ret = br.Read(buffer, 0, buffSize)) > 0)
{
    //Write hex length...
    hexBuff = Encoding.UTF8.GetBytes(ret.ToString("X"));
    e.Context.Stream.Write(hexBuff, 0, hexBuff.Length);

    //Write CRLF...
    e.Context.Stream.Write(CRLF, 0, CRLF.Length);

    //Write byte content...
    e.Context.Stream.Write(buffer, 0, ret);

    //Write CRLF...
    e.Context.Stream.Write(CRLF, 0, CRLF.Length);
}
//End chunking...
//Write hex length...
hexBuff = Encoding.UTF8.GetBytes(0.ToString("X"));
e.Context.Stream.Write(hexBuff, 0, hexBuff.Length);
2
ответ дан 29 November 2019 в 02:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: