I’ve already ready the other post(s) related to node http requests firing twice. I believe this is different.
I scripted a demo that uses a child process to read from a sqlite db and wired that functionality to an http request.
const { spawn } = require( 'node:child_process' )
const http = require( 'node:http' )
const queryDB = async ( query ) => {
const child = spawn( 'sqlite3', [ 'some-sqlite3.db', query ] )
return new Promise( resolve => {
child.stdout.on( 'data', data => {
resolve( data.toString() )
} )
} )
}
const server = http.createServer()
server.on( 'request', async ( req, res ) => {
const url = new URL( req.url, 'http://' + req.headers.host )
const queryStr = url.searchParams.get( 'q' )
res.writeHead( 200, { 'Content-Type': 'text/plain' } )
console.log( { queryStr }, new Date().toLocaleString() )
res.write( await queryDB( queryStr ) )
res.end( 'n' )
} )
server.listen( 3000, () => console.log( 'server live' ) )
I added a console.log to the http request handler to confirm the search param’s being parsed correctly but found the following when requesting http://localhost:3000/?q=pragma table_list
either through browser or cURL
{ queryStr: 'pragma table_list' } 7/16/2024, 3:58:12 PM
{ queryStr: null } 7/16/2024, 3:58:12 PM
So it appears the request gets fired or handled twice and is not getting a query string the on the second event.
I rewrote queryDB to resolve after all data is received from the child process’ stdout but found it made no difference to the console output.
const queryDB = async ( query ) => {
const child = spawn( 'sqlite3', [ 'bmc.db', query ] )
return new Promise( resolve => {
let response = ''
child.stdout.on( 'data', data => {
response += data.toString()
} )
child.on( 'exit', () => {
resolve( response )
} )
} )
}
The http response I’m getting is exactly what I want but I would like some help understanding why the above is happening and how I can mitigate it.
10