javascript error in nifi executeScript - javascript

I am having an issue getting the javascript script for the executeScript nifi process to work and would appreciate help with this. The goal is to pass a flowfile which will contain a json object. I need to parse this json without knowing the content/fields prior and pass this along to write it out to the flowfile that is being passed out to the next process that is MergeContent and counts the number flowfiles.
Tried testing the script and got the following error:
nifi.script.ExecuteScript - ExecuteScript[id=bd6842e9-e3a4-4d88-a59d-
7da1d74d109b] ExecuteScript[id=bd6842e9-e3a4-4d88-a59d-7da1d74d109b]
failed to process due to
org.apache.nifi.processor.exception.ProcessException:
javax.script.ScriptException: <eval>:21:17 Expected : but found value
let value = json[key];
^ in <eval> at line number 21 at column number 17; rolling
back session: org.apache.nifi.processor.exception.ProcessException:
javax.script.ScriptException: <eval>:21:17 Expected : but found value
I am not very familiar with javascript so would appreciate the help.
flowFile = session.get();
if (flowFile != null) {
var StreamCallback =
Java.type("org.apache.nifi.processor.io.StreamCallback");
var IOUtils = Java.type("org.apache.commons.io.IOUtils");
var StandardCharsets = Java.type("java.nio.charset.StandardCharsets");
var transformed_message = {};
var error = false;
var line = "ops_testQueue";
flowFile = session.write(flowFile, new StreamCallback(function
(inputStream, outputStream) {
var content = IOUtils.toString(inputStream,
StandardCharsets.UTF_8); // message or content
var message_content = {};
try {
message_content = JSON.parse(content);
if(Array.isArray(message_content)){
}
Object.keys(message_content).forEach((key) => {
var value = json[key];
result.push(key + '=' + value);
var jkey = "," + "\"" + key + "\"" + '=' + value
});
line = line + jkey +
" value=" + "1"
+ " " + Date.now() * 1000000;
// Write output content
if (transformed_message) {
outputStream.write(line.getBytes(StandardCharsets.UTF_8));
}
} catch (e) {
error = true;
outputStream.write(content.getBytes(StandardCharsets.UTF_8));
}
}));
if (transformed_message.post_state) {
flowFile = session.putAttribute(flowFile, "type",
transformed_message.type);
}
if (error) {
session.transfer(flowFile, REL_FAILURE)
} else {
session.transfer(flowFile, REL_SUCCESS)
}
}
EDIT:
input to executeScript:
{"pID":"1029409411108724738",
"contentType":"text",
"published":"2018-08-14 16:48:23Z",
"crawled":"2018-08-14 12:48:33-04:00",
"ID":"765"}
output from executeScript:
ops_testQueue,"ID"=765 value=1 1534265314969999870
Am I missing something?

I saw a couple of things here:
I don't know if Nashorn (Java's JS Engine) supports the full lambda
syntax, I was able to get it to work by making the lambda a function
(see script below).
You refer to a json variable to get the value from a key, but I think you want message_content.
result is not defined, so you get an error when you push to it.
Here's an edited version of your script that I got to work the way I think you want it (but please correct me if I'm wrong):
flowFile = session.get();
if (flowFile != null) {
var StreamCallback =
Java.type("org.apache.nifi.processor.io.StreamCallback");
var IOUtils = Java.type("org.apache.commons.io.IOUtils");
var StandardCharsets = Java.type("java.nio.charset.StandardCharsets");
var transformed_message = {};
var error = false;
var line = "ops_testQueue";
flowFile = session.write(flowFile, new StreamCallback(function
(inputStream, outputStream) {
var content = IOUtils.toString(inputStream,
StandardCharsets.UTF_8); // message or content
var message_content = {};
try {
message_content = JSON.parse(content);
if(Array.isArray(message_content)){
}
var jkey = "";
Object.keys(message_content).forEach(function(key) {
var value = message_content[key];
//result.push(key + '=' + value);
jkey = "," + "\"" + key + "\"" + '=' + value
});
line = line + jkey +
" value=" + "1"
+ " " + Date.now() * 1000000;
// Write output content
if (transformed_message) {
outputStream.write(line.getBytes(StandardCharsets.UTF_8));
}
} catch (e) {
error = true;
log.error(e);
outputStream.write(content.getBytes(StandardCharsets.UTF_8));
}
}));
if (transformed_message.post_state) {
flowFile = session.putAttribute(flowFile, "type",
transformed_message.type);
}
if (error) {
session.transfer(flowFile, REL_FAILURE)
} else {
session.transfer(flowFile, REL_SUCCESS)
}
}

Related

Javascript catch error

I am totally new to this, i am learning this javascript. I am building an app/bot but am stuck at this. I didnt not write this code just found it on the web. So when the command start to execute i am getting this "catch" error but dont know what is problem. Most of the songs it wont show but accesing link in browser works fine: Here is the part of the code that gives error.
if (quizState) {
//Load current song stats
console.log(newMedia.author + " " + newMedia.duration);
var XMLsource = 'http://musicbrainz.org/ws/2/artist/?query=artist:' + newMedia.author.replace(/ /g, "%20") + '&limit=1';
simpleAJAXLib = {
init: function() {
this.fetchJSON(XMLsource);
},
fetchJSON: function(url) {
var root = 'https://query.yahooapis.com/v1/public/yql?q=';
var yql = 'select * from xml where url="' + url + '"';
var proxy_url = root + encodeURIComponent(yql) + '&format=json&diagnostics=false&callback=simpleAJAXLib.display';
document.getElementsByTagName('body')[0].appendChild(this.jsTag(proxy_url));
},
jsTag: function(url) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', url);
return script;
},
display: function(results) {
try {
quizCountry = results.query.results.metadata["artist-list"].artist.area.name;
quizYear = results.query.results.metadata["artist-list"].artist["life-span"].begin.match(/\d{4}/);
quizBand = results.query.results.metadata["artist-list"].artist.name;
if (quizCountry != "" && quizYear != "") {
console.log(quizCountry + " " + quizYear);
API.sendChat("U kojoj godini je/su " + quizBand + " osnovan/i?");
}
} catch (e) {
console.log("Error: " + e.description);
API.sendChat("Žao nam je, čini se da musicbrainz ne prepoznaje ovaj bend ili umjetnika. Nastavit ćemo za vrijeme sljedeće pjesme.");
console.log("country or year not known");
}
}
}
simpleAJAXLib.init();
}
If the search on http://musicbrainz.org/ws/2/artist/? returns more than one artist, the object returns an array in
results.query.results.metadata["artist-list"].artist
So, to access the data, it would be
quizCountry = results.query.results.metadata["artist-list"].artist[0].area.name;
quizYear = results.query.results.metadata["artist-list"].artist[0]["life-span"].begin.match(/\d{4}/);
quizBand = results.query.results.metadata["artist-list"].artist[0].name;
So, you'll need to check if
results.query.results.metadata["artist-list"].count > 1
and change your code appropriately
e.g.
if(results.query.results.metadata["artist-list"].count > 1) {
quizCountry = results.query.results.metadata["artist-list"].artist[0].area.name;
quizYear = results.query.results.metadata["artist-list"].artist[0]["life-span"].begin.match(/\d{4}/);
quizBand = results.query.results.metadata["artist-list"].artist[0].name;
} else {
quizCountry = results.query.results.metadata["artist-list"].artist.area.name;
quizYear = results.query.results.metadata["artist-list"].artist["life-span"].begin.match(/\d{4}/);
quizBand = results.query.results.metadata["artist-list"].artist.name;
}
Although, you may want to change your logic totally if you get more than one artist in the response - but the above should fix your errors

Cannot open file "/dev/ttyO2" when trying to use the serial port on the Beaglebone Black

I am trying to open the serial port 2 on my beagle bone, using the following code:
var b = require('bonescript');
var x = '/dev/ttyO2';
var SerialPort = require("serialport").SerialPort;
var serialPort = new SerialPort('/dev/ttyO2', {
baudrate: 115200,
parser: b.serialParsers.readline("\n")
});
The complete code:
var b = require('bonescript');
var x = '/dev/ttyO2';
var SerialPort = require("serialport").SerialPort;
var serialPort = new SerialPort('/dev/ttyO2', {
baudrate: 115200,
parser: b.serialParsers.readline("\n")
});
b.pinMode("P9_17", b.OUTPUT);
var countTry =2;
var i = 0; // to loop over the array
var waiting_interval = 3000; // waiting for every slave to reply
var deli;
var slaves = ["S1", "S2" , "S3", "S4", "S5", "S6"];
var counter=[0 , 0 , 0 , 0 ,0 ,0];
var slave_exists = false;
serialPort.on('open',function onSerialOpen(){
console.log("opened");
serialPort.on('data', function listenToSlaves(data){
i--;
if(data.search("END" + slaves[i]) ==0){
console.log("ENDED");
slave_exists = true;
counter[i]=0;
}
else{
// if(data!="END" + slaves[i]){
if(data.search("END" + slaves[i])!==0){
deli = data.indexOf(":");
var parameter = data.substring(0, deli);
var value = data.substring(deli +1);
console.log("parameter is: " + parameter + " - Value is: " + value);
}
}
if(slave_exists){
counter[i] =0;
}
i++;
});
writeToSlaves();
});
function writeToSlaves(){
//If the previous slave (the slave before the one I am sending to
//in the next step doesnt exist, add the counter or consideer
//it not existing)
if(!slave_exists){
counter[i-1]+=1;
if(counter[i-1]>=countTry){
console.log("--------counter[" + i + "]: " + counter[i]);
// in case that the slave returned no data after trying
//to send him several times
console.log(slaves[i-1] + " doesn't exist");
}
}
//sending to the following slave
b.digitalWrite("P9_17", b.HIGH);
serialPort.write(slaves[i], function(){ slave_exists = false;});
b.digitalWrite("P9_17", b.LOW);
console.log("I wrote to slave: " + i);
if(i<slaves.length - 1) i++;
else i=0;
setTimeout(writeToSlaves, waiting_interval);
}
but I am always facing this error:events.js:72
throw er; // Unhandled 'error' event
^
Error: Cannot open /dev/ttyO2
I am running another file first (the code down), the I try to rerun the previous code, and it runs perfect. I need to do that whenever I want to run the first code!
The code that runs from the first time is here:
( I tried the following code alone, it writes to the serial port but doesnt recieve, no event at recieption):
var b = require('bonescript');
var rxport = '/dev/ttyO2';
var txport = '/dev/ttyO2';
var options = { baudrate: 115200, parity: 'even', parser: b.serialParsers.readline('\n') };
var teststring = "This is the string I'm sending out as a test";
b.serialOpen(rxport, options, onRxSerial);
function onRxSerial(x) {
console.log('rx.eventrx= ' + x.event);
if(x.err) throw('***FAIL*** ' + JSON.stringify(x));
if(x.event == 'open') {
//readReapeatedly();
b.serialOpen(txport, options, onTxSerial);
}
if(x.event == 'data') {
console.log("I am receiving on rxport");
console.log('rx (' + x.data.length +
') = ' + x.data.toString('ascii'));
}
}
function onTxSerial(x) {
console.log('tx.event = ' + x.event);
if(x.err) throw('***FAIL*** ' + JSON.stringify(x));
if(x.event == 'open') {
writeRepeatedly();
}
if(x.event == 'data') {
// console.log('tx (' + x.data.length +
// ') = ' + x.data.toString('ascii'));
console.log(x.data);
}
}
function printJSON(x) {
console.log(JSON.stringify(x));
}
function writeRepeatedly() {
console.log("write to serial");
b.serialWrite(txport, teststring, onSerialWrite);
console.log("I have sent data");
}
function onSerialWrite(x) {
console.log("Iam in the onSerialWrite function");
if(x.err) console.log('onSerialWrite err = ' + x.err);
if(x.event == 'callback') {setTimeout(writeRepeatedly, 5000);
console.log("HERE");
}
}
The problem was solved.
In /boot/uboot/uEnv.txt, Update the line:"#cape_enable=capemgr.enable_partno= " to be:
"cape_enable=capemgr.enable_partno=BB-UART1,BB-UART2,BB-UART4, BB-UART5 "
or add the last line to the mentioned file. In some cases, you need to try this line instead of the mentioned:
"optargs=capemgr.enable_partno=BB-UART1,BB-UART2,BB-UART4, BB-UART5" (this is my case - but it disabled the HDMI interface of my BBB).
You can specify the UART you want to enable.
A helpful webpage is here.

how to resolve error SyntaxError: Unexpected comma in array literal (line 27, file "Code")?

I try to run script at google script.
my script is like this
function doGet(e) {
var sourceText = ''
if (e.parameter.q){
sourceText = e.parameter.q;
}
var sourceLang = 'auto';
if (e.parameter.source){
sourceLang = e.parameter.source;
}
var targetLang = 'ja';
if (e.parameter.target){
targetLang = e.parameter.target;
}
/* Option 1 */
var translatedText = LanguageApp.translate(sourceText, sourceLang, targetLang)
/* Option 2 */
var url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl="
+ sourceLang + "&tl=" + targetLang + "&dt=t&q=" + encodeURI(sourceText);
var result = JSON.parse(UrlFetchApp.fetch(url).getContentText());
translatedText = result[0][0][0];
var json = {
'sourceText' : sourceText,
'translatedText' : translatedText
};
// set JSONP callback
var callback = 'callback';
if(e.parameter.callback){
callback = e.parameter.callback
}
// return JSONP
return ContentService
.createTextOutput(callback + '(' + JSON.stringify(json) + ')')
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
when i try to run this script it give error like this:
SyntaxError: Unexpected comma in array literal (line 27, file "Code").
How to resolve this error?
Error line is this:
var result = JSON.parse(UrlFetchApp.fetch(url).getContentText());
The url you entered does not return a valid json, I tried to use your url like this:
https://translate.googleapis.com/translate_a/single?client=gtx&sl=fr&tl=en&dt=t&q=salut
and it gave me that output, which is clearly not a json:
[[["Hello","salut",,,1]],,"fr"]

Extracting image from API

Trying to output an image from an API but I keep getting an error "Empty JSON string"
function getIcon2(id)
{
var api = "http://services.runescape.com/m=itemdb_rs/api/catalogue/detail.json?item=";
var data2 = JSON.parse(UrlFetchApp.fetch(api + id));
return data2.item.icon_large;
}
function iconTest(){
var icon = getIcon2(itemsheet.getRange("C2").getValue());
itemsheet.getRange("D18").setValue(data2);
}
I figured it out.
function getIcon() {
for(var i = 2; i < 500; i++) {
id = itemsheet.getRange("C" + i).getValue()
if(id == "")
return; //If the cell is empty, ignore it.
try {
target = itemsheet.getRange("B" + i);
var api = "http://services.runescape.com/m=itemdb_rs/api/catalogue/detail.json?item=";
var raw = UrlFetchApp.fetch(api + id);
var data = JSON.parse(raw);
formula = "=image(\"" + data.item.icon_large + "\",1)";
target.setFormula(formula);
} catch(err) {
Logger.log("getIcon...." + err)
return;
}
}
}

Which headers do I have to pass on an JavaScript S3 AWS request using signature v4 and assumed role credentials?

I'm trying to make a REST connection to Amazon S3 and I'm struggling to implement the signature V4 process. I know, Amazon also provides a JavasScript an sdk, but I need to get it to work by myself.
To test my code, I'm using the AWS testsuite and my code successfully returns the expected results. However, all my real life attempts fail because of signature does not match error.
The issue for me is, the examples don't include any headers except host and date which is kind of straightforward. I'm having to pass the "full monty" including access tokens and I'm sure there is a problem with the headers.
Here is what I'm doing on click of a button:
function simpleS3Scenario(my_storage) {
return new RSVP.Queue()
.push(function () {
return my_storage.allDocs();
})
.push(function (my_alldocs_response) {
console.log("initial ALLDOCS")
console.log(my_alldocs_response);
})
...
};
allDocs will eventually run into this:
S3Storage.prototype.buildQuery = function (param, options) {
var context = this,
url = this._base_url,
url_path = this._bucket + "/",
headers,
requestText;
return new RSVP.Queue()
.push(function () {
return SigV4_custom.makeSignedRequest(
"GET",
url + url_path,
'',
{"max-key": 100, "prefix": "sample_folder"},
{},
context._region,
"s3",
"AWS4-HMAC-SHA256",
context._secret_access_key,
context._access_key,
context._session_token
);
})
.push(function (e) {
console.log("YUPI");
console.log(e);
})
...
which enters my request signature handler, which is based on this (not working with Signature v4) Amazon example | code: sigv4.js:
(sorry, not shortened yet, scroll down to ENTRY POINT, then work yourself up)
var SigV4_custom = new function(){
this.createCanonicalRequest = function(){};
this.createStringToSign = function(){};
this.generateSignatureAndSign = function(){};
this.makeSignedRequest = function(){};
}
// trim polyfill
String.prototype.trim = String.prototype.trim || function () {
var start = -1,
end = this.length;
while( this.charCodeAt(--end) < 33 );
while( this.charCodeAt(++start) < 33 );
return this.slice( start, end + 1 );
};
// =============== generator funtions =================
// generate query parameter string for canonical request
function generateCanonicalQueryString(my_parameter_dict) {
var canonical_query_string = '',
encoded_parameter_dict = {},
key_list = [],
key,
value,
i,
i_len;
// set and encode
for (key in my_parameter_dict) {
if (my_parameter_dict.hasOwnProperty(key)) {
value = my_parameter_dict[key];
if (typeof value === "object") {
encoded_parameter_dict[encodeURIComponent(key)] =
encodeURIComponent(value[0]) + '&';
// Append each additional value to the query parameter
for (i = 0, i_len = value.length; i < i_len; i += 1) {
encoded_parameter_dict[encodeURIComponent(key)] +=
encodeURIComponent(key) + '=' + encodeURIComponent(value[i]) +'&';
}
encoded_parameter_dict[encodeURIComponent(key)] =
encoded_parameter_dict[encodeURIComponent(key)].slice(0,-1);
} else {
encoded_parameter_dict[encodeURIComponent(key)] =
encodeURIComponent(value);
}
}
}
// then fill key_list
for (key in encoded_parameter_dict) {
if (encoded_parameter_dict.hasOwnProperty(key)) {
key_list.push(key);
}
}
key_list.sort();
for (i = 0, i_len = key_list.length; i < i_len; i += 1) {
canonical_query_string +=
key_list[i] + "=" + encoded_parameter_dict[key_list[i]] + "&";
}
return canonical_query_string.slice(0, -1);
}
// generate canonical header string
function generateCanonicalHeaderString(my_header_dict, is_signature) {
var canonical_header_string = '',
encoded_header_dict = {},
header_list = [],
header,
value,
trimmed_value,
header_lowercase,
i,
i_len,
separator,
connector,
format,
cutoff;
if (is_signature) {
cutoff = -1;
separator = ":";
connector = "\n";
format = function (my_value) {
return my_value.toLowerCase();
}
} else {
cutoff = -1;
separator = "=";
connector = "&";
format = function (my_value) {
return my_value;
}
}
// Take header keys and put in array, then sort and build
for (header in my_header_dict) {
if (my_header_dict.hasOwnProperty(header)) {
header_lowercase = format(header);
value = my_header_dict[header];
trimmed_value = undefined;
//XXX there are not only strings in the headers...
if (value.trim) {
trimmed_value = value.trim();
}
if (encoded_header_dict[header_lowercase] === undefined) {
encoded_header_dict[header_lowercase] = trimmed_value || value;
header_list.push(header_lowercase);
} else {
encoded_header_dict[header_lowercase] += "," + trimmed_value || value;
}
}
}
header_list.sort();
for (i = 0, i_len = header_list.length; i < i_len; i += 1) {
canonical_header_string +=
header_list[i] +
separator +
encoded_header_dict[header_list[i]] +
connector;
}
canonical_header_string = canonical_header_string.slice(0, cutoff);
return canonical_header_string;
}
// generate the signed header string
function generateSignedHeaderString(my_header_dict) {
var signed_header_string = '',
header_list = [],
header,
header_lowercase,
i,
i_len;
for (header in my_header_dict) {
if (my_header_dict.hasOwnProperty(header)) {
header_list.push(header.toLowerCase());
}
}
header_list.sort();
for (i = 0, i_len = header_list.length; i < i_len; i += 1) {
signed_header_string += header_list[i] + ';';
}
return signed_header_string.slice(0, -1);
}
// returns a timestamp in the YYYYMMDD'T'HHmmSS'Z' format, for SigV4 calls
function generateTimestamp() {
var date = new Date();
function bump(my_time_parameter) {
if (my_time_parameter.length === 1) {
return '0' + my_time_parameter;
}
return my_time_parameter;
}
// Assemble date, bump single digits to doubles
// validation: return "20130524T000000Z";
return date.getUTCFullYear() +
bump((date.getUTCMonth()+1).toString()) + // month
bump(date.getUTCDate().toString()) + // day
'T' +
bump(date.getUTCHours().toString()) + // hour
bump(date.getUTCMinutes().toString()) + // minute
bump(date.getUTCSeconds().toString()) + // second
'Z';
}
// generate the credential scope
function generateCredentialScope(my_timestamp, my_region, my_service) {
return my_timestamp.substring(0, 8) + "/" +
my_region + "/" +
my_service + "/" +
"aws4_request";
}
// ================== CORE methods ==================
SigV4_custom.createStringToSign = function (request_time, credential_scope,
canonical_request, signing_algorithm) {
// Step 1: designate the algorithm (for SigV4 it is SHA256)
// Step 2: designate the RequestDate (already done, passed to function)
// Step 3: create credentialScope (already done, passed to funtion)
return signing_algorithm + '\n' +
request_time + '\n' +
credential_scope + '\n' +
canonical_request;
}
SigV4_custom.generateSignatureAndSign = function(secret, request_time, region,
service, string_to_sign) {
var datestamp = request_time.substring(0, 8),
hash_date,
hash_region,
hash_service,
hash_signing,
request = 'aws4_request';
hash_date = CryptoJS.HmacSHA256(datestamp, 'AWS4' + secret, {asBytes: true});
hash_region = CryptoJS.HmacSHA256(region, hash_date, {asBytes: true});
hash_service = CryptoJS.HmacSHA256(service, hash_region, {asBytes: true});
hash_signing = CryptoJS.HmacSHA256(request, hash_service, {asBytes: true});
// sign and return
return CryptoJS.HmacSHA256(string_to_sign, hash_signing)
.toString(CryptoJS.enc.Hex);
}
SigV4_custom.createCanonicalRequest = function(method, pathname,
parameter_dict, header_dict, hashed_payload) {
var canonical_request = "",
http_request_method = "",
canonical_url = "",
canonical_query_string = "",
canonical_header_string = "",
signed_header_string = "",
payload;
// Step 1: Start with the HTTP request method
http_request_method = method;
// Step 2: Add the canonicalUrl parameter
canonical_url = pathname;
// Step 3: Add the canonicalQueryString parameter
canonical_query_string = generateCanonicalQueryString(parameter_dict);
// Step 4: Add the canonicalHeaders parameter
canonical_header_string = generateCanonicalHeaderString(header_dict, true);
// Step 5: Add the signedHeaders parameter
signed_header_string = generateSignedHeaderString(header_dict);
// Step 6: Add the hashed payload
payload = hashed_payload;
// Step 7: string together the canonicalRequest from steps 1 through 6
canonical_request += http_request_method + '\n' +
canonical_url + '\n' +
canonical_query_string + '\n' +
canonical_header_string + '\n\n' +
signed_header_string + '\n' +
payload;
return canonical_request;
};
// =================== ENTRY POINT ===================
// Call this function to make a SigV4 REST API call.
SigV4_custom.makeSignedRequest = function (method, path, payload,
parameter_dict, header_dict, region, service, signing_algorithm,
secret_access_key, access_key_id, security_token) {
var link = document.createElement("a"),
request_time = generateTimestamp(),
scope = generateCredentialScope(request_time, region, service),
authorization_string,
canonical_request,
string_to_sign,
request_uri,
signature;
// link is a location object, set its href to use its properties
link.href = path;
// set all headers, then generate a canonical_request
// payload must be hashed here, as this may vary and the hash is required
// for canonization and as a header. Empty payloads will hash an empty "".
header_dict['X-Amz-Content-Sha256'] = CryptoJS.SHA256(payload)
.toString(CryptoJS.enc.Hex);
header_dict['host'] = link.hostname;
header_dict['X-Amz-Date'] = request_time;
header_dict['X-Amz-Credential'] = access_key_id + "/" + scope;
header_dict['X-Amz-Security-Token'] = security_token;
header_dict['X-Amz-Algorithm'] = signing_algorithm;
header_dict['X-Amz-Expires'] = 86400;
// Task 1: Compute the canonical request
canonical_request = CryptoJS.SHA256(
this.createCanonicalRequest(
method,
link.pathname,
parameter_dict,
header_dict,
header_dict['X-Amz-Content-Sha256']
)
)
.toString(CryptoJS.enc.Hex);
// delete host because it is also in the headers (needs to be in both
// initially to create the canonicalization)
delete parameter_dict['host'];
// Task 2: Create the string to sign using the encoded canonical request
string_to_sign = this.createStringToSign(
request_time,
scope,
canonical_request,
signing_algorithm
);
// Task 3: Create the signature using the signing key and the string to sign
signature = this.generateSignatureAndSign(
secret_access_key,
request_time,
region,
service,
string_to_sign
);
// Task 4: Build the authorization header
header_dict['Authorization'] = header_dict['X-Amz-Algorithm'] +
" Credential=" + header_dict['X-Amz-Credential'] + "," +
"SignedHeaders=" + generateSignedHeaderString(header_dict) + "," +
"Signature=" + signature;
// Task 5: Make the request (through jIO)
return new RSVP.Queue()
.push(function () {
return jIO.util.ajax({
"method": method,
"url": path,
"headers": header_dict
});
});
}
So when I run the Amazon samples with just two headers through this, I get correct signature and authorization header at the end. I believe I'm doing something wrong with the headers, especially which headers should go into the signature, but I can't find any good help online and am stuck on this for a few days now.
Question:
Maybe someone has an idea from looking at how I'm handling the headers, why my requests to AWS fail due to non-matching signature?
THANKS!
Edit:
I have used this Amazon Example page for deriving signatures. If I run the sample inputs through my createSignatureAndSign method, I can produce the same outputs. So my signature is correct an secret are correct.

Categories