Отсутствующие заголовки размером с кусочки в потоке переводаJavascript

Форум по Javascript
Ответить
Anonymous
 Отсутствующие заголовки размером с кусочки в потоке перевода

Сообщение Anonymous »

Я работал над проектом «Http Server с нуля», и в течение последних нескольких дней я застрял, но безрезультатно. Это моя функция генератора для чтения кодировки, < /p>
async function* readChunks(conn: TCPConn, buf: DynBuf): BufferGenerator {

for(let last = false; !last;) {
console.log("dynbuf: ", buf.data.subarray(buf.readOffset, buf.readOffset + buf.length));

const idx = buf.data.subarray(buf.readOffset, buf.readOffset+ buf.length).indexOf(Buffer.from('\r\n'));
if(idx < 0) {// need more data
if (buf.length > MAX_CHUNK_SIZE) {
throw new HTTPError(413, 'Chunk size too large');
}
const data = await soRead(conn);
bufPush(data, buf);
continue;
}

if (idx+1 > MAX_CHUNK_SIZE) {
throw new HTTPError(413, 'Chunk size too large');
}
//console.log("idx:", idx, buf.data.subarray(buf.readOffset, buf.readOffset+idx));
let remain = parseChunkHeader(buf.data.subarray(buf.readOffset, buf.readOffset+idx)); //parse chunk size
bufPop(buf, idx+2); //remove line

console.log("dynbuf after reading size: ", buf.data.subarray(buf.readOffset, buf.readOffset + buf.length))

if(Number.isNaN(remain)) {
console.log("bad chunk: ",buf.data.subarray(buf.readOffset, buf.readOffset+idx).toString())
throw new HTTPError(400, "Bad chunk");
}
last = (remain === 0);
console.log("chunk size: ", remain);

while(remain) {
if(buf.length === 0) {
await bufExpectMore(conn, buf, 'chunk data');
}

const consume = Math.min(remain, buf.length);
const data = buf.data.subarray(buf.readOffset, buf.readOffset + consume);
console.log(data.toString())
bufPop(buf, consume);
remain-=consume;

yield data;
}

console.log("dynbuf after chunk read: ", buf.data.subarray(buf.readOffset, buf.readOffset + buf.length))
await bufExpectMore(conn, buf, 'chunk data');
while(buf.length < 2) {
await bufExpectMore(conn, buf, 'chunk data');
}

if(buf.data[buf.readOffset] !== 0x0D || buf.data[buf.readOffset + 1] !== 0x0A) {
throw new HTTPError(400, 'Missing CRLF after chunk data');
}

bufPop(buf, 2);
console.log("dynbuf after final remove: ", buf.data.subarray(buf.readOffset, buf.readOffset + buf.length))
}
}

Функция bufexpectmore () только что читает данные из буфера OS (моя логика чтения включает в себя приостановление и возобновление сокета для излучения событий данных). Но на моем сервере отсутствуют части некоторых кусков, из -за которых он бросает httperror. Клиент отправляет повторно каждую секунду. Вот журнал сервера: < /p>
dynbuf:
dynbuf:
dynbuf after reading size:
chunk size: 30
Hello world what are you doing
dynbuf after chunk read:
dynbuf after final remove:
dynbuf:
dynbuf:

< /code>
Первый кусок был получен просто отлично, и в конце, когда данные были прочитаны, следующий CRLF был запущен. Но в следующей итерации, когда данные загружаются в Dynbuf , 31 64 отсутствует в байтовом потоке, а CRLF 0D 0A загружается в BUF.
Сначала я предположил, что Bufpop () может быть казначей, но это не могло быть сделано, что можно было прочитать bufexpectmore () .
Я нашел работу по этой проблеме, введя wariate bufexpectmore (.../*пропущено*/) сразу после того, как данные чанка считываются полностью.
Так, очевидно, когда сокет читается сразу после того, как я читаю, что я проду Для цикла он каким -то образом отбрасывает заголовок размера куски, ожидайте, что следующий CRLF.
Пожалуйста, помогите мне понять основную причину такого поведения.
p.s. Вот Dynbuf Тип определения:
type DynBuf = {
data: Buffer;
length: number;
readOffset: number;
}

и Dynbuf Логика операций:
export function bufSize(buf:DynBuf): number {
return buf.data.length - buf.readOffset
}

function bufCapacity(buf: DynBuf):number {
return buf.data.length;
}

export function bufPush(data: Buffer, buf: DynBuf):void {
const newLen = buf.length + data.length;

if(newLen > bufSize(buf)) {
//grow the buffer
let cap = Math.max(bufSize(buf), 32);
while(cap < newLen) {
cap *= 2;
}
let grown = Buffer.alloc(cap);
buf.data.copy(grown, 0, buf.readOffset);
buf.data= grown;
}

data.copy(buf.data, buf.length, 0);
buf.length=newLen;
}

export function bufPop(buf:DynBuf, len:number):void {
buf.readOffset += len;
buf.length-=len;
if(buf.readOffset >= bufCapacity(buf)/2) {
buf.data = Buffer.from(buf.data.subarray(buf.readOffset));
buf.readOffset = 0;
}
}



Подробнее здесь: https://stackoverflow.com/questions/796 ... ing-stream
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»