I'm used to apache and putting configuration items in httpd.conf
Where do these types of configurations go in a node environment. For example, I want to make sure that only GET, POST, and PUT are accepted and Head and Trace are not accepted. Where does a config like that go?
Additional things like Cache-Control and limiting request and response sizes.
Node.js is just a JS framework with a system API. Technically, you could reimplement Apache HTTP Server in Node.js, mimicking its behaviour and its configuration structure. But would you?
I believe you are using Node.js' HTTP module. Look at the docs: there's no way to read configuration from a file. The server is programmatically created using http.createServer. You provide a callback that listens to requests. This callback provides an http.IncomingMessage parameter (first parameter) which contains everything you need.
Here's an example:
// load the module
var http = require('http');
// create the HTTP server
var server = http.createServer(function(request, response) {
// use the "request" object to know everything about the request
console.log('got request!');
// method ('GET', 'POST', 'PUT, etc.):
console.log('HTTP method: ' + request.method);
// URL:
console.log('HTTP URL: ' + request.url);
// headers:
console.log('HTTP headers follow:');
console.log(request.headers);
// client address:
console.log('client address: ' + request.socket.address().address);
});
// listen on port 8000
server.listen(8000);
If you really want a configuration file, you will have to forge it yourself. I suggest creating a JSON configuration file as this can be turned directly into a JS object using JSON.parse(). Then just use your configuration object programmatically to achieve what you want.
Related
I'm building an API on Cloud Functions with NodeJS and Express (Firebase) and I'd like to accept only calls via HTTPs so calls made over plain HTTP will fail.
Is it possible to do it?
You should examine the request object being passed to your function. It's going to be an Express type Request object. Request has a property called protocol that should be "https". So:
functions.https.onRequest((req, res) => {
if (req.protocol !== "https") {
// reject the request
res.sendStatus(403)
}
})
Generaly you want a application running for each protocol listening to a different port. To solve your problem you could simply ignore the requests for the http instance or redirect every http request to a https request.
Here's a middleware for that:
app.use(function(request, response){
if(!request.secure){
response.redirect("https://" + request.headers.host + request.url);
}
});
See the express documentation.
What is the difference between the request in this line of code:
http.createServer(function(request,response){. . .}
and request in
http.request()
Are both requests done to the server?
I am new to node.js and I am sorry if I sound dumb!
How does http.request() work?
In http.request() we fetch data from another site but in order to fetch data from another site we first need to go to our site and then make a request? Explain it with a simple real-life example!
http.request() makes a request to another HTTP server. Suppose for some reason I wanted to go download Stack Overflow's home page...
http.request('https://stackoverflow.com/', (res) => {
// ...
});
http.createServer()... it creates an HTTP server. That is, it binds your application to a socket to listen on. When a new connection is made from somewhere or something else, it handles the underlying HTTP protocol of that request and asks your application to deal with it by way of a callback. From the Node.js documentation:
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('okay');
});
These two methods have absolutely nothing to do with each other. http.request() is for making a request to an HTTP server. http.createServer() is for creating your own HTTP server. Don't get confused by the callbacks.
Based on the source code of nodejs (extract below), createServer is just a helper method to instantiate a Server.
Extract from line 1674 of http.js.
exports.Server = Server;
exports.createServer = function(requestListener) {
return new Server(requestListener);
};
The http.request() API is for when you want your server code to act as a client and request content from another site and has GET, POST, PUT, DELETE methods.
Im using https://www.npmjs.com/package/hardhttps for my node.js application.
I want to send response headers to the client side
Strict-Transport-Security enforces secure (HTTP over SSL/TLS) connections to the server
X-Frame-Options provides clickjacking protection
X-XSS-Protection enables the Cross-site scripting (XSS) filter built into most recent web browsers
X-Content-Type-Options prevents browsers from MIME-sniffing a response away from the declared content-type
Content-Security-Policy prevents a wide range of attacks, including Cross-site scripting and other cross-site injections
https://blog.risingstack.com/node-js-security-checklist/ states that I could use https://www.npmjs.com/package/helmet but I am not using express and never wan't to.
The https server is for a wss websocket. I'm checking certain things on upgrade to see if I want to accept the connection or not (as part of onion layered security)
var server=(require('hardhttps').createServer({key:pem.key,cert:pem.cert,ca:[pem.ca],passphrase:pem.pass})).listen(port);
server.on("upgrade",function(req,socket,head){// happens before the websockect receives on `connection`
var ip=req.headers['x-forwarded-for']||req.connection.remoteAddress||req.socket.remoteAddress||req.connection.socket.remoteAddress;//got their ip (can compare with previous visitor)
});
var wss=new WebSocketServer({
server:server
, verifyClient:function(info,cb){
//could verify ip here and block the connection from happening...
if(('https://'+host)===(info.req.headers.origin)){cb(true);}
}});
wss.on('connection',function(socket){var ip=socket._socket.remoteAddress//....
I think I ether have to set the headers when I start the server or inside the upgrade, but I can't see any examples of this.
If I search for this I find that people are talking about custom headers a lot but the above headers I specifically want to set are not custom at all, at least to http! A websocket is just a wrapper on http (as I understand).
For a node.js application without using any external framework e.g. express:
const http = require('http');
http.createServer((request, response) => {
request.on('error', (err) => {
console.error(err);
// for this simple example I am not including the data event
// e.g. if the request contains data in the body
}).on('end', () => {
response.on('error', (err) => {
console.error(err);
});
// you can explicitly set your headers with setHeader or
// use writeHead as a "shortcut" to include the statusCode.
// Note writeHead won't cache results internally
// and if used in conjuction with setHeader will take some sort of "precedence"
response.writeHead(200, {
"Strict-Transport-Security": "max-age=31536000"
// other security headers here...
});
response.end("<html><body><h1>Hello, Security Headers!</h1></body></html>");
});
}).listen(8080);
See the node.js documentation for more details on setting headers on the response object
I have made a couchdb design document which works perfectly on the following url
http://localhost:5984/db/_design/app/index.html
Now the problem is i am trying to fetch the page contents and display it from node js but only the html page is displayed the linked css and js files are not working and when i tried to narrow down the problem i found that the css and js files are suppose to have the login credentials of the couchdb and is not linking I even tried adding the auth header in the response parameter but still no luck
var http = require('http');
var json;
var root = new Buffer("admin:pass").toString('base64');
http.createServer(function(req, res) {
res.setHeader('Authorization', root);
res.writeHead(200, { 'Content-Type':'text/html' });
couchPage();
res.end(json);
}).listen(8080);
function couchPage() {
var options = {
hostname: 'localhost',
port: 5984,
path: '/db/_design/app/index.html',
auth: 'admin:pass',
method: 'GET'
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
json = chunk;
});
});
req.end();
}
could any one please guide me where am i wrong
I think this has nothing to do with couchdb authorization. The problem is that you do not perform any routing on your nodejs server. That is, the browser makes a request to localhost:8080 and receives the content of /db/_design/app/index.html as an answer. Now, the browser detects a link to a stylesheet, say "style.css". It performs a request to localhost:8080/style.css but your nodejs server simply ignores the "style.css" part of the request. Instead, the client will receive the content of /db/_design/app/index.html again!
If you want to serve attachments of your design document through nodejs, you have to parse the request first and then retrieve the corresponding document from couchdb. However, I don't think that you actually want to do this. Either you want to use couchdb in a traditional way behind nodejs (not directly accessible from the client) and then you would just use it as a database with your html (or template) files stored on disk. Or you want to directly expose couchdb to the client and make nodejs listen to events via the couchdb _changes feed.
I've been playing with node.js and then came across the express framework. I can't seem to get it to work when different ports are being used.
I have my ajax on http://localhost:8888 which is a MAMP server I'm running on my Mac.
$.ajax({
url: "http://localhost:1337/",
type: "GET",
dataType: "json",
data: { },
contentType: "application/json",
cache: false,
timeout: 5000,
success: function(data) {
alert(data);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('error ' + textStatus + " " + errorThrown);
}
});
As you can see my node.js server is running on http://localhost:1337/. As a result nothing is getting returned and it's throwing an error.
Is there a way around this?
Thanks
Ben
The problem you have is that you are trying to make a cross-origin request and that's not allowed by browsers (yes, the same hostname with a different port counts as a different origin for this purpose). You have three options here:
1. Proxy the request.
Do this one if you can. Write some code that runs on the :8888 server
that proxies requests to the 1337 one. You can also do this by
sticking a proxy in front of both of them, something like Nginx is
pretty good at this and easy to set up
2. Use CORS (Cross Origin Resource Sharing)
See: http://en.wikipedia.org/wiki/Cross-origin_resource_sharing and https://developer.mozilla.org/en/http_access_control
This means adding some headers to your responses to tell the browser that cross-origin requests are ok here. In your Express server add middleware like this:
function enableCORSMiddleware (req,res,next) {
// You could use * instead of the url below to allow any origin,
// but be careful, you're opening yourself up to all sorts of things!
res.setHeader('Access-Control-Allow-Origin', "http://localhost:8888");
next()
}
server.use(enableCORSMiddleware);
3. Use JSONP
This is a trick where you encode your "AJAX" response as Javascript code. Then you ask the browser to load that code, the browser will happily load scripts cross-origin so this gets round the cross-origin issue. It also lets anyone else get round it as well though, so be sure that's what you want!
On the server side you need wrap your response in a Javascript function call, express can do this for automatically if you enable the "jsonp callback" option like this:
server.enable("jsonp callback");
Then send your response using the "json()" method of response:
server.get("/ajax", function(req, res) {
res.json({foo: "bar"});
});
On the client side you can enanble JSONP in jQuery just by changing "json" to "jsonp" in the dataType option:
dataType: "jsonp",