NODE JS http form post failing without fidler proxy - node.js

I am making http form post using request node module (https://www.npmjs.org/package/request).
The post request fails with error - {"code":"ECONNRESET","errno":"ECONNRESET","syscall":"read","level":"error","message":"","timestamp":"2014-09-05T17:35:34.616Z"}
If I run fiddler and channel the request via fiddler, it works fine.
Any idea why would that happen and how I can resolve it!
Here is the exact code I am using. It works as long as I use it as stand alone node js. But, if its made a web app, it fails. It seems to work a few times.., but fails continuously after that. At this point, even the stand alone node js fails to run.
However, when I enable the proxy and open fiddler, it works magically!
var request = require('request');
var url = "https://idctestdemo.hostedcc.com/callcenter/mason/agents/pipes/muterecording.pipe"//"https://restmirror.appspot.com/"
,form_data = {"pipe-name": "Deepak"};
var args = { url: url, form: form_data};
if(process.argv.length > 2){
var enable_proxy = process.argv[2];
if(enable_proxy && enable_proxy[0] == 'p'){
console.log('enabling proxy')
args['proxy'] = 'http://127.0.0.1:8888';
args["rejectUnauthorized"] = false;
}
}
var oclient = request.post(args
,function(error, response, body){
if (error){
console.log('error in reponse');
console.error(error);
} else {
console.log('success!');
console.dir(body);
}
});
oclient.on('error',function(err){
console.log('client error');
console.error(err);
});
oclient.on('end',function(end_data){console.log('end', end_data)});
oclient.on('data',function(d){console.log('on data', d)});
console.log('waiting for response...')
If everything goes well, the expected response should be
<script>
parent.xb.pipe.onNotify('Deepak',{desc:'Pipe opened by server',payload:{time:'Mon Sep 8 12:58:18 2014'},type:'MSG_OPENED'});
</script>
<script>
parent.xb.pipe.onNotify('Deepak',{desc:'Not logged in',payload:{hostcode:'ny-1'},type:'ERR_NOLOGIN'});
</script>
<script>
parent.xb.pipe.onNotify('Deepak',{desc:'Pipe closed by server',payload:null,type:'MSG_CLOSED'});
</script>

ECONNRESET
means the other side you want to connect/send data to, is not accepting requests.
Maybe you can find more information by looking into the server log.
You also could try to check what happens if you change the port listen to.
If I should help more, I need more information.

Related

How to tell if request was from browser or browser extension

When I run the following code I get two requests from my Chrome browser and have narrowed it down to one extension just by disabling it in chrome, but my question is how do I tell from my server side code which is the browser request and which is the extensions request
var http = require('http');
var server = http.createServer((request, response) => {
if (request.url == '/favicon.ico'){
console.log('ignore icon request')
}else{
console.log(request.url);
response.write('hi');
response.end();
}
});
server.listen(3000);
calling http://localhost:3000/, my output ends up being
/
/
ignore icon request
so similar to what I did with ignoring the favicon, is there a simple way of ignoring that extension request?

Node HTTP Server does not respond to first request within Electron

I'm trying to start a local server in Electron to capture Google's OAuth callback like so:
this.server = http.createServer((request, response) => {
const { query } = url.parse(request.url, true);
if (query.code) {
this.onCodeReceived(query.code);
// do something nicer here eventually
response.end();
} else {
response.end('Error');
this.authStatus = 'error';
}
}).listen(this.LOCAL_SERVER_PORT);
The issue I'm having is that when I finish authenticating with Google the window just sits at "Waiting for 127.0.0.1..." and never actually finishes. I've found using console.log in the request handler that the handler is never actually called, so I'm stumped as to why the request isn't going through.
I've verified that the callback URL has the same port the server is listening to, and that the server actually begins listening. Weirdly if I open a new tab and go to the URI I get the expected Error response.
For reference the callback URI is set as http://127.0.0.1:18363 and this.LOCAL_SERVER_PORT = 18363.
If anyone has any ideas I'd greatly appreciate it. Thank you!

node request pipe hanging after a few hours

I have an endpoint in a node app which is used to download images
var images = {
'car': 'http://someUrlToImage.jpg',
'boat': 'http://someUrlToImage.jpg',
'train': 'http://someUrlToImage.jpg'
}
app.get('/api/download/:id', function(req, res){
var id = req.params.id;
res.setHeader("content-disposition", "attachment; filename=image.jpg");
request.get(images[id]).pipe(res);
});
Now this code works fine, but after a few hours of the app running, the endpoint just hangs.
I am monitoring the memory usage of the app, which remains consistent, and any other endpoints which just return some JSON respond as normal so it is not as if the event loop is somehow being blocked. Is there a gotcha of some kind that I am missing when using the request module to pipe a response? Or is there a better solution to achieve this?
I am also using the Express module.
You should add an error listener on your request because errors are not passed in pipes. That way, if your request has an error, it will close the connection and you'll get the reason.
request
.get(...)
.on('error', function(err) {
console.log(err);
res.end();
})
.pipe(res)

check on server side if youtube video exist

How to check if youtube video exists on node.js app server side:
var youtubeId = "adase268_";
// pseudo code
youtubeVideoExist = function (youtubeId){
return true; // if youtube video exists
}
You don't need to use the youtube API per-se, you can look for the thumbnail image:
Valid video = 200 - OK:
http://img.youtube.com/vi/gC4j-V585Ug/0.jpg
Invalid video = 404 - Not found:
http://img.youtube.com/vi/gC4j-V58xxx/0.jpg
I thought I could make this work from the browser since you can load images from a third-party site without security problems. But testing it, it's failing to report the 404 as an error, probably because the content body is still a valid image. Since you're using node, you should be able to look at the HTTP response code directly.
I can't think of an approach that doesn't involve making a separate HTTP request to the video link to see if it exists or not unless you know beforehand of a set of video IDs that are inactive,dead, or wrong.
Here's an example of something that might work for you. I can't readily tell if you're using this as a standalone script or as part of a web server. The example below assumes the latter, assuming you call a web server on /video?123videoId and have it respond or do something depending on whether or not the video with that ID exists. It uses Node's request library, which you can install with npm install request:
var request = require('request');
// Your route here. Example on what route may look like if called on /video?id=123videoId
app.get('/video', function(req, response, callback){
var videoId = 'adase268_'; // Could change to something like request.params['id']
request.get('https://www.youtube.com/watch?v='+videoId, function(error, response, body){
if(response.statusCode === 404){
// Video doesn't exist. Do what you need to do here.
}
else{
// Video exists.
// Can handle other HTTP response codes here if you like.
}
});
});
// You could refactor the above to take out the 'request.get()', wrap it in a function
// that takes a callback and re-use in multiple routes, depending on your problem.
#rodrigomartell is on the right track, in that your check function will need to make an HTTP call; however, just checking the youtube.com URL won't work in most cases. You'll get back a 404 if the videoID is a malformed ID (i.e. less than 11 characters or using characters not valid in their scheme), but if it's a properly formed videoID that just happens to not correspond to a video, you'll still get back a 200. It would be better to use an API request, like this (note that it might be easier to use the request-json library instead of just the request library):
request = require('request-json');
var client = request.newClient('https://www.googleapis.com/youtube/v3/');
youtubeVideoExist = function (youtubeId){
var apikey ='YOUR_API_KEY'; // register for a javascript API key at the Google Developer's Console ... https://console.developers.google.com/
client.get('videos/?part=id&id='+youtubeId+'&key='+apikey, function(err, res, body) {
if (body.items.length) {
return true; // if youtube video exists
}
else {
return false;
}
});
};
Using youtube-feeds module. Works fast (~200ms) and no need API_KEY
youtube = require("youtube-feeds");
existsFunc = function(youtubeId, callback) {
youtube.video(youtubeId, function(err, result) {
var exists;
exists = result.id === youtubeId;
console.log("youtubeId");
console.log(youtubeId);
console.log("exists");
console.log(exists);
callback (exists);
});
};
var notExistentYoutubeId = "y0srjasdkfjcKC4eY"
existsFunc (notExistentYoutubeId, console.log)
var existentYoutubeId = "y0srjcKC4eY"
existsFunc (existentYoutubeId, console.log)
output:
❯ node /pathToFileWithCodeAbove/FileWithCodeAbove.js
youtubeId
y0srjcKC4eY
exists
true
true
youtubeId
y0srjasdkfjcKC4eY
exists
false
false
All you need is to look for the thumbnail image. In NodeJS it would be something like
var http = require('http');
function isValidYoutubeID(youtubeID) {
var options = {
method: 'HEAD',
host: 'img.youtube.com',
path: '/vi/' + youtubeID + '/0.jpg'
};
var req = http.request(options, function(res) {
if (res.statusCode == 200){
console.log("Valid Youtube ID");
} else {
console.log("Invalid Youtube ID");
}
});
req.end();
}
API_KEY is not needed. It is quite fast because there is only header check for statusCode 200/404 and image is not loaded.

Node.js and understanding how response works

I'm really new to node.js so please bear with me if I'm making a obvious mistake.
To understand node.js, i'm trying to create a webserver that basically:
1) update the page with appending "hello world" everytime the root url (localhost:8000/) is hit.
2) user can go to another url (localhost:8000/getChatData) and it will display all the data built up from the url (localhost:8000/) being triggered
Problem I'm experiencing:
1) I'm having issue with displaying that data on the rendered page. I have a timer that should call get_data() ever second and update the screen with the data variable that stores the appended output. Specifically this line below response.simpleText(200, data); isn't working correctly.
The file
// Load the node-router library by creationix
var server = require('C:\\Personal\\ChatPrototype\\node\\node-router').getServer();
var data = null;
// Configure our HTTP server to respond with Hello World the root request
server.get("/", function (request, response) {
if(data != null)
{
data = data + "hello world\n";
}
else
{
data = "hellow world\n";
}
response.writeHead(200, {'Content-Type': 'text/plain'});
console.log(data);
response.simpleText(200, data);
response.end();
});
// Configure our HTTP server to respond with Hello World the root request
server.get("/getChatData", function (request, response) {
setInterval( function() { get_data(response); }, 1000 );
});
function get_data(response)
{
if(data != null)
{
response.writeHead(200, {'Content-Type': 'text/plain'});
response.simpleText(200, data);
console.log("data:" + data);
response.end();
}
else
{
console.log("no data");
}
}
// Listen on port 8080 on localhost
server.listen(8000, "localhost");
If there is a better way to do this, please let me know. The goal is to basically have a way for a server to call a url to update a variable and have another html page to report/display the updated data dynamically every second.
Thanks,
D
The client server model works by a client sending a request to the server and the server in return sends a response. The server can not send a response to the client that the client hasn't asked for. The client initiates the request. Therefore you cannot have the server changing the response object on an interval.
The client will not get these changes to the requests. How something like this is usually handled as through AJAX the initial response from the server sends Javascript code to the client that initiates requests to the server on an interval.
setTimeout accepts function without parameter which is obvious as it will be executed later in time. All values you need in that function should be available at the point of time. In you case, the response object that you are trying to pass, is a local instance which has scope only inside the server.get's callback (where you set the setTimeout).
There are several ways you can resolve this issue. you can keep a copy of the response instance in the outer scope where get_data belongs or you can move the get_data entirely inside and remove setTimeout. The first solution is not recommended as if getChatData is called several times in 1sec the last copy will be prevailing.
But my suggestion would be to keep the data in database and show it once getChatData is called.

Resources