At present I'm using req.headers.host to determine the server's host name, which is effective when processing a request received at the server.
But how can one determine the host name in the absence of a request (i.e. without req)? I'm thinking, in particular, when the node server is first created and run, and before any requests are received.
I'm using the express module.
Thanks
you can use the os module and os.hostname()
https://nodejs.org/docs/latest/api/os.html#os_os_hostname
Related
Ive been trying to implement the WebSocket protocol from scratch in nodejs, doing so i have a question thats since been unawnsered. What exactly are subprotocols in regards to websockets? The second parameter of the WebSocket constructor is where you specify "subprotocols" -
let socket = new WebSocket("ws://localhost:3000",["http",...]);
Can anybody give me a clear awnser to what purpose they have?
Websockets just define a mechanism to exchange arbitrary messages. What those messages mean, what kind of messages a client can expect at any particular point in time or what messages they are allowed to send is entirely up to the implementing application. So you need an agreement between the server and client about these things. You might say… you need a protocol specification. The subprotocol parameter simply lets clients formally exchange this information. You can just make up any name for any protocol you want. The server can simply check that the client appears to adhere to that protocol during the handshake. You can also use it to request different kinds of protocols from the server, or use it for versioning (e.g. when you introduce my-protocol-v2, but still need to support clients only understanding my-protocol-v1).
Explained on MDN here
Think of a subprotocol as a custom XML schema or doctype declaration.
You're still using XML and its syntax, but you're additionally
restricted by a structure you agreed on. WebSocket subprotocols are
just like that. They do not introduce anything fancy, they just
establish structure. Like a doctype or schema, both parties must agree
on the subprotocol; unlike a doctype or schema, the subprotocol is
implemented on the server and cannot be externally referred to by the
client.
Subprotocols are explained in sections 1.9, 4.2, 11.3.4, and 11.5 of the spec.
A client has to ask for a specific subprotocol. To do so, it will send
something like this as part of the original handshake:
http GET /chat HTTP/1.1 ... Sec-WebSocket-Protocol: soap, wamp
or, equivalently:
... Sec-WebSocket-Protocol: soap Sec-WebSocket-Protocol: wamp
Now the server must pick one of the protocols that the client
suggested and it supports. If there is more than one, send the first
one the client sent. Imagine our server can use both soap and wamp.
Then, in the response handshake, it sends:
Sec-WebSocket-Protocol: soap
The server can't send more than one Sec-Websocket-Protocol header. If
the server doesn't want to use any subprotocol, it shouldn't send any
Sec-WebSocket-Protocol header. Sending a blank header is incorrect.
The client may close the connection if it doesn't get the subprotocol
it wants.
If you want your server to obey certain subprotocols, then naturally
you'll need extra code on the server. Let's imagine we're using a
subprotocol json. In this subprotocol, all data is passed as JSON. If
the client solicits this protocol and the server wants to use it, the
server needs to have a JSON parser. Practically speaking, this will be
part of a library, but the server needs to pass the data around.
Some sample code, copy from https://hpbn.co/websocket/#subprotocol-negotiation, to make it clear.
The client can advertise which protocols it supports to the server as
part of its initial connection handshake:
var ws = new WebSocket('wss://example.com/socket',
['appProtocol', 'appProtocol-v2']);
ws.onopen = function () {
if (ws.protocol == 'appProtocol-v2') {
...
} else {
...
}
}
The npm-request library allows me to construct HTTP requests using a nice JSON-style syntax, like this.
request.post(
{
url: 'https://my.own.service/api/route',
formData: {
firstName: 'John',
lastName: 'Smith'
}
},
(err, response, body) => {
console.log(body)
}
);
But for troubleshooting, I really need to see the HTTP message body of the request as it would appear on the wire. Ideally I'm looking for a raw bytes representation with a Node.js Buffer object. It seems easy to get this for the response, but not the request. I'm particularly interested in multipart/form-data.
I've looked through the documentation and GitHub issues and can't figure it out.
Simplest way to do this is to start a netcat server on any port:
$ nc -l -p 8080
and change the URL to localhost in your code:
https://localhost:8080/v1beta1/text:synthesize?key=API_KEY
Now, any requests made will print the entire, raw HTTP message sent to the localhost server.
Obviously, you won't be able to see the response, but the entire raw request data will be available for you to inspect in the terminal you have netcat running
I figured out how to dump the HTTP message body with Request. In both cases, I'm just copying the same approach that request uses internally.
Multipart Form Uploads
req._form.pipe(process.stdout);
URL-encoded Forms
console.log(req.body);
You could try #jfriend00 suggestion an use a network sniffer like wireshark but as you're fetching an https URL this might not be the easiest route as it requires some setup to intercept TLS connections.
So maybe it would be enough turning on debug mode for the request module itself, you can do that by simply setting require('request').debug = true. As a third option you could go with the dedicated debug module for request here which allows you to view request and response headers and bodies.
I can think of a number of ways to see the bytes of the request:
Turn on debugging in the request module. There are multiple ways to do that documented here including setting NODE_DEBUG=request or require('request').debug = true or using the request-debug module.
Use a network sniffer to see what's actually being sent over the socket, independent of your node.js code.
Create your own dummy http server that does nothing but log the exact incoming request and send your same request to that dummy server so it can log it for you.
Create or use a proxy (like nginx) that can dump the exact incoming request before forwarding it on to its final destination and send the request to the proxy.
Step through the sending of the request in the debugger to see exactly what it is writing to the socket (this may be time consuming, particularly with async callbacks, but will eventually work).
you could use a nodejs server capable of logging the raw request/response string , then direct your request to that server
i gave an example using both http and https server - no dependencies
nodejs getting raw https request and response
I am questioning whether it is required to validate fields like req.ip or req.path server-side.
It boils down to the question: Is it possible for the client to set something like .set('Remote-Addr', <Malicious JavaScript>) and it successfully being propagated to my Node or Express middleware?
Thanks for helping!
There is no way to validate source IP, particular when proxies are involved. In the proxy case, a chain of IP addresses is supposed to be put in http headers, but that can certainly be faked so what express thinks is the original IP cannot be trusted. It is likely accurate, but not guaranteed accurate.
req.path is entirely local and does not involve any client headers and is not subject to any client spoofing. It just comes from the actual HTTP request URL that arrives at your server. The only way it wouldn't be the same as the actual request URL is if you were using a mount point for routers in which case the mount point part of the path will have been removed by express. Or perhaps if your own middleware attempted to mess with it.
In PHP, getting cookies sent from a remote server is simply a matter of using cURL with some cookie handling option enabled.
If I was to treat my server as a client making requests to a remote server, I was wondering how this might be done in node.js? Would my server/app even be receiving these cookies? If so, how can I get the name and values of these cookies?
I've tried using the following node.js modules to no avail:
request (??? not part of functionality?)
tough-cookie (not part of functionality)
client-http (I get an empty array)
node-curl (I get an empty array)
Any pointers would be appreciated. Thanks!
You can use the http module that comes with Node.js
var http = require('http');
http.get('http://www.google.ca', function(res) {
console.log(res.headers['set-cookie']);
});
will give you all the cookies that google.ca would try to set on you when you visit.
I create simple web app, using neo4j REST API, JS and JQuery. I am able to create new node using $post:
$.post("http://localhost:7474/db/data/node",
{
"name":data[i].name,
"phone":data[i].phone
},
function(jsonData) {
newlyCreated = jsonData.self;
},
'json');
it works, new node is created and appears in db.
Unfortunately when I try to create index using $post, this syntax doesn't work:
$.post("http://localhost:7474/db/data/index/node",{"name":"phone"},function(indexInfo) {
console.log(indexInfo);
}, 'json');
When I try to use neo4j http console:
POST http://localhost:7474/db/data/index/node/ {"name": "phone"}
It works fine index is created.
Any suggestions why $.post doesn't work properly in this case?
It's a no-no to send requests to Neo4j directly through JavaScript. Probably it doesn't work because of the Cross Origin ( No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'xxyy' is therefore not allowed access).
Usually Neo4j runs on port 7474, so if you're doing requests from port 80 (default http port) you're no allowed. Also, if you make request from the same port (like the browser does, you also need to add Authentication is that is enabled in your Neo4j configuration)
The security risk is that if you do direct request from a browser to a secure Neo4j, saving username and password in the browser will let anyone have direct access to your Neo4j instance.
So the best way is to create a proxy (with a Allow Origin configuration), that verify the request and if it's a valid one, authenticate and send it to the database, and return to the browser request the required data. :)