-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
181 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
class ImageProxyController < ApplicationController | ||
include ActionController::Live | ||
|
||
def raster | ||
remote_url = "#{IMAGE_SERVER_CONFIG[:url]}/iiif/2/#{params[:path]}.#{params[:format]}" | ||
uri = URI(remote_url) | ||
Net::HTTP.start(uri.host, uri.port) do |http| | ||
request = Net::HTTP::Get.new(uri) | ||
request['Authorization'] = "Bearer #{IMAGE_SERVER_CONFIG[:token]}" | ||
|
||
http.request request do |remote_response| | ||
response.headers['Content-Length'] = remote_response['Content-Length'] | ||
response.headers['Content-Type'] = remote_response['Content-Type'] | ||
response.status = :ok | ||
|
||
remote_response.read_body do |chunk| | ||
response.stream.write chunk | ||
end | ||
end | ||
ensure | ||
response.stream.close | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
console.log("Image auth service worker started running at: " + new Date().getTime()); | ||
|
||
let imageServerUrl = null; | ||
const pidsToTokens = new Map(); | ||
const iiifUrlWithRequiredAuthRegex = /.+\/iiif\/2\/(standard|limited)\/([^/]+)\/.+/; | ||
|
||
async function sleep(ms) { | ||
return new Promise((resolve) => setTimeout(resolve, ms)); | ||
} | ||
|
||
function registerAuthToken(identifier, token) { | ||
// TODO: Also clear out some old tokens (with addedAt time that's far in the past) so that | ||
// the pidsToTokens Map doesn't grow indefinitely. | ||
pidsToTokens.set( | ||
identifier, | ||
{ | ||
token: token, | ||
addedAt: Date.now() | ||
} | ||
); | ||
}; | ||
|
||
async function checkForAuthToken(identifier) { | ||
console.log(`Checking for ${identifier}`); | ||
const start = Date.now(); | ||
const checkDelayTimes = [0, 100, 3000]; // [100, 200] | ||
for (const delayTime of checkDelayTimes) { | ||
await sleep(delayTime); | ||
console.log(`Checking for ${identifier} in pidsToTokens Map after ${delayTime} millisecond delay.`); | ||
if (pidsToTokens.has(identifier)) { | ||
return pidsToTokens.get(identifier); | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
async function fetchWithAuthorizationHeader(request) { | ||
|
||
console.log(`Adding header to request: ${request.url}`); | ||
const identifier = request.url.match(iiifUrlWithRequiredAuthRegex)[2]; | ||
|
||
// Check if there is a token available for this identifier | ||
const entry = await checkForAuthToken(identifier); | ||
const headers = new Headers(request.headers); | ||
if (entry) { | ||
console.log(`Making request with token ${entry.token}`); | ||
headers.set('Authorization', `Bearer ${entry ? entry.token : null}`); | ||
} | ||
|
||
const newRequest = new Request(request, { | ||
mode: 'cors', | ||
credentials: 'omit', | ||
headers: headers | ||
}); | ||
|
||
return fetch(newRequest); | ||
} | ||
|
||
self.addEventListener('fetch', function (event) { | ||
const url = event.request.url; | ||
// console.log(`imageServerUrl: ${imageServerUrl}`); | ||
// console.log(`Intercepting fetch request for: ${url}`); | ||
if (url.startsWith(imageServerUrl) && url.match(iiifUrlWithRequiredAuthRegex)) { | ||
event.respondWith(fetchWithAuthorizationHeader(event.request)); | ||
} | ||
}); | ||
|
||
self.addEventListener("message", (event) => { | ||
const { data } = event; | ||
console.log('Service worker received message: ', data); | ||
|
||
if (data.type == 'registerAuthToken') { | ||
registerAuthToken(data.identifier, data.token); | ||
} | ||
|
||
if (data.type == 'setImageServerUrl') { | ||
imageServerUrl = data.url; | ||
} | ||
}); |