Node JS get key value pairs from header - javascript

If the request contains a header such as:
Authorization: Digest username="Mufasa",
realm="testrealm#host.com",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"
Does node have any built-in way to extract the key value pairs? Or should I just use string.split?

Use the URL module http://nodejs.org/api/url.html
Example: http://www.host.com:8080/path?name=daniel
Takes a URL string, and return an object.
url.parse(urlStr, [parseQueryString], [slashesDenoteHost])
var server = http.createServer(function (request, response) {
var queryData = url.parse(request.url, true).query;
response.writeHead(200, {"Content-Type": "text/plain"});
response.end('Hello ' + queryData.name + '\n');
}
In this example name is mapped to daniel.

Related

My First Node.js server : Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING

The following server is supposed to :
CASE #1 : serve mysitename.html if the request is http://localhost:8080
CASE #2 : serve the relevant file if the request is e.g. http://localhost:8080/mysitename.html
CASE #3 send me an email if the request is http://localhost:8080/contactform?name=..&..&...etc.
If I visit http://localhost:8080/mysitename.htmleverything works fine. mysitename.html is loaded and then all subsequent content (.js, .css, .png etc.) is loaded through it.
PROBLEM : However, if I visit http://localhost:8080, the following happens :
I get a Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING error on the browser's (Chrome) console.
`mysitename.html' appears corrupted on the client. Parts of the DOM are missing and when I try to view the source page, it just hangs and never actually loads. Loading only part of the DOM is weird given that all DOM elements of this file are static/hardcoded.
What's confusing is that the rest of the content (.js, .css etc..) is loaded but nothing actually shows because of the corrupted .html. Is it possible that CASE#1 is interrupted by CASE#2 that follows right after it? What exactly am I doing wrong ?
CASE#2 initially had an error which was causing an infinite loop found by Johnny Estilles (see his answer below). This has since been fixed but the issues mentioned above now occur.
server.js
// setting up email handler
var nodemailer = require('nodemailer');
var emailHandlerService = 'Gmail';
var emailHandlerAddress = ******;
var emailHandlerPassword = ******;
var transporter = nodemailer.createTransport({
service: emailHandlerService,
auth: {
user: emailHandlerAddress,
pass: emailHandlerPassword
}
});
// setting up http server
var http = require('http');
var fs = require('fs');
var url = require("url");
var path = require("path");
var rootDir = __dirname + "/public";
var mimeTypes = {
"html": "text/html",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"png": "image/png",
/* Even though the js mime type is set as well, scripts are still sent
as "text/plain" according to the Chrome console. Why is that ? */
"js": "application/javascript",
"css": "text/css",
"ico": "image/ico"
};
// initializing server
var httpServer = http.createServer(function (request, response)
{
// CASE #1
// if the user is on http://localhost:8080, load public/mysitename.html
if (request.url === "/")
{
fs.readFile('public/mysitename.html', function (err, html)
{
if (err)
{
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('404 Not Found\n');
throw (err);
}
else
{
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
}
});
}
// CASE #2
// else if this is a contact form data request
// forward the data to my email (I'll make a more precise Regex for the request)
else if (/contactform/.test(request.url))
{
var parsedURL = url.parse(request.url, true);
var name = parsedURL.query.name;
var email = parsedURL.query.email;
var subject = parsedURL.query.subject;
var enquiry = parsedURL.query.enquiry;
var browser = parsedURL.query.browsername + " " +
parsedURL.query.browserversion;
transporter.sendMail({
from: emailHandlerAddress,
to: emailHandlerAddress,
subject: subject,
text: "|| NAME = " + name + " || EMAIL = " +
email + " || BROWSER = " + browser + " || DEVICE = " +
parsedURL.query.device + " || ENQUIRY = " + enquiry
});
response.end(JSON.stringify(parsedURL.query));
}
// CASE #3
// if none of the above is true then this is a request to serve static files
else
{
var pathname = url.parse(request.url).pathname;
var filename = path.join(rootDir, pathname);
fs.exists(filename, function (exists)
{
if (!exists)
{
fs.readFile('public/404.html', function (err, html)
{
if (err)
{
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('404 Not Found\n');
throw (err);
}
else
{
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
}
response.end();
});
}
else
{
var requestedFileExtension = path.extname(filename).split(".")[1];
var mimeType = mimeTypes[requestedFileExtension] || 'text/plain';
// as I noted above, this doesn't seem to have any effect
// for my .js files
response.writeHead(200, mimeType);
var fileStream = fs.createReadStream(filename);
fileStream.pipe(response);
}
});
}
}).listen(8080);
FIXING ISSUE #1: Infinite loop
You're missing an equal sign (or two) in your initial if().
Change
if (request.url = "/")
to
if (request.url == "/")
or
if (request.url === "/")
FIXING ISSUE #2: Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING
Your're missing a response.end() in CASE #1.
// CASE #1
// if the user is on http://localhost:8080, load public/mysitename.html
if (request.url === "/")
{
fs.readFile('public/mysitename.html', function (err, html)
{
if (err)
{
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('404 Not Found\n');
throw (err);
}
else
{
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
}
response.end(); // <-- MISSING
});
}

request.url is not giving complete url in nodejs

I am running the following code snippet from the node js beginner book.
var http = require("http");
var url = require("url");
function onRequest(request, response) {
console.log("request url issss " + request.url);
var pathName = url.parse(request.url).pathName;
console.log("Request for " + pathName + " received");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello Worldd");
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started11.");
Now while hitting http://localhost:8888/start in the browser, i am getting request.url is start only instead of full url. Hence path name is coming undefined.
Following is the console out put
Server has started11.
request url issss /start/
Request for undefined received
Thanks,
Shantanu
It's pathname with the n lowercased.
Also, request.url does not contain the fully qualified URL, it only contains the requested URL that the client sends.

Node.js url methods return null

I'm trying to get node.js to print http request properties to the browser. However, the properties of the request url either return null or don't print at all. Here is the code for the server (server.js):
var http = require('http');
var url = require('url');
function start() {
function onRequest(request, response) {
var pathname = url.parse(request.url, true).pathname;
var protocol = url.parse(request.url, true).protocol;
var hostname = url.parse(request.url, true).host;
var path = url.parse(request.url, true).path;
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World"); //this is the text that is sent back
response.write("\nThe HTTP response is " + response.statusCode);
response.write("\nRequest for "+ pathname +" has been received. The request url is " + request.url + " and our protocol is " + protocol +".Also, our host is " + hostname);
response.write("\nThe concatenated path is " + path);
response.end(); //this is the end of the response
}
var new_server = http.createServer(onRequest).listen(8888);
} //end of start function
exports.start = start;
And the index file that executes this is index.js
var server = require("./server");
console.log("To see what the sever responds with, go to localhost:8888.");
server.start();
My browser output is, when I type in the url bar localhost:8888
Hello World
The HTTP response is 200
Request for / has been received. The request url is / and our protocol is null.Also, our host is null
The concatenated path is /
I need to get the url properties. Thank you.
The reason these variables are returning undefined is because the url only contains the path. The protocol and the host are stored elsewhere. Take this example from the node.js documentation:
var url = require('url');
console.log( url.parse(
'http://user:pass#host.com:8080/p/a/t/h?query=string#hash', true
));
That will return the following object:
{
href: 'http://user:pass#host.com:8080/p/a/t/h?query=string#hash',
protocol: 'http:',
host: 'user:pass#host.com:8080',
auth: 'user:pass',
hostname: 'host.com',
port: '8080',
pathname: '/p/a/t/h',
search: '?query=string',
query: { query: 'string' },
hash: '#hash',
slashes: true
}
These values are present in the URL, so they are present in the object. The localhost:8888 URL has none of these.
On another note, there are three important aspects to the request object: the url, the method, and the headers. If you try doing this, I suspect you will find the information you're looking for:
var urlStr = 'http://' + req.headers.host + req.url,
parsedURL = url.parse( urlStr ,true );
console.log(parsedURL);
//this should give you the data you are looking for.

Node.js server just keeps loading with no result.

I have been trying to get my server to work but when I send post data it just keeps loading and no results are given. Here is my noen.js file.
var http = require('http');
var url = require('url');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
var queryData = url.parse(request.url, true).query;
response.writeHead(200, {"Content-Type": "text/plain"});
if (queryData.name) {
// user told us their name in the GET request, ex: http://host:8000/?name=Tom
var exec = require('child_process').exec;
function puts(error, stdout, stderr) {sys.puts(stdout)}
exec ("casperjs test.js " + queryData.name + '\n');
} else {
response.end("Contact Admin - Not Working\n");
}
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(1213);
Can anyone help me fix this? When I go to
127.0.0.1:8000/?name=tom
I get no response the page just goes into a long loading loop
There is no response.end in case if is true so then response "never" ends.
write at bottom of the if
response.end("something");
And you will get the response;
For get the output of the process to the response:
https://stackoverflow.com/a/3944751/3018595
var http = require('http');
var url = require('url');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
var queryData = url.parse(request.url, true).query;
response.writeHead(200, {"Content-Type": "text/plain"});
if (queryData.name) {
// user told us their name in the GET request, ex: http://host:8000/?name=Tom
var exec = require('child_process').exec;
exec ("casperjs test.js " + queryData.name + '\n',function(err, stdout, stderr) {
response.end(stdout);
});
} else {
response.end("Contact Admin - Not Working\n");
}
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(1213);
The reason your browser is keep waiting because you are not ending your response. You have to call response.end to let your server complete the response otherwise it will keep thinking that the response is not complete yet. I added a line in your if statement and tested your code and it is working perfectly fine.
added line ** response.end("Request processed successfully...\n");**, assuming that you need to display a different message in case your "else" statement.
I tested url http://:1213/?name=tom
var http = require('http');
var url = require('url');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
var queryData = url.parse(request.url, true).query;
response.writeHead(200, {"Content-Type": "text/plain"});
if (queryData.name) {
// user told us their name in the GET request, ex: http://host:8000/?name=Tom
var exec = require('child_process').exec;
function puts(error, stdout, stderr) {sys.puts(stdout)}
exec ("casperjs test.js " + queryData.name + '\n');
response.end("Request processed successfully...\n");
} else {
response.end("Contact Admin - Not Working\n");
}
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(1213);

Node.js sample code not working

I'm trying to run some simple codes of node.js, this hello world works without a problem:
var http = require('http');
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("Este node.js criou um servidor\n");
});
server.listen(8000);
But when I try to run this one that should be simple enough, the browser (tried IE and chrome) stays loading for a long time and then gives a timeout. What could be the problem?
var http = require("http"),
fs = require("fs");
http.createServer(function (request, response) {
request.on('end', function () {
if (request.url == '/') {
fs.readFile('test.txt', 'utf-8', function (error, data) {
response.writeHead(200, {
'Content-Type': 'text/plain'
});
data = parseInt(data) + 1;
fs.writeFile('test.txt', data);
response.end('This page was refreshed ' + data + ' times!');
});
} else {
response.writeHead(404);
response.end();
}
});
}).listen(8000);
By the way, I've created the test.txt file in the same folder as the code and it have only the number 1 inside it.
The end request never launch, because the request is finished when the server is called. Remove that line and ready like this:
var http = require("http"),
fs = require("fs");
http.createServer(function (request, response) {
// request.on('end', function () {
if (request.url == '/') {
fs.readFile('test.txt', 'utf-8', function (error, data) {
response.writeHead(200, {
'Content-Type': 'text/plain'
});
data = parseInt(data) + 1;
fs.writeFile('test.txt', data);
response.end('This page was refreshed ' + data + ' times!');
});
} else {
response.writeHead(404);
response.end();
}
// });
}).listen(8000);
The request object from a HTTP handler is an instance of readable stream, which will not emit the end event when in non-flowing mode. If an end event is expected, then the stream must be resumed..
If you aren't going to collect the body of the request, then you don't need to listen for the end event at all. You can just write the response:
http.createServer(function(req, res) {
if (request.url == '/') {
fs.readFile('test.txt', 'utf-8', function (error, data) {
res.writeHead(200, {'Content-Type': 'text/plain'});
data = parseInt(data) + 1;
fs.writeFile('test.txt', data);
res.end('This page was refreshed ' + data + ' times!');
});
} else {
res.writeHead(404);
res.end();
}
}).listen();
Otherwise, the stream can converted to flowing mode by either of these:
req.resume();
req.on('data', function(chunk) {});
The way that it seems to be structured is quite different from what I have seen otherwise. You shouldn't need the request.on structure. Generally, you could using something like this:
var http = require("http");
var Start = function(){
var onRequest = function(request, response){
response.writeHead(200, {"Content-Type" : "text/plain" });
response.write("HEllo World");
response.end();
}
http.createServer(onRequest).listen(8888);
}
exports.Start = Start;
The reason for the exports is so that you can start it form another file (which is good if you are going for the suggested modular design. As to loading files - your way of loading may work, but the problem is that it will only server text file - trying to use an html file will fail miserably, and you probably want to be serving html files as well, along with .js and .css files as well (and anything else, for example pictures). Therefore, please refer to my answer, which is the very long one with plenty of code, in the folllowing link: Click Here.

Categories

Resources