Skip to content

Commit d17764f

Browse files
committed
Added Headers in Request object
1 parent d2062c3 commit d17764f

File tree

4 files changed

+74
-38
lines changed

4 files changed

+74
-38
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
# Changelog
22

33
All notable changes to this project will be documented in this file.
4+
## [0.9.3] - 2025-03-04
5+
### Fixed
6+
- Fixed the issue of res.end()
7+
8+
## [0.9.3] - 2025-03-04
9+
### Fixed
10+
- Added Headers in response objects
11+
412
## [0.9.0] - 2024-12-31
513
### Fixed
614
- minor bug fixes

lib/httpParser.js

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,72 @@ const { findFirstBrac, HTTPbody, JSONbodyParser, queryParser } = require('./util
22

33
// Async function to parse the HTTP request
44
async function httpParser (request) {
5-
const req = {} // Create a new object to store the parsed request
6-
const requestString = request.toString() // Convert buffer to string, if necessary
7-
8-
// Step 1: Split the request into headers and body by finding "\r\n\r\n"
9-
const headerBodySplit = requestString.split('\r\n\r\n') // Headers and body are separated by double newline
10-
const headersPart = headerBodySplit[0] // First part is the headers
11-
const bodyPart = headerBodySplit[1] // Second part is the body
12-
13-
// Step 2: Extract the headers (the first line is the request line, e.g., "POST /path HTTP/1.1")
14-
const headers = headersPart.split('\n')
15-
16-
// Parse the request line (first line of the headers)
17-
const requestLine = headers[0].split(' ') // ["POST", "/path", "HTTP/1.1"]
18-
req.method = requestLine[0] // e.g., "POST"
19-
req.path = requestLine[1] // e.g., "/path"
20-
req.version = requestLine[2] // e.g., "HTTP/1.1"
21-
22-
// Step 3: Handle GET requests (expect a query string)
23-
req.query = queryParser(req.path) // Parse query string for GET requests
24-
req.path = req.path.split('?')[0] // Remove query string from path
25-
26-
// Step 4: Handle POST requests (expect a body)
27-
if (req.method === 'POST') {
28-
// Now we need to parse the body, which is in `bodyPart`
29-
const position = 0 // Start at position 0 of the bodyPart
30-
31-
// Await the body parsing (this is an async operation)
32-
const bodyData = await HTTPbody(bodyPart, position)
33-
34-
// Step 5: Parse the body into JSON format
35-
try {
36-
req.body = JSONbodyParser(bodyData) // Convert the parsed body into JSON
37-
} catch (error) {
38-
console.error('Error parsing JSON body:', error)
5+
try {
6+
const req = {} // Create a new object to store the parsed request
7+
const requestString = request.toString() // Convert buffer to string, if necessary
8+
9+
// Step 1: Split the request into headers and body by finding "\r\n\r\n"
10+
const headerBodySplit = requestString.split('\r\n\r\n') // Headers and body are separated by double newline
11+
if (headerBodySplit.length < 1) {
12+
throw new Error('Invalid HTTP request format')
13+
}
14+
15+
const headersPart = headerBodySplit[0] // First part is the headers
16+
const bodyPart = headerBodySplit[1] || '' // Second part is the body, default to empty string if no body
17+
18+
// Step 2: Extract the headers (the first line is the request line, e.g., "POST /path HTTP/1.1")
19+
const headers = headersPart.split(/\r?\n/).filter(line => line.trim()) // Handle both \r\n and \n
20+
21+
// Parse the request line (first line of the headers)
22+
const requestLine = headers[0].split(' ') // ["POST", "/path", "HTTP/1.1"]
23+
if (requestLine.length !== 3) {
24+
throw new Error('Invalid request line format')
25+
}
26+
27+
req.method = requestLine[0].toUpperCase() // e.g., "POST"
28+
req.path = requestLine[1] // e.g., "/path"
29+
req.version = requestLine[2] // e.g., "HTTP/1.1"
30+
31+
// Add headers parsing
32+
req.headers = {}
33+
for (let i = 1; i < headers.length; i++) {
34+
const line = headers[i].trim()
35+
if (line) {
36+
const colonIndex = line.indexOf(':')
37+
if (colonIndex === -1) continue // Skip malformed headers
38+
39+
const key = line.slice(0, colonIndex).trim().toLowerCase()
40+
const value = line.slice(colonIndex + 1).trim()
41+
req.headers[key] = value
42+
}
43+
}
44+
45+
// Step 3: Handle GET requests (expect a query string)
46+
req.query = queryParser(req.path) // Parse query string for GET requests
47+
req.path = req.path.split('?')[0] // Remove query string from path
48+
49+
// Step 4: Handle POST requests (expect a body)
50+
if (req.method === 'POST') {
51+
if (!bodyPart) {
52+
req.body = {}
53+
} else {
54+
try {
55+
// Await the body parsing (this is an async operation)
56+
const bodyData = await HTTPbody(bodyPart, 0)
57+
// Step 5: Parse the body into JSON format
58+
req.body = JSONbodyParser(bodyData) // Convert the parsed body into JSON
59+
} catch (error) {
60+
console.error('Error parsing request body:', error)
61+
req.body = {} // Set empty object as fallback
62+
}
63+
}
3964
}
4065

4166
return req // Return the fully parsed request object
67+
} catch (error) {
68+
console.error('Error parsing HTTP request:', error)
69+
throw error // Re-throw to let caller handle the error
4270
}
43-
44-
// Step 6: If it's another HTTP method, just return the parsed headers
45-
return req
4671
}
4772

4873
module.exports = { httpParser }

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hasty-server",
3-
"version": "0.9.0",
3+
"version": "0.9.3",
44
"main": "./server/index.js",
55
"directories": {
66
"lib": "lib",

server/response.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,9 @@ class Response {
243243
})
244244
})
245245
return null
246+
}
247+
end () {
248+
this.socket.end()
246249
}
247250
}
248251

0 commit comments

Comments
 (0)