Openshift 3.X with Websockets - websocket

I'm trying to host a websocket-application op Openshift 3, but I have running into some issues.
Code at the backend:
templatePath = os.path.join(os.path.dirname(__file__), "templates")
staticPath = os.path.join(os.path.dirname(__file__), "static")
settings = {
"template_path": templatePath,
"static_path": staticPath,
"debug" : True
}
application = web.Application([
(r'/ws', WSHandler),
(r'/', MainHandler, {"staticFilesPath":staticPath}),
(r"/(.*)", tornado.web.StaticFileHandler, {'path': staticPath}),
],**settings)
class WSHandler(tornado.websocket.WebSocketHandler):
def initialize(self, messageHandler):
print 'Initializing MessageHandler'
self.messageHandler = messageHandler
def check_origin(self,origin):
return True
def open(self):
print 'Connection received'
def on_message(self, message):
message = simplejson.loads(message)
print 'received message of type "' + message['type'] + '"'
outputMessage = {'type': 'Hello', 'data': 'World'}
self.sendMessage(outputMessage)
def on_close(self):
print 'Connection closed'
class MainHandler(tornado.web.RequestHandler):
def initialize(self, staticFilesPath):
self.staticFilesPath = staticFilesPath
def get(self):
print 'New connection'
webClientHtml = os.path.join(self.staticFilesPath,'index.html')
loader = tornado.template.Loader(".")
self.write(loader.load(webClientHtml).generate())
At the frontend:
var hostname = window.document.location.hostname;
var host = "ws://" + hostname + ":8000/ws";
var ws = new WebSocket(host);
This leads to ERR_CONNECTION_TIMED_OUT. I know the port 8000 had to be specified in Openshift 2. The documentation I could find about websocket-ports op Openshift 3 seems to suggest this is no longer necessary, but I can't figure out what to use. I have tried 80 and not specifying a port, but neither works.
Does anybody know what I'm doing wrong?

Related

socket disconnect and connect after some time python

I am working on a project, using WSGI server. My connect agents and users disconnected and again connected after some time with new sid (session IDs). Which is creating a problem. I need same sid throughout the user interaction on the web. And are eventlet used for?
New to sockets need help on this issue.
here is my code:
import socketio
import os
from dotenv import load_dotenv
import jwt
from Controllers.DatabaseController import DBController
DBHandler = DBController()
load_dotenv()
private_key = os.getenv('PRIVATE_KEY')
# headers = {'Authorization': private_key}4
sio = socketio.Server(ping_interval=25,ping_timeout=55)
app = socketio.WSGIApp(sio, static_files={
'/': './public/'
})
agents = {}
users = {}
total_agents = 0
def add_agents(sid, First_Name, Last_Name):
global total_agents
if (total_agents >= 0):
total_agents += 1
agents[sid] = {
'Type': 'Agent',
'First_Name': First_Name,
'Last_Name': Last_Name,
'Data': {}
}
return agents
def add_users(sid):
global total_users
if (total_users >= 0):
total_users += 1
users[total_users] = {
sid: {
'Data': ''
}
}
return agents
#sio.event
def connect(sid, environ):
global agents
token = environ.get('HTTP_X_USERNAME')
print(token)
if not token:
print(sid, 'connected')
return True
try:
user_session_data = jwt.decode(token, private_key, algorithms='HS256')
# if user_session_data is False:
# with sio.session(sid) as session:
# session['username'] = token
# sio.emit('user_joined', 1)
# print(sid, 'connected')
# users_list = add_users(sid)
# print(users_list)
#
# print(user_session_data)
result, colnames = DBHandler.GetAgentData(user_session_data['user'])
if result is not False:
First_Name = result[0][0]
Last_Name = result[0][1]
Username = result[0][2]
with sio.session(sid) as session:
session['username'] = token
#sio.emit(Username, 1)
print(sid, 'connected')
agents_list = add_agents(sid, First_Name, Last_Name)
sio.enter_room(sid, 'agents')
print(agents_list)
except Exception as e:
print(e)
print("wrong token ")
return False
#sio.event
def disconnect(sid):
print(sid, 'disconnected')
sio.leave_room(sid, 'agents')
del agents[sid]
#sio.event
def request_call(sid):
sio.emit('call_request', {'sid': sid}, room='agents')
#sio.event
def accept_call(sid):
sio.emit('call_accepted', {'sid': sid}, to=sid)

Configuration of IBMMQ with JMeter

I am doing an IBM WebSphere MQ testing using JMeter. I have created the JSR223 sampler script based on the following reference link https://www.blazemeter.com/blog/ibm-mq-testing-with-jmeter-learn-how. Here i am using only one queue name(request) to inject my request into IBM MQ server.
But in my cases, i have to retrieve my response using different query name.
Example :
Request_queryname : DNB.LX.SRXX.LOGGING.IN
Response_queryname : DNB.LX.SRXX.LOGGING.OUT
So if i am passing my request using this query name "DNB.LX.SRXX.LOGGING.IN", i need to retrive my response with another query name "DNB.LX.SRXX.LOGGING.OUT".
May i know how to retrieve this response. I am having following parameters with me.
QueueManager : CLDACESP
Channelname : ACE.CONFIG.SXXCONN
Hostname : 172.25.XX.XX
Host port : 1414
queue name(request) :DNB.LX.SRXX.LOGGING.IN
queue name(response) :DNB.LX.SRXX.LOGGING.OUT
Just create a new session pointing to another queue, all you need to do is to duplicate the code and change the queue name.
I.e.
Producer:
import com.ibm.msg.client.jms.JmsFactoryFactory
import com.ibm.msg.client.wmq.WMQConstants
import javax.jms.Session
def hostName = "172.25.XX.XX"
def hostPort = 1414
def channelName = "DEV.APP.SVRCONN"
def queueManagerName = "QM1"
def queueName = "DNB.LX.SRXX.LOGGING.IN"
def ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER)
def cf = ff.createConnectionFactory()
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, hostName)
cf.setIntProperty(WMQConstants.WMQ_PORT, hostPort)
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channelName)
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT)
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, queueManagerName)
def conn = cf.createConnection("app", "test")
def sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE)
def destination = sess.createQueue(queueName)
conn.start()
def producer = sess.createProducer(destination)
def rnd = new Random(System.currentTimeMillis())
def payload = String.format("JMeter...IBM MQ...test message no. %09d!", rnd.nextInt(Integer.MAX_VALUE))
def msg = sess.createTextMessage(payload)
producer.send(msg)
producer.close()
Consumer:
import com.ibm.msg.client.jms.JmsFactoryFactory
import com.ibm.msg.client.wmq.WMQConstants
import javax.jms.Session
def hostName = "172.25.XX.XX"
def hostPort = 1414
def channelName = "DEV.APP.SVRCONN"
def queueManagerName = "QM1"
def queueName = "DNB.LX.SRXX.LOGGING.OUT"
def ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER)
def cf = ff.createConnectionFactory()
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, hostName)
cf.setIntProperty(WMQConstants.WMQ_PORT, hostPort)
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channelName)
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT)
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, queueManagerName)
def conn = cf.createConnection("app", "test")
def sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE)
conn.start()
def consumer = sess.createConsumer(destination)
def msg = consumer.receive(1)
//do what you need with this message(s)
consumer.close()
More information:
IBMMQ Classes for JMS
Apache Groovy - Why and How You Should Use It

Error Implementing free dictionary Api in discord.py

I am trying to implement this api but the code says error every single time.
My code so far:
#client.command()
async def mean(ctx,word):
response = requests.get(f"https://api.dictionaryapi.dev/api/v2/entries/en/{word}")
if response.status_code == 404:
await ctx.send("No such word")
return
else:
wordx = response.json()
the_dictionary = wordx[0]
meanings = the_dictionary['meanings']
definitions = meanings[0]
definition = definitions['definitions']
meaningg = definition[0]
meaning = meaningg['definition']
example = meaningg.get('example',['None'])
synonymslist = meaningg.get("synonyms",['None'])
if isinstance(synonymslist,str):
synonymslist = [synonymslist]
pass
synonyms = ','.join(synonymslist)
deffinal= discord.Embed(title=f"`{word.upper()}`")
deffinal.add_field(name = "Definition", value=f"{meaning}")
deffinal.add_field(name = 'Example', value = f"{example}")
deffinal.add_field(name = "Synonyms", value = f"{synonyms}")
await ctx.channel.send(embed = deffinal)
Here is the error message:
Your error does not come from the API call to the dictionary api, but rather from your call to the discord api.
The error message says discord.errors.HTTPException: [...] In embed.fields.2.value: This field is required.
So the error comes from an empty field in your embed! The field has index 2 so it is actually the third field (Synonyms) which is causing the problem.
You can simply check if a string is empty, before even adding the field. And if it is empty, just don't add it.
deffinal= discord.Embed(title=f"`{word.upper()}`")
if meaning:
deffinal.add_field(name = "Definition", value=f"{meaning}")
if example:
deffinal.add_field(name = 'Example', value = f"{example}")
if synonyms:
deffinal.add_field(name = "Synonyms", value = f"{synonyms}")
#client.command()
async def mean(ctx,word):
response = requests.get(f"https://api.dictionaryapi.dev/api/v2/entries/en/{word}")
if response.status_code == 404:
await ctx.send("No such word")
return
else:
wordx = response.json()
the_dictionary = wordx[0]
meanings = the_dictionary['meanings']
definitions = meanings[0]
definition = definitions['definitions']
meaningg = definition[0]
meaning = meaningg['definition']
example = meaningg.get('example',['None'])
synonymslist = meaningg.get("synonyms",['None'])
if isinstance(synonymslist,str):
synonymslist = [synonymslist]
pass
synonyms = ','.join(synonymslist)
deffinal= discord.Embed(title=f"`{word.upper()}`")
if meaning:
deffinal.add_field(name = "Definition", value=f"{meaning}")
if example:
deffinal.add_field(name = 'Example', value = f"{example}")
if synonyms:
deffinal.add_field(name = "Synonyms", value = f"{synonyms}")
await ctx.channel.send(embed = deffinal)
Adding to itzFlubby answer, using requests will be blocking read more which means if you block for too long then your bot will freeze since it has not stopped the function’s execution at that point to do other things.
Here is the final code, also I changed the format a bit to make it easier to read.
# import aiohttp
#bot.command()
async def mean(ctx, word):
async with aiohttp.ClientSession() as session:
async with session.get(f"https://api.dictionaryapi.dev/api/v2/entries/en/{word}") as r:
if r.status == 200:
info = await r.json()
else:
return await ctx.reply("No such word")
the_dictionary = info[0]['meanings'][0]['definitions'][0]
definition = the_dictionary.get('definition')
example = the_dictionary.get('example')
synonymslist = the_dictionary.get("synonyms")
# if only one synonym is avaliable
if isinstance(synonymslist, str):
synonymslist = [synonymslist]
synonyms = '\n'.join(synonymslist)
deffinal = discord.Embed(title=f"`{word.upper()}`")
if definition:
deffinal.add_field(name="Definition", value=f"```{definition}```")
if example:
deffinal.add_field(name='Example', value=f"```{example}```")
if synonyms:
deffinal.add_field(name="Synonyms", value=f"```{synonyms}```")
await ctx.reply(embed=deffinal)

Need assistance with creating a Git client-side 'commit-msg' hook

I have installed the 'ticket_status.rb' server-side hook on Assembla. Although this is exactly what I'm looking for (in theory), it does not flag until the developer attempts to push to the server. If they have made several commits before pushing, it becomes incredibly frustrating to go back through their history and edit any invalid commit messages.
I am looking to create a client-side hook that will reject a developer's commit if an open ticket in Assembla is not referenced in the commit message. I assume that since it is client-side, it will not be able to check if the ticket is open in the Assembla project space. However, if the hook could at least check that '#n' has been included in the commit message (where 0 < n < 10,000), it should catch the majority of invalid commit messages.
GitHub has provided sample code for a client-side 'commit-msg' hook. I would like assistance in modifying the code below to instead search for a ticket number (#n) in the commit message (or an open ticket in the Assembla project space, if possible):
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message. The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit. The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".
# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
# This example catches duplicate Signed-off-by lines.
test "" = "$(grep '^Signed-off-by: ' "$1" |
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
echo >&2 Duplicate Signed-off-by lines.
exit 1
}
I have also provided the source code for the server-side hook that rejects the commit if it does not contain a valid open ticket number in the commit message (ticket_status.rb):
#!/usr/bin/env ruby
# -*- encoding : utf-8 -*-
#
# Reject a push to a branch if it has commits that do refer a ticket in open state
#
# ref = ARGV[0]
sha_start = ARGV[1]
sha_end = ARGV[2]
# HOOK PARAMS
space = 'space-wiki-name'
api_key = 'user-api-key'
api_secret = 'user-api-secret'
# HOOK START, end of params block
require "net/https"
require "uri"
begin
require "json"
rescue LoadError
require 'rubygems'
require 'json'
end
# Check referred tickets that are in open stage
class TicketValidator
API_URL = "https://api.assembla.com"
attr_accessor :space, :api_key, :api_secret
def initialize()
#ticket_statuses = []
#tickets = {}
end
def init
init_http
load_statuses
end
def check(sha, comment)
comment.to_s.scan(/#\d+/).each do |t|
ticket = t.tr('#', '')
# Do not check it twice
next if #tickets[ticket]
ticket_js = api_call "/v1/spaces/#{space}/tickets/#{ticket}.json"
error = nil
if ticket_js['error'].nil?
unless #ticket_statuses.include? ticket_js['status'].downcase
error = "Ticket #{t} is not open!"
end
else
error = ticket_js['error']
end
if error
#tickets[ticket] = {:error => error, :sha => sha}
else
#tickets[ticket] = :ok
end
end
end
def load_statuses
statuses = api_call "/v1/spaces/#{space}/tickets/statuses.json"
statuses.each do |status|
if status["state"] == 1 # open
#ticket_statuses << status["name"].downcase
end
end
end
def api_call(uri)
request = Net::HTTP::Get.new(uri,
{'Content-Type' => 'application/json',
'X-Api-Key' => api_key,
'X-Api-Secret' => api_secret})
result = #http.request(request)
JSON.parse(result.body)
end
def init_http
uri = URI.parse(API_URL)
#http = Net::HTTP.new(uri.host, uri.port)
#http.use_ssl = true
#http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
def show_decision!
#tickets.reject! {|_, value| value == :ok }
unless #tickets.empty?
puts "You have references to tickets in closed state"
#tickets.each do |ticket, details|
puts "\t#{details[:sha]} - ##{ticket} #{details[:error]}"
end
puts "Valid statuses: #{#ticket_statuses.join(', ')}"
exit 1
end
end
end
class Parser
def initialize(text, validator)
#text = text
#validator = validator
end
def parse
commit = nil
comment = nil
#validator.init
#text.to_s.split("\n").each do |line|
if line =~ /^commit: ([a-z0-9]+)$/i
new_commit = $1
if comment
#validator.check(commit, comment)
comment = nil
end
commit = new_commit
else
comment = comment.to_s + line + "\n"
end
end
# Check last commit
#validator.check(commit, comment) if comment
end
end
text = `git log --pretty='format:commit: %h%n%B' #{sha_start}..#{sha_end}`
#validator = TicketValidator.new
#validator.space = space
#validator.api_key = api_key
#validator.api_secret = api_secret
Parser.new(text, #validator).parse
#validator.show_decision!
Any help is much appreciated. Thanks
You can try this commit-msg validator. It's not ruby but you can easily configure it for your needs and you can even write your own Assembla reference to validate ticket numbers against their API. See the repo README for more details.
Here is a starting point for your custom reference, and its associated test file. I haven't tested it thoroughly but it should be pretty easy to change as you wish, since it's basically JavaScript.
lib/references/assembla.js
'use strict';
var exec = require('child_process').exec;
var https = require('https');
var util = require('util');
// HOOK PARAMS
var space = 'space-wiki-name';
var apiKey = 'user-api-key';
var apiSecret = 'user-api-secret';
function Ticket(ticket, match) {
this.allowInSubject = true;
this.match = match;
this._ticket = ticket;
}
Ticket.prototype.toString = function() {
return '#' + this._ticket;
}
Ticket.prototype.isValid = function(cb) {
var options = {
hostname: 'api.assembla.com',
path: util.format('/v1/spaces/%s/tickets/%s.json', space, this._ticket),
headers: {
'Content-Type' : 'application/json',
'X-Api-Key' : apiKey,
'X-Api-Secret' : apiSecret
}
};
https.get(options, function(res) {
if (res.statusCode === 404) {
return cb(null, false); // invalid
}
var body = '';
res.on('data', function(chunk) {
body += chunk.toString();
});
res.on('end', function () {
var response = body ? JSON.parse(body) : false;
if (res.statusCode < 300 && response) {
return cb(null, true); // valid?
}
console.error('warning: Reference check failed with status code %d',
res.statusCode,
response && response.message ? ('; reason: ' + response.message) : '');
cb(null, false); // request errored out?
});
});
}
// Fake class that requires the existence of a ticket # in every commit
function TicketRequired() {
Ticket.call(this);
this.error = new Error('Commit should include an Assembla ticket #');
}
util.inherits(TicketRequired, Ticket);
TicketRequired.prototype.isValid = function(cb) {
cb(null, false);
}
Ticket.parse = function(text) {
var instances = [];
var cb = function(match, ticket) {
instances.push( new Ticket(ticket, match) );
};
text.replace(/#(-?\d+)\b/gi, cb);
if (!instances.length) {
// maybe should skip merge commits here
instances.push(new TicketRequired());
}
return instances;
}
module.exports = Ticket;
test/references/assembla.js
'use strict';
var assert = require('assert');
var Ticket = require('../../lib/references/assembla');
describe('references/assembla', function() {
it('should validate correctly using the API', function(done) {
this.timeout(5000); // allow enough time
var tickets = Ticket.parse('Change functionality\n\nFixes #13 and #9999 (invalid)');
var ct = 0;
var checkDone = function() {
if (++ct == tickets.length) done();
};
var valid = [true, false];
valid.forEach(function(val, idx) {
tickets[idx].isValid(function(err, valid) {
assert.equal(valid, val, tickets[idx].toString());
checkDone();
});
});
});
it('should require a ticket #', function() {
var tickets = Ticket.parse('Commit message without any ticket ref #');
assert.equal(tickets.length, 1);
assert.equal(tickets[0].error.message, 'Commit should include an Assembla ticket #');
});
});

Unable to produce Proper Encryption Key in Ruby using HMAC

I am attempting to follow the documentation per Access Control and interrogating code like azure-documentdb-node SDK and I am unable to do so.
I get the following error: 401 Unauthorized: {"code":"Unauthorized","message":"The input authorization token can't serve the request. Please check that the expected payload is built as per the protocol, and check the key being used. Server used the following payload to sign: 'post\ndbs\n\n13 april 2015 18:21:05 gmt\n\n'\r\nActivityId: ...
My ruby code looks like the following:
require 'openssl'
require 'rest-client'
require 'base64'
require 'uri'
require 'json'
require 'time'
def get_databases url, master_key
time = Time.now.httpdate
authorization = get_master_auth_token "get", "", "dbs", time, master_key
header = { "authorization" => authorization, "x-ms-date" => time, "x-ms-version" => "2015-04-08" }
RestClient.get url, header
end
def get_master_auth_token verb, resource_id, resource_type, date, master_key
digest = OpenSSL::Digest::SHA256.new
key = Base64.decode64 master_key
text = verb + "\n" +
resource_type + "\n" +
resource_id + "\n" +
date + "\n" +
"\n"
hmac = OpenSSL::HMAC.digest digest, key, text.downcase
auth_string = "type=" + "master" + "&ver=" + "1.0" + "&sig=" + hmac
URI.escape auth_string
end
Thanks!
EDIT: After Ryan's advice and example I've simplified the code down to the following snippit that should be a match for the node code he has posted BUT it still fails in ruby:
def hard_coded_get_databases master_key, url
verb = "get"
resource_type = "dbs"
resource_id = ""
date = Time.now.httpdate
serv_version = '2014-08-21'
master_token = "master"
token_version = "1.0"
key = Base64.decode64 master_key
text = verb + "\n" + resource_type + "\n" + resource_id + "\n" + date + "\n\n"
body = text.downcase.force_encoding "utf-8"
signature = OpenSSL::HMAC.digest OpenSSL::Digest::SHA256.new, key, body
auth_token = URI.escape("type="+master_token + "&ver="+token_version + "&sig="+signature)
header = { "accept" => "application/json", "x-ms-version" => serv_version, "x-ms-date" => date, "authorization" => auth_token }
RestClient.get url, header
end
EDIT2: I believe I've isolated the problem to how I am doing the master key authentication.
Taking Ryan's example we can trim his node code down the following:
var crypto = require("crypto")
function encode_message(masterKey, message) {
var key = new Buffer(masterKey, "base64"); // encode/decode? base64 the masterKey
var body = new Buffer(message.toLowerCase(), "utf8"); // convert message to "utf8" and lower case
return crypto.createHmac("sha256", key).update(body).digest("base64"); // encrypt the message using key
}
If I call this node code I can produce the following key:
encode_message("blah", 'get\ncolls\n\nTue, 14 Apr 2015 13:34:22 GMT\n\n')
'IYlLuyZtVLx5ANkGMAxviDHgC/DJJXSj1gUGLvN0oM8='
If I produce the equivalent ruby code to create the authentication my ruby code looks like the following:
require 'base64'
require 'openssl'
def encode_message master_key, message
key = Base64.urlsafe_decode64 master_key
hmac = OpenSSL::HMAC.digest 'sha256', key, message
Base64.urlsafe_encode64 hmac
end
If I call this code I get the following:
2.2.1 :021 > encode_message("blah", "get\ncolls\n\nTue, 14 Apr 2015 13:34:22 GMT\n\n")
=> "N6BL3n4eSvYA8dIL1KzlTIvR3TcYpdqW2UNPtKWrjP8="
Clearly the 2 encoded auth tokens are not the same. (Ryan again thanks so much for the help to get this far).
I have found the answer. Thanks to Magnus Stahre ... he is the man for helping me figure it out.
It was the encoding as I thought and the trick is this:
def encode_message master_key, message
key = Base64.urlsafe_decode64 master_key
hmac = OpenSSL::HMAC.digest 'sha256', key, message.downcase
Base64.encode64(hmac).strip
end
I was downcasing in my code too early AND my Base64.encode64 was failing to strip away a newline character that ruby was adding on the end.
i'll start off by apologizing for my limited Ruby knowledge but let me try assist here;
in your get_master_auth_token function it appears you are decoding the key before using it. is this correct? if so, why?
here is a node.js sample that uses the master key, builds up the auth header value and does a simple http call to list the collections in a database
var crypto = require("crypto");
var https = require("https");
https.globalAgent.options.secureProtocol = "TLSv1_client_method";
var verb = 'get';
var resourceType = 'dbs'; //the resource you are trying to get. dbs, colls, docs etc.
var resourceId = ''; //the parent resource id. note: not the id, but the _rid. but for you, because you are trying to lookup list of databases there is no parent
var masterKey = '...'; //your masterkey
var date = new Date().toUTCString();
var auth = getAuthorizationTokenUsingMasterKey(verb, resourceId, resourceType, date, masterKey);
var options = {
hostname: '...', //your hostname (without https://)
port: 443,
path: '/dbs/',
method: 'GET',
headers: {
accept: 'application/json',
'x-ms-version': '2014-08-21',
'x-ms-date': date,
authorization: auth,
}
};
for (var i = 0; i < 1000; i++) {
var req = https.request(options, function (res) {
process.stdout.write(new Date().toUTCString() + " - statusCode: " + res.statusCode + "\n");
res.on('data', function (d) {
}).on('error', function (e) {
})
});
//console.log(req);
req.end();
}
function getAuthorizationTokenUsingMasterKey(verb, resourceId, resourceType, date, masterKey) {
var key = new Buffer(masterKey, "base64");
var text = (verb || "") + "\n" +
(resourceType || "") + "\n" +
(resourceId || "") + "\n" +
(date || "") + "\n" +
("") + "\n";
var body = new Buffer(text.toLowerCase(), "utf8");
var signature = crypto.createHmac("sha256", key).update(body).digest("base64");
var MasterToken = "master";
var TokenVersion = "1.0";
return encodeURIComponent("type=" + MasterToken + "&ver=" + TokenVersion + "&sig=" + signature);
}
In your example, the resourceId passed to the getAuthorizationTokenUsingMasterKey method should be "" and the resourceType should be "dbs" as you have it.
I did notice that in some cases you have to URI Encode the value, but I think you are doing that already as the very last line of the func.
the only difference I can spot in your code vs my code is that you appear to be decoding the master_key which I don't do.
what I would recommend you do is run this node sample and compare the values of the strings we have in body & signature to the your values. they need to match.

Resources