Skip to content

Commit

Permalink
Introduce a wrapper around the various transporters that runs it thro…
Browse files Browse the repository at this point in the history
…ugh a proxy (#133)

* Introduce a wrapper around the various transporters that runs it through a proxy.

* remove the proxy support for JSONP, and instead throw an error.
  • Loading branch information
epugh authored Nov 1, 2023
1 parent 59c9eef commit 3e60631
Show file tree
Hide file tree
Showing 12 changed files with 288 additions and 24 deletions.
6 changes: 4 additions & 2 deletions factories/esSearcherFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
var self = this;
var uri = esUrlSvc.parseUrl(self.url);
var apiMethod = self.config.apiMethod;
var proxyUrl = self.config.proxyUrl;

if ( esUrlSvc.isBulkCall(uri) ) {
apiMethod = 'BULK';
Expand All @@ -135,7 +136,7 @@
});
}
var url = esUrlSvc.buildUrl(uri);
var transport = transportSvc.getTransport({apiMethod: apiMethod});
var transport = transportSvc.getTransport({apiMethod: apiMethod, proxyUrl: proxyUrl});

var queryDslWithPagerArgs = angular.copy(self.queryDsl);
if (self.pagerArgs) {
Expand Down Expand Up @@ -382,6 +383,7 @@
var uri = esUrlSvc.parseUrl(self.url);

var apiMethod = self.config.apiMethod;
var proxyUrl = self.config.proxyUrl;

var templateCall = isTemplateCall(self.args);

Expand All @@ -399,7 +401,7 @@
// });
//}
var url = esUrlSvc.buildRenderTemplateUrl(uri);
var transport = transportSvc.getTransport({apiMethod: apiMethod});
var transport = transportSvc.getTransport({apiMethod: apiMethod, proxyUrl: proxyUrl});

var queryDslWithPagerArgs = angular.copy(self.queryDsl);
if (self.pagerArgs) {
Expand Down
6 changes: 4 additions & 2 deletions factories/httpJsonpTransportFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
angular.module('o19s.splainer-search')
.factory('HttpJsonpTransportFactory', [
'TransportFactory',
'$http',
'$http','$sce',
HttpJsonpTransportFactory
]);

function HttpJsonpTransportFactory(TransportFactory, $http) {
function HttpJsonpTransportFactory(TransportFactory, $http, $sce) {
var Transport = function(options) {
TransportFactory.call(this, options);
};
Expand All @@ -21,6 +21,8 @@
Transport.prototype.query = query;

function query(url) {
url = $sce.trustAsResourceUrl(url);

// you don't get header or payload support with jsonp, it's akin to GET requests that way.
return $http.jsonp(url, { jsonpCallbackParam: 'json.wrf' });
}
Expand Down
37 changes: 37 additions & 0 deletions factories/httpProxyTransportFactory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';

/*jslint latedef:false*/

(function() {
angular.module('o19s.splainer-search')
.factory('HttpProxyTransportFactory', [
'TransportFactory',
'$http',
'HttpJsonpTransportFactory',
HttpProxyTransportFactory
]);

function HttpProxyTransportFactory(TransportFactory, $http, HttpJsonpTransportFactory) {
var Transport = function(options) {
TransportFactory.call(this, options);
};

Transport.prototype = Object.create(TransportFactory.prototype);
Transport.prototype.constructor = Transport;

Transport.prototype.query = query;

function query(url, payload, headers) {
var transport = this.options().transport;

// It doesn't make sense to use JSONP instead of GET with a proxy
if (transport instanceof HttpJsonpTransportFactory) {
throw new Error('It does not make sense to proxy a JSONP connection, use GET instead.');
}
url = this.options().proxyUrl + url;
return transport.query(url, payload, headers);
}

return Transport;
}
})();
4 changes: 3 additions & 1 deletion factories/searchApiSearcherFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@



/* jshint unused: false */
function addDocToGroup (groupedBy, group, searchApiDoc) {
/*jslint validthis:true*/
console.log('addDocToGroup');
Expand All @@ -59,9 +60,10 @@
/*jslint validthis:true*/
const self= this;
var apiMethod = self.config.apiMethod;
var proxyUrl = self.config.proxyUrl;
var url = self.url;
var uri = esUrlSvc.parseUrl(self.url);
var transport = transportSvc.getTransport({apiMethod: apiMethod});
var transport = transportSvc.getTransport({apiMethod: apiMethod, proxyUrl: proxyUrl});

// maybe the url and the payload should be managed inside the transport?
// i don't like how it's not more seamless what to do on a GET and a POST
Expand Down
11 changes: 5 additions & 6 deletions factories/solrSearcherFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
angular.module('o19s.splainer-search')
.factory('SolrSearcherFactory', [
'$q',
'$sce',
'$log',
'SolrDocFactory',
'SearcherFactory',
Expand All @@ -18,7 +17,7 @@
]);

function SolrSearcherFactory(
$q, $sce, $log,
$q, $log,
SolrDocFactory, SearcherFactory, transportSvc,
activeQueries, defaultSolrConfig,
solrSearcherPreprocessorSvc
Expand Down Expand Up @@ -231,16 +230,16 @@

activeQueries.count++;
return $q(function(resolve, reject) {
var trustedUrl = $sce.trustAsResourceUrl(url);

var apiMethod = defaultSolrConfig.apiMethod; // Solr defaults to JSONP
if (self.config && self.config.apiMethod) {
apiMethod = self.config.apiMethod;
}
var proxyUrl = self.config.proxyUrl;

var transport = transportSvc.getTransport({apiMethod: apiMethod, proxyUrl: proxyUrl});

var transport = transportSvc.getTransport({apiMethod: apiMethod});

transport.query(trustedUrl, null, null)
transport.query(url, null, null)
.then(function success(resp) {
var solrResp = resp.data;
activeQueries.count--;
Expand Down
3 changes: 2 additions & 1 deletion factories/vectaraSearcherFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,9 @@
/*jslint validthis:true*/
const self= this;
var apiMethod = 'POST';
var proxyUrl = self.config.proxyUrl;
var url = self.url;
var transport = transportSvc.getTransport({apiMethod: apiMethod});
var transport = transportSvc.getTransport({apiMethod: apiMethod, proxyUrl: proxyUrl});

var queryDslWithPagerArgs = angular.copy(self.queryDsl);
if (self.pagerArgs) {
Expand Down
2 changes: 1 addition & 1 deletion pages/home/HomeCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@

angular.module('myApp').controller('HomeCtrl', ['$scope', 'o19sRSearch', function($scope, o19sRSearch) {
//TODO - put any directive code here
}]);
}]);
21 changes: 15 additions & 6 deletions services/transportSvc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ angular.module('o19s.splainer-search')
'HttpGetTransportFactory',
'HttpJsonpTransportFactory',
'BulkTransportFactory',
'HttpProxyTransportFactory',
function transportSvc(
HttpPostTransportFactory,
HttpGetTransportFactory,
HttpJsonpTransportFactory,
BulkTransportFactory
BulkTransportFactory,
HttpProxyTransportFactory
) {
var self = this;

Expand All @@ -27,16 +29,23 @@ angular.module('o19s.splainer-search')
if (apiMethod !== undefined) {
apiMethod = apiMethod.toUpperCase();
}

let transport = null;
if (apiMethod === 'BULK') {
return bulkTransport;
transport = bulkTransport;
} else if (apiMethod === 'JSONP') {
return httpJsonpTransport;
transport = httpJsonpTransport;
} else if (apiMethod === 'GET') {
return httpGetTransport;
transport = httpGetTransport;
} else {
return httpPostTransport;
transport = httpPostTransport;
}

var proxyUrl = options.proxyUrl;
if (proxyUrl !== undefined) {
transport = new HttpProxyTransportFactory({proxyUrl: proxyUrl, transport: transport});
//transport = proxyTransport;
}
return transport;
}
}
]);
4 changes: 0 additions & 4 deletions test/spec/bulkTransportFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ describe('Service: transport: es bulk transport', function() {
beforeEach(module('o19s.splainer-search'));

var $httpBackend;
var $q;
var $rootScope;
var $timeout;
var BulkTransportFactory;

Expand All @@ -17,8 +15,6 @@ describe('Service: transport: es bulk transport', function() {

beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
$q = $injector.get('$q');
$rootScope = $injector.get('$rootScope');
$timeout = $injector.get('$timeout');
}));

Expand Down
57 changes: 57 additions & 0 deletions test/spec/esSearchSvc.js
Original file line number Diff line number Diff line change
Expand Up @@ -1276,6 +1276,63 @@ describe('Service: searchSvc: ElasticSearch', function() {
expect(called).toEqual(1);
});
});
describe('templated and proxied search', function() {
beforeEach(inject(function () {

// the 'id' tells us that we have a templated search.
var mockEsParams = {
id: 'tmdb-title-search-template',
params: {
search_query: 'star'
}
};

var config = {
apiMethod: 'POST',
proxyUrl: 'http://myserver/api?url='
}

searcher = searchSvc.createSearcher(
mockFieldSpec,
mockEsUrl,
mockEsParams,
mockQueryText,
config,
'es'
);
}));

it('returns docs, and removes _source and highlight query params', function() {
$httpBackend.expectPOST('http://myserver/api?url=' + mockEsUrl + '/template', function verifyParamsStripped(data) {
var esQuery = angular.fromJson(data);
return (
(esQuery.id === 'tmdb-title-search-template') &&
(angular.isDefined(esQuery.highlight) == false) &&
(angular.isDefined(esQuery._source) == false) &&
(angular.isDefined(esQuery.from) == false) &&
(angular.isDefined(esQuery.size) == false) &&
(esQuery.params.from === 0) &&
(esQuery.params.size === 10)
);
}).
respond(200, mockES7Results);

var called = 0;

searcher.search()
.then(function() {
var docs = searcher.docs;
expect(docs.length === 2);

expect(searcher.numFound).toEqual(2);
called++;
});

$httpBackend.flush();
$httpBackend.verifyNoOutstandingExpectation();
expect(called).toEqual(1);
});
});
describe('scripted fields', function() {
var mockScriptedResults = {
hits: {
Expand Down
Loading

0 comments on commit 3e60631

Please sign in to comment.