Bugfix/http redirect to ws (#211)

* allow redirect to ws(s) url after starting with http(s) #210

* further fixes for #210
This commit is contained in:
Dave Horton
2023-01-07 15:00:18 -05:00
committed by GitHub
parent 2e3fb60e72
commit 0c52324915
3 changed files with 27 additions and 6 deletions

View File

@@ -82,12 +82,18 @@ class CallSession extends Emitter {
this._pool = srf.locals.dbHelpers.pool; this._pool = srf.locals.dbHelpers.pool;
const handover = (newRequestor) => {
this.logger.info(`handover to new base url ${newRequestor.url}`);
this.requestor.removeAllListeners();
this.application.requestor = newRequestor;
this.requestor.on('command', this._onCommand.bind(this));
this.requestor.on('connection-dropped', this._onWsConnectionDropped.bind(this));
this.requestor.on('handover', handover.bind(this));
};
this.requestor.on('command', this._onCommand.bind(this)); this.requestor.on('command', this._onCommand.bind(this));
this.requestor.on('connection-dropped', this._onWsConnectionDropped.bind(this)); this.requestor.on('connection-dropped', this._onWsConnectionDropped.bind(this));
this.requestor.on('handover', (newRequestor) => { this.requestor.on('handover', handover.bind(this));
this.logger.info(`handover to new base url ${newRequestor.url}`);
this.application.requestor = newRequestor;
});
} }
/** /**

View File

@@ -5,6 +5,7 @@ const assert = require('assert');
const {TaskPreconditions} = require('../utils/constants'); const {TaskPreconditions} = require('../utils/constants');
const normalizeJambones = require('../utils/normalize-jambones'); const normalizeJambones = require('../utils/normalize-jambones');
const WsRequestor = require('../utils/ws-requestor'); const WsRequestor = require('../utils/ws-requestor');
const {TaskName} = require('../utils/constants');
const {trace} = require('@opentelemetry/api'); const {trace} = require('@opentelemetry/api');
const specs = new Map(); const specs = new Map();
const _specData = require('./specs'); const _specData = require('./specs');
@@ -157,13 +158,14 @@ class Task extends Emitter {
async performAction(results, expectResponse = true) { async performAction(results, expectResponse = true) {
if (this.actionHook) { if (this.actionHook) {
const type = this.name === TaskName.Redirect ? 'session:redirect' : 'verb:hook';
const params = results ? Object.assign(this.cs.callInfo.toJSON(), results) : this.cs.callInfo.toJSON(); const params = results ? Object.assign(this.cs.callInfo.toJSON(), results) : this.cs.callInfo.toJSON();
const span = this.startSpan('verb:hook', {'hook.url': this.actionHook}); const span = this.startSpan(type, {'hook.url': this.actionHook});
const b3 = this.getTracingPropagation('b3', span); const b3 = this.getTracingPropagation('b3', span);
const httpHeaders = b3 && {b3}; const httpHeaders = b3 && {b3};
span.setAttributes({'http.body': JSON.stringify(params)}); span.setAttributes({'http.body': JSON.stringify(params)});
try { try {
const json = await this.cs.requestor.request('verb:hook', this.actionHook, params, httpHeaders); const json = await this.cs.requestor.request(type, this.actionHook, params, httpHeaders);
span.setAttributes({'http.statusCode': 200}); span.setAttributes({'http.statusCode': 200});
span.end(); span.end();
if (expectResponse && json && Array.isArray(json)) { if (expectResponse && json && Array.isArray(json)) {

View File

@@ -2,6 +2,7 @@ const {Client, Pool} = require('undici');
const parseUrl = require('parse-url'); const parseUrl = require('parse-url');
const assert = require('assert'); const assert = require('assert');
const BaseRequestor = require('./base-requestor'); const BaseRequestor = require('./base-requestor');
const WsRequestor = require('./ws-requestor');
const {HookMsgTypes} = require('./constants.json'); const {HookMsgTypes} = require('./constants.json');
const snakeCaseKeys = require('./snakecase-keys'); const snakeCaseKeys = require('./snakecase-keys');
const pools = new Map(); const pools = new Map();
@@ -91,6 +92,18 @@ class HttpRequestor extends BaseRequestor {
assert.ok, (['GET', 'POST'].includes(method), `HttpRequestor:request method must be 'GET' or 'POST' not ${method}`); assert.ok, (['GET', 'POST'].includes(method), `HttpRequestor:request method must be 'GET' or 'POST' not ${method}`);
const startAt = process.hrtime(); const startAt = process.hrtime();
/* if we have an absolute url, and it is ws then do a websocket connection */
if (this._isAbsoluteUrl(url) && url.startsWith('ws')) {
this.logger.debug({hook}, 'HttpRequestor: switching to websocket connection');
const h = typeof hook === 'object' ? hook : {url: hook};
const requestor = new WsRequestor(this.logger, this.account_sid, h, this.secret);
if (type === 'session:redirect') {
this.close();
this.emit('handover', requestor);
}
return requestor.request('session:new', hook, params, httpHeaders);
}
let newClient; let newClient;
try { try {
let client, path, query; let client, path, query;