Using RHINO js engine to make http requests - javascript

I'm trying to use the Mozilla/Rhino js engine to test some SOAP requests in the command line. However, none of the normal objects for making requests (XMLHttpRequest, HttpRequest) seem to be available. Why is this? Can I import libraries?

I was able to get it to work using just Rhino with the following code.
var post = new org.apache.commons.httpclient.methods.PostMethod("https://someurl/and/path/");
var client = new org.apache.commons.httpclient.HttpClient();
// ---- Authentication ---- //
var creds = new org.apache.commons.httpclient.UsernamePasswordCredentials("username", "password");
client.getParams().setAuthenticationPreemptive(true);
client.getState().setCredentials(org.apache.commons.httpclient.auth.AuthScope.ANY, creds);
// -------------------------- //
post.setRequestHeader("Content-type", "application/xml");
post.setRequestEntity(new org.apache.commons.httpclient.methods.StringRequestEntity(buildXML(), "text/plain", "ASCII" ));
var status = client.executeMethod(post);
var br = new java.io.BufferedReader(new java.io.InputStreamReader(post.getResponseBodyAsStream()));
var response = "";
var line = br.readLine();
while(line != null){
response = response + line;
line = br.readLine();
}
post.releaseConnection();

You might possibly find a library to import, you could also write your own in Java and make them available to your rhino instance, depending on how your are using it. Keep in mind Rhino is just a Javascript language engine. It doesn't have a DOM, and is not inherently 'web aware' so to speak.
However, since it sounds like you are doing this for testing/experimentation purposes, and you will probably be more productive not having to reinvent the wheel to do so, I will strongly, strongly suggest that you just download Node.js and look into the request module (for making HTTP requests) or any of the various SOAP modules.
You can do a ton more with Node.js, but you can also use it as a very simple runner for Javascript files as well. Regardless you should move away from Rhino though. It is really old and not really supported anymore, especially now that with JDK8 even the javax.script support will switch to the Nashorn engine.
UPDATE: If you really want to give it a go (and if you are prepared to monkey around with Java), you might look at this SO question and its answers. But unless you are something of a masochist, I think you'll be happier taking a different path.

I was actually able to do this using Orchestrator 5.1 with the 'Scriptable task' object to interface with the Zabbix API:
var urlObject = new URL(url);
var jsonString = JSON.stringify({ jsonrpc: '2.0', method: 'user.login', params: { user: 'username', password: 'password' }, id: 1 });
urlObject.contentType = "application/json";
result = urlObject.postContent(jsonString);
System.log(result);
var authenticationToken = JSON.parse(result).result;

Related

How to load external js library in Jmeter?

I have the following code in a jsr223 sampler:
var key = "key";
var dateStamp = "20160329T134359Z";
var regionName = "us-east-1";
var serviceName = "execute-api";
var kDate= Crypto.HMAC(Crypto.SHA256, dateStamp, "AWS4" + key, { asBytes: true})
var kRegion= Crypto.HMAC(Crypto.SHA256, regionName, kDate, { asBytes: true });
var kService=Crypto.HMAC(Crypto.SHA256, serviceName, kRegion, { asBytes: true });
var kSigning= Crypto.HMAC(Crypto.SHA256, "aws4_request", kService, { asBytes: true });
vars.put("AWSKey", kSigning);
Now when I run it i get this error:
Response code: 500
Response message: javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "Crypto" is not defined. (#6) in at line number 6
Obviously I dont have the crypto libs. However I am at loss on how to load them. I downloaded all the relavant js and put them in the /lib folder and still nothing.
I downloaded this file: https://github.com/Boussetta/CryptoJS-v3.1.2
Which handles the functions in the code above but for the life of me I have not idea how to import it.
TIA
If you want to go for JavaScript - there are 2 options:
Use Rhino load() method like:
load("crypto.js")
Use HmacUtils class from Apache Commons Codec from JavaScript
var rawhmac = org.apache.commons.codec.digest.HmacUtils.hmacSha1(key,data)
var encoded = org.apache.commons.codec.binary.Base64.encodeBase64String(rawhmac)
However I would recommend going for option 3 - switch to "groovy" language instead of JavaScript, that way you will be able to:
Re-use Amazon authentication samples in your test
Get maximum performance and confidence as groovy scripts can be compiled while other languages are interpreted so groovy implementation will take less resources and will work faster. See Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For! article for more details.

HTTP Request using Mozilla Rhino

I would like to write a JavaScript code processed with Mozilla Rhino that can do a simple HTTP GET request, which fetches a text string from a URL.
The problem is that, I couldn't find any support in Rhino to do any kind of HTTP requests. Besides, I don't have access to the Rhino instance itself, it's running via TopBraid Composer IDE for ontology modelling. I believe any idea about a simple library that I can import within my JavaScript file maybe a good solution.
Any help?
Thanks.
Okay, so it wasn't that difficult to figure it out. This one works via TopBraid Composer and without importing any JAVA libraries. Here's the answer in case anyone needs it later on.
var resourceURL = new java.net.URL(
'http://someurl');
var urlConnection = resourceURL.openConnection();
var inputStream = new java.io.InputStreamReader(urlConnection
.getInputStream());
var bufferedReader = new java.io.BufferedReader(inputStream);
var inputLine = bufferedReader.readLine();
bufferedReader.close();
var jsString = String(inputLine);
return jsString;

Use "readabilitySAX" on distant pages, in Node.js

I want to get the length of articles published on newspapers and magazines websites and on blogs.
In a server made in Node.js, I want to use the "readabilitySAX" module (https://github.com/fb55/readabilitySAX), but I must make a mistake with the way to use it because this code is not working:
var Readability = require("readabilitySAX/readabilitySAX.js"),
Parser = require("htmlparser2/lib/Parser.js");
var readable = new Readability({
pageURL: "http://www.nytimes.com/2014/04/18/business/treatment-cost-could-influence-doctors-advice.html?src=me&ref=general"
});
parser = new Parser(readable, {});
console.log(readable.getArticle().textLength);
The pageURL attribute is used when Readability resolve relative links, not to download a page.
To download a page, you can use the get method :
require("readabilitySAX").get("http://url", {type:"html"}, function(article) {
console.log(article.textLength);
})

JSONP callback in Dart

I have been trying to get basic JSONP working in Dart and I am getting stuck. Reading this blog post as well as this this blog show that I should use window.on.message.add(dataReceived); to get a MessageEvent and retrieve data from the event.
Dart complains that "There is no such getter 'message' in events". In addition, I looked up different ways of getting a MessageEvent but it seems to be something completely unrelated (WebSockets?) and is not what I actually need.
If anybody can explain what is going on and how to really use JSONP in Dart, that would be awesome!
You don't need to use what is described in the articles you point anymore. You can use dart:js :
import 'dart:html';
import 'dart:js';
void main() {
// Create a jsFunction to handle the response.
context['processData'] = (JsObject jsonDatas) {
// call with JSON datas
};
// make the call
ScriptElement script = new Element.tag("script");
script.src = "https://${url}?callback=processData";
document.body.children.add(script);
}
I recently wrote a blog post on this myself as I was running into similar problems.
I first cover a few prerequisite things like Verifying CORS Compliance and Verifying JSONP Support
I too ended up registering with the updated method:
window.onMessage.listen(dataReceived);
I then had a fairly simple method to dynamically create the script tag in Dart as well (my requirement was that I had to use Dart exclusively and couldn't touch the website source files):
void _createScriptTag()
{
String requestString = """function callbackForJsonpApi(s) {
s.target="dartJsonHandler";
window.postMessage(JSON.stringify(s), '*');
}""";
ScriptElement script = new ScriptElement();
script.innerHtml = requestString;
document.body.children.add(script);
}
I then invoked it from Dart with some simple logic that I wrapped in a method for convenience.
void getStockQuote(String tickerId)
{
String requestString = "http://finance.yahoo.com/webservice/v1/symbols/" + tickerId + "/quote?format=json&callback=callbackForJsonpApi";
ScriptElement script = new ScriptElement();
script.src = requestString;
document.body.children.add(script);
}
If you are using dart:js I find Alexandre's Answer useful and, after upvoting Alexandre, I have updated my post to include the simplified version as well:
context['callbackForJsonpApi'] = (JsObject jsonData)
{
//Process JSON data here...
};
This obviously eliminates the need for the onMessage and _createScriptTag above, and can be invoked the same as before.
I decided to keep both approaches, however, as I have noticed over time the Dart APIs changing and it seems to be a good idea to have a fallback if needed.
The syntax has changed
window.onMessage.listen(dataReceived);

Parsing XML / RSS from URL using Java Script

Hi i want to parse xml/rss from a live url like http://rss.news.yahoo.com/rss/entertainment using pure Java Script(not jquery). I have googled a lot. Nothing worked for me. can any one help with a working piece of code.
(You cannot have googled a lot.) Once you have worked around the Same Origin Policy, and if the resource is served with an XML MIME type (which it is in this case, text/xml), you can do the following:
var x = new XMLHttpRequest();
x.open("GET", "http://feed.example/", true);
x.onreadystatechange = function () {
if (x.readyState == 4 && x.status == 200)
{
var doc = x.responseXML;
// …
}
};
x.send(null);
(See also AJAX, and the XMLHttpRequest Level 2 specification [Working Draft] for other event-handler properties.)
In essence: No parsing necessary. If you then want to access the XML data, use the standard DOM Level 2+ Core or DOM Level 3 XPath methods, e.g.
/* DOM Level 2 Core */
var title = doc.getElementsByTagName("channel")[0].getElementsByTagName("title")[0].firstChild.nodeValue;
/* DOM Level 3 Core */
var title = doc.getElementsByTagName("channel")[0].getElementsByTagName("title")[0].textContent;
/* DOM Level 3 XPath (not using namespaces) */
var title = doc.evaluate('//channel/title/text()', doc, null, 0, null).iterateNext();
/* DOM Level 3 XPath (using namespaces) */
var namespaceResolver = (function () {
var prefixMap = {
media: "http://search.yahoo.com/mrss/",
ynews: "http://news.yahoo.com/rss/"
};
return function (prefix) {
return prefixMap[prefix] || null;
};
}());
var url = doc.evaluate('//media:content/#url', doc, namespaceResolver, 0, null).iterateNext();
(See also JSX:xpath.js for a convenient, namespace-aware DOM 3 XPath wrapper that does not use jQuery.)
However, if for some (wrong) reason the MIME type is not an XML MIME type, or if it is not recognized by the DOM implementation as such, you can use one of the parsers built into recent browsers to parse the responseText property value. See pradeek's answer for a solution that works in IE/MSXML. The following should work everywhere else:
var parser = new DOMParser();
var doc = parser.parseFromString(x.responseText, "text/xml");
Proceed as described above.
Use feature tests at runtime to determine the correct code branch for a given implementation. The simplest way is:
if (typeof DOMParser != "undefined")
{
var parser = new DOMParser();
// …
}
else if (typeof ActiveXObject != "undefined")
{
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
// …
}
See also DOMParser and HTML5: DOM Parsing and Serialization (Working Draft).
One big problem you might run into is that generally, you cannot get data cross domain. This is big issue with most rss feeds.
The common way to deal with loading data in javascript cross domain is calls JSONP. Basically, this means that the data you are retrieving is wrapped in a javascript callback function. You load the url with a script tag, and you define the function in your code. So when the script loads, it executes the function and passes the data to it as an argument.
The problem with most xml/rss feeds is that services that only provide xml tend not to provide JSONP wrapping capability.
Before you go any farther, check to see if your data source provides a json format and JSONP functionality. That will make this a lot easier.
Now, if your data source doesn't provide json and jsonp functionality, you have to get creative.
On relatively easy way to handle this is to use a proxy server. Your proxy runs somewhere under your control, and acts as a middleman to get your data. The server loads your xml, and then your javascript does the requests to it instead. If the proxy server runs on the same domain name then you can just use standard xhr(ajax) requests and you don't have to worry about cross-domain stuff.
Alternatively, your proxy server can wrap the data in a jsonp callback and you can use the method mentioned above.
If you are using jQuery, then xhr and jsonp requests are built-in methods and so make doing the coding very easy. Other common js libraries should also support these. If you are coding all of this from scratch, its a little more work but not terribly difficult.
Now, once you get your data hopefully its just json. Then there's no parsing needed.
However, if you end up having to stick with an xml/rss version, and if you're jQuery, you can simply use jQuery.parseXML http://api.jquery.com/jQuery.parseXML/.
better convert xml to json. http://jsontoxml.utilities-online.info/
after converting if you need to print json object check this tutorial
http://www.w3schools.com/json/json_eval.asp

Categories