Я работал над проектом «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
Отсутствующие заголовки размером с кусочки в потоке перевода ⇐ Javascript
Форум по Javascript
-
Anonymous
1749388966
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;
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79657870/missing-chunk-size-headers-in-chunked-transfer-encoding-stream[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия