@@ -2,47 +2,72 @@ const { findFirstBrac, HTTPbody, JSONbodyParser, queryParser } = require('./util
22
33// Async function to parse the HTTP request
44async 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
4873module . exports = { httpParser }
0 commit comments