Read raw http message in Nodejs - javascript

I'm sending an http request using the http.request function, and I would like to read the whole http response like text; that is, the raw http protocol text. Is it possible? I've written the below code but it's not working.
// Set up the request
console.log('Sending request');
var post_req = http.request(post_options, function(res) {
res.setEncoding('utf8');
console.log('Response statusCode: ' + res.statusCode);
// res.on('data', function (chunk) {
// console.log('Response: ' + chunk);
// });
// res.on('end', function() {});
});
post_req.on('socket', function (socket) {
var response = "";
socket.on('data', function(chunk){
console.log(chunk);
});
});
// post the data
post_req.write(post_data);
post_req.end();

If you want access to the raw http message, I'd suggest using the net module instead, and writing the request yourself. Something like this for a simple GET request:
var net = require('net');
var host = 'stackoverflow.com',
port = 80,
socket = net.connect(port, host, function() {
var request = "GET / HTTP/1.1\r\nHost: " + host + "\r\n\r\n",
rawResponse = "";
// send http request:
socket.end(request);
// assume utf-8 encoding:
socket.setEncoding('utf-8');
// collect raw http message:
socket.on('data', function(chunk) {
rawResponse += chunk;
});
socket.on('end', function(){
console.log(rawResponse);
});
});
For a POST request sending application/x-www-form-urlencoded data, you could write the request using something like:
function writePOSTRequest (data, host, path) {
return "POST " + path + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" +
"Content-Length: " + Buffer.byteLength(data) + "\r\n\r\n" +
data + "\r\n\r\n";
}
var data = "name1=value1&name2=value2",
request = writePOSTRequest(data, host, "/path/to/resource");
where I'm using Buffer.byteLength because Content-Length requires the length in bytes, not in characters. Also, remember that data must be URL encoded.
If you don't know much about the format of HTTP messages, then this is a decent place to start:
http://jmarshall.com/easy/http/
Also, if you don't know what the encoding of the response will be then you'll have to parse the headers first to find out, but UTF-8 is by far the most common so it's a pretty safe bet.

Streams2 and Streams1 not always able to inter-operate well, see "problem: streams1 and streams2 duality" in this video.
I tried to listen data at a bit lower level than streams and this code prints raw http response with headers for me:
var http = require('http');
var raw = '';
console.log('Sending request');
var req = http.request({host: 'stackoverflow.com'}, function(res) {
watch(res, 'res');
res.on('end', function() {
console.log(raw);
});
res.on('data', function(data) {
// if we don't attach 'data' handler here 'end' is not called
});
});
req.on('socket', function (socket) {
socket.resume();
var oldOndata = socket.ondata;
socket.ondata = function(buf, start, end) {
raw += buf.slice(start, end).toString();
oldOndata.call(socket, buf, start, end);
};
});
req.end();

Assuming these kind of tools are allowed in your environment, you could run up an HTTP debug proxy such as Fiddler http://www.fiddler2.com/, which enables you to inspect the HTTP calls and responses.

Related

Server proxy with Node JS

I want to build a proxy with node.js to use in my browser.
I searched at google and saw that example, but some Apis are deprecated.
So I changed the code following:
var http = require('http');
http.createServer(function(request, response) {
console.log("req for:"+ request.headers['host'] + "\nmethod: "+ request.method);
var options = {
host : request.headers['host'],
method : request.method,
headers : request.headers
}
var callback = function(res){
// get the proxyclient response and write to the original response
res.addListener('data', function(chunk){
console.log("writing response");
response.write(chunk, 'binary');
});
res.addListener('end', function(){
console.log("end response");
response.end();
});
};
// send the original request
var proxy = http.request(options, callback);
// intercept the request and write to proxyclient
request.addListener('data', function(chunk){
console.log("new request");
proxy.write(chunk, 'binary');
});
request.addListener('end', function(){
console.log("end request");
proxy.end();
});
}).listen(3333);
After that, I changed my browser proxy settings to use localhost:3333.
My problem is that event "data" isn't fired.
This should work as I thought?
Maybe if you write this code;
response.writeHead(res.statusCode, res.headers); after res.addListener('end', function(){
console.log("end response");
response.end();
});

Nodejs http request returning json not in json format

I'm trying to make a request to here, if you click on the link you should see a JSON response (as expected). I've, tried https and http, it doesnt matter (at least I don't think so).
Anyways the problem when I try to get a response from the command line, I get non UTF-8 characters like �������B��������E��9 as a response, even when I specify utf-8 encoding. Ive tried the npm module request and doing node http/https requests.
All i need is to just return a JSON response.
I've also tried JSON.parse() but to no avail.
Here's the code I've tried
var request = require("request")
var url = endpoint;
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body); // Print the json response
}
})
and the basic http request
var endpoint = 'http://api.stackexchange.com/2.1/search/advanced?order=desc&sort=relevance&q=jsonp&site=stackoverflow';
var req = http.request(endpoint, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write('data\n');
req.write('data\n');
req.end();
Stackoverflow servers are misconfigured, so they return gzip-encoded body even though you didn't ask for it.
Looks like you have to gunzip your response after receiving it.

With node.js how to I set a var to response from HTTP client?

I know this is probably Asynchronous Javascript 101 and I do have some books on the Kindle I could consult, but I am nowhere near my device.
I have a node app with a variable being assigned to a module that I'm loading. The module has one function that downloads a string of data from a URL.
The problem is, how do I not set the variable until the request has returned?
My code looks like this:
Downloader.js:
var http = require('http');
exports.downloadString = function(str) {
console.log("Downloading from " + str);
http.get(str, function(res) {
var data = [];
console.log("Got response: " + res.statusCode);
res.on('data', function (chunk) {
data.push(chunk);
});
res.on('end', function() {
return data.join('');
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
}
app.js:
var downloader = require('./lib/Downloader')
, dateParser = require('./lib/DateParser')
, eventIdGenerator = require('./lib/EventIdGenerator');
var report = downloader.downloadString("http://exampleapi.com");
console.log(report);
I need to wait until the variable named "report" is populated.
Obviously this means my Mocha tests are also failing as I'm still unsure of how to tell the test to wait until the variable is filled.
I'm sure this is extremely simple, but I am drawing a blank!
Thanks!
Node.js is (mostly) asynchronous, so you'd need to pass a callback function to your module:
Downloader.js:
var http = require('http');
exports.downloadString = function(str, callback) {
console.log("Downloading from " + str);
http.get(str, function(res) {
var data = [];
console.log("Got response: " + res.statusCode);
res.on('data', function (chunk) {
data.push(chunk);
});
res.on('end', function() {
callback(data.join(''));
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
};
app.js:
var downloader = require('./lib/Downloader')
, dateParser = require('./lib/DateParser')
, eventIdGenerator = require('./lib/EventIdGenerator');
downloader.downloadString("http://exampleapi.com", function(report) {
console.log(report);
});

Node.js http request

I am a beginner with node.js, and I'm not seeming to get this to work.
function sleep(milliSeconds){
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + milliSeconds);
}
var isRequestComplete = false;
while(isRequestComplete == false){
console.log("in make request");
var querystring = require('querystring');
var data = querystring.stringify({
username: 'username',
password: 'password',
action: 'convert',
voice: 'engfemale1',
text: 'stuff and things, this should take longer than one request.'
});
var options = {
host: 'ws.ispeech.org',
port: 80,
path: '/api/rest/1.5',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
};
var http = require('http');
var req = http.request(options, function(res) {
console.log("got response");
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log("body: " + chunk);
if(chunk.indexOf("finished") != -1){
isRequestComplete = true;
}
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write(data);
req.end();
console.log("completed");
sleep(5000);
}
For whatever reason the http request does not send a response back, ever. Unless the code is fully finished, so in the while loop I never get a response back. Thus the loop never ends. The username and password in my program are inputted, here they are not for confidentiality. Thanks for reading.
this is NOT the way to get your code to sleep! A while loop isn't "sleeping" it's processing as fast as it can. In you case it's grabbing date after date after date trying to get to your destination.
take a look here to see how this *should work.
http://nodejs.org/api/http.html
Have a look at the very first http-server example on http://nodejs.org/.
You have to create an http-server that listens for requests from browsers that arrive at the specified IP-Address:Port. Once a request arrives, the server send the specified response to the browser.

POST request with data in node.js

How could I send POST request with data (eg. some variables) to the https server and display the results to the end user?
Use the http.Client module. From the docs:
var http = require('http');
var google = http.createClient(80, 'www.google.com');
var request = google.request('GET', '/', {'host': 'www.google.com'});
request.end();
request.on('response', function (response) {
console.log('STATUS: ' + response.statusCode);
console.log('HEADERS: ' + JSON.stringify(response.headers));
response.setEncoding('utf8');
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
I am pretty sure that you can exchange GET with POST ;)

Categories

Resources