Skip to content

Commit

Permalink
Set basic authentication credentials for users in query endpoint URIs.
Browse files Browse the repository at this point in the history
Issue #63 - if user information is present on the query endpoint URI, set
the corresponding basic authentication credentials on outgoing query
requests.
  • Loading branch information
lkitching committed Aug 1, 2017
1 parent 00bb42c commit 573621a
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 15 deletions.
38 changes: 23 additions & 15 deletions lib/tripod/streaming.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,37 @@
module Tripod
module Streaming

def self.create_http_client(uri, opts)
client = Net::HTTP.new(uri.host, uri.port)
client.use_ssl = true if uri.port.to_s == "443"
client.read_timeout = opts[:timeout_seconds] || 10
client
end

def self.create_request(uri, opts)
headers = opts[:extra_headers] || {}
a = opts[:accept] || headers['Accept'] || '*/*'
headers['Accept'] = a

req = Net::HTTP::Post.new(uri.request_uri, headers)

if uri.user
req.basic_auth(uri.user, uri.password)
end
req
end

# stream data from a url
# opts
#  :accept => "*/*"
# :timeout_seconds = 10
# :response_limit_bytes = nil
def self.get_data(request_url, payload, opts={})

accept = opts[:accept]
timeout_in_seconds = opts[:timeout_seconds] || 10
limit_in_bytes = opts[:response_limit_bytes]

# set request headers
headers = opts[:extra_headers] || {}

# if explicit accept option is given, set it in the headers (and overwrite any existing value in the extra_headers map)
# if none is given accept */*
headers['Accept'] = accept || headers['Accept'] || '*/*'

uri = URI(request_url)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if uri.port.to_s == "443"
http.read_timeout = timeout_in_seconds
http = self.create_http_client(uri, opts)
post_request = self.create_request(uri, opts)

total_bytes = 0

Expand All @@ -35,7 +43,7 @@ def self.get_data(request_url, payload, opts={})
response = StringIO.new

begin
http.request_post(uri.request_uri, payload, headers) do |res|
http.request(post_request, payload) do |res|

response_duration = Time.now - request_start_time if Tripod.logger.debug?

Expand Down
89 changes: 89 additions & 0 deletions spec/tripod/streaming_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,95 @@
end
end

describe '.create_http_client' do
context 'http URI with no options' do
let(:client) { Tripod::Streaming.create_http_client(URI('http://localhost:8080/sparql/query'), {}) }

it 'should set host' do
expect(client.address).to eq('localhost')
end

it 'should set port' do
expect(client.port).to eq(8080)
end

it 'should set default read timeout' do
expect(client.read_timeout).to eq(10)
end

it 'should not use ssl' do
expect(client.use_ssl?).to eq(false)
end
end

context 'https URI with default https port' do
let(:client) { Tripod::Streaming.create_http_client(URI('https://localhost:443/sparql/query'), {}) }
it 'should use ssl' do
expect(client.use_ssl?).to eq(true)
end
end

context 'with read timeout option' do
let(:read_timeout) { 5 }
let(:client) { Tripod::Streaming.create_http_client(URI('http://localhost/sparql/query'), {:timeout_seconds => read_timeout}) }

it 'should set read timeout' do
expect(client.read_timeout).to eq(read_timeout)
end
end
end

describe '.create_request' do
context 'with no user or extra headers' do
let(:req) { Tripod::Streaming.create_request(URI('http://localhost/sparql/query'), {}) }
it 'should set accept header' do
expect(req['accept']).to eq('*/*')
end
end

context 'with no user and extra headers' do
let!(:extra_headers) { {'content-type' => 'application/sparql-query', 'connection' => 'close'} }
let!(:req) { Tripod::Streaming.create_request(URI('http://localhost/sparql/query'), {:extra_headers => extra_headers}) }

it 'should set headers' do
extra_headers.each do |name, value|
expect(req[name]).to eq(value)
end
end
end

context 'with no user and extra headers and accept options' do
let(:extra_headers) { { 'accept' => 'text/trig' } }
let(:accept) { 'application/n-triples' }
let(:req) { Tripod::Streaming.create_request(URI('http://localhost/sparql/query'), {:extra_headers => extra_headers, :accept => accept}) }

it 'should set accept option as accept header' do
expect(req['accept']).to eq(accept)
end
end

context 'with user and no headers' do
let(:req) { Tripod::Streaming.create_request(URI('http://user:password@localhost/sparql/query'), {}) }
it 'should use basic auth' do
expect(req['authorization']).to match(/Basic [a-zA-Z0-9+\/=]+/)
end
end

context 'with user and extra Authorization header' do
let(:extra_headers) { {'content-type' => 'application/sparql-query', 'authorization' => 'Token abcdef'} }
let(:uri) { URI('http://user:password@localhost/sparql/query') }
let(:req) { Tripod::Streaming.create_request(uri, {:extra_headers => extra_headers}) }

it 'should use basic auth' do
expect(req['authorization']).to match(/Basic [a-zA-Z0-9+\/=]+/)
end

it 'should set other extra header' do
expect(req['content-type']).to eq('application/sparql-query')
end
end
end

# these tests actually download remote resources (from jQuery's CDN) to test the streaming bits
# TODO: move this out so it doesn't run with the normal rake task??
context "streaming" do
Expand Down

0 comments on commit 573621a

Please sign in to comment.