kaven-utils
Version:
Utils for Node.js.
97 lines (96 loc) • 3.58 kB
JavaScript
/********************************************************************
* @author: Kaven
* @email: kaven@wuwenkai.com
* @website: http://blog.kaven.xyz
* @file: [kaven-utils] /src/net/http/HttpRequestParser.ts
* @create: 2022-04-14 18:04:28.409
* @modify: 2022-05-01 14:12:19.792
* @version: 4.0.1
* @times: 21
* @lines: 111
* @copyright: Copyright © 2022 Kaven. All Rights Reserved.
* @description: [description]
* @license: [license]
********************************************************************/
import { Strings_CR_LF, Strings_Empty } from "kaven-basic";
import { HttpRequestBody } from "./HttpRequestBody.js";
import { HttpRequestHeader } from "./HttpRequestHeader.js";
import { HttpRequestMessage } from "./HttpRequestMessage.js";
export class HttpRequestParser {
index = 0;
buffer;
message;
ResetMessage() {
const message = this.message;
this.message = undefined;
return message;
}
Add(data) {
if (this.buffer === undefined) {
this.buffer = data;
}
else {
this.buffer = Buffer.concat([this.buffer, data]);
}
}
TryGet() {
if (this.buffer === undefined) {
return undefined;
}
if (this.message === undefined) {
this.index++;
this.message = new HttpRequestMessage(this.index);
}
let offset = 0;
try {
if (!this.message.ShouldParseBody) {
let index = this.buffer.indexOf(Strings_CR_LF);
while (index !== -1) {
const line = this.buffer.slice(offset, index).toString().TrimEnd(Strings_CR_LF);
offset = index + 2;
if (!this.message.IsStartLineParsed) {
this.message.StartLine.Parse(line);
this.message.IsStartLineParsed = true;
if (!this.message.IsHttpRequest) {
return this.ResetMessage();
}
}
else if (!this.message.IsHeadersParsed) {
if (line !== Strings_Empty) {
const header = new HttpRequestHeader("", "");
header.Parse(line);
this.message.Headers.push(header);
}
else {
this.message.IsHeadersParsed = true;
if (this.message.ShouldParseBody) {
break;
}
else {
return this.ResetMessage();
}
}
}
else {
break;
}
index = this.buffer.indexOf(Strings_CR_LF, offset);
}
}
if (this.message.ShouldParseBody) {
const end = offset + this.message.BodySize;
if (end > this.buffer.byteLength) {
return undefined;
}
const body = this.buffer.slice(offset, end);
offset = end;
this.message.Body = new HttpRequestBody(body);
return this.ResetMessage();
}
}
finally {
this.buffer = this.buffer.slice(offset);
}
return undefined;
}
}