serve favicons over hashed paths for improved caching
This commit is contained in:
parent
66da5f6497
commit
4dfecce966
@ -210,7 +210,13 @@ export class ServerRegistration {
|
|||||||
|
|
||||||
// An updated favicon has been sent, update the src
|
// An updated favicon has been sent, update the src
|
||||||
if (ping.favicon) {
|
if (ping.favicon) {
|
||||||
document.getElementById('favicon_' + this.serverId).setAttribute('src', ping.favicon)
|
const faviconElement = document.getElementById('favicon_' + this.serverId)
|
||||||
|
|
||||||
|
// Since favicons may be URLs, only update the attribute when it has changed
|
||||||
|
// Otherwise the browser may send multiple requests to the same URL
|
||||||
|
if (faviconElement.getAttribute('src') !== ping.favicon) {
|
||||||
|
faviconElement.setAttribute('src', ping.favicon)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ class App {
|
|||||||
constructor () {
|
constructor () {
|
||||||
this.mojangUpdater = new MojangUpdater(this)
|
this.mojangUpdater = new MojangUpdater(this)
|
||||||
this.pingController = new PingController(this)
|
this.pingController = new PingController(this)
|
||||||
this.server = new Server(this.handleClientConnection)
|
this.server = new Server(this)
|
||||||
this.timeTracker = new TimeTracker(this)
|
this.timeTracker = new TimeTracker(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,9 +11,11 @@ function getRemoteAddr (req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
constructor (clientSocketHandler) {
|
constructor (app) {
|
||||||
|
this._app = app
|
||||||
|
|
||||||
this.createHttpServer()
|
this.createHttpServer()
|
||||||
this.createWebSocketServer(clientSocketHandler)
|
this.createWebSocketServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
createHttpServer () {
|
createHttpServer () {
|
||||||
@ -23,15 +25,40 @@ class Server {
|
|||||||
this._http = http.createServer((req, res) => {
|
this._http = http.createServer((req, res) => {
|
||||||
logger.log('info', '%s requested: %s', getRemoteAddr(req), req.url)
|
logger.log('info', '%s requested: %s', getRemoteAddr(req), req.url)
|
||||||
|
|
||||||
|
if (req.url.startsWith('/hashedfavicon?')) {
|
||||||
|
this.handleFaviconRequest(req, res)
|
||||||
|
} else {
|
||||||
// Attempt to handle req using distServeStatic, otherwise fail over to faviconServeStatic
|
// Attempt to handle req using distServeStatic, otherwise fail over to faviconServeStatic
|
||||||
// If faviconServeStatic fails, pass to finalHttpHandler to terminate
|
// If faviconServeStatic fails, pass to finalHttpHandler to terminate
|
||||||
distServeStatic(req, res, () => {
|
distServeStatic(req, res, () => {
|
||||||
faviconsServeStatic(req, res, finalHttpHandler(req, res))
|
faviconsServeStatic(req, res, finalHttpHandler(req, res))
|
||||||
})
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
createWebSocketServer (proxyClientSocketHandler) {
|
handleFaviconRequest = (req, res) => {
|
||||||
|
const hash = req.url.split('?')[1]
|
||||||
|
|
||||||
|
for (const serverRegistration of this._app.serverRegistrations) {
|
||||||
|
if (serverRegistration.faviconHash && serverRegistration.faviconHash === hash) {
|
||||||
|
const buf = Buffer.from(serverRegistration.lastFavicon.split(',')[1], 'base64')
|
||||||
|
|
||||||
|
res.writeHead(200, {
|
||||||
|
'Content-Type': 'image/png',
|
||||||
|
'Content-Length': buf.length
|
||||||
|
}).end(buf)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terminate request, no match
|
||||||
|
res.writeHead(404)
|
||||||
|
res.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
createWebSocketServer () {
|
||||||
this._wss = new WebSocket.Server({
|
this._wss = new WebSocket.Server({
|
||||||
server: this._http
|
server: this._http
|
||||||
})
|
})
|
||||||
@ -45,7 +72,7 @@ class Server {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Pass client off to proxy handler
|
// Pass client off to proxy handler
|
||||||
proxyClientSocketHandler(client)
|
this._app.handleClientConnection(client)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
const crypto = require('crypto')
|
||||||
|
|
||||||
const TimeTracker = require('./time')
|
const TimeTracker = require('./time')
|
||||||
|
|
||||||
const config = require('../config')
|
const config = require('../config')
|
||||||
@ -61,11 +63,8 @@ class ServerRegistration {
|
|||||||
update.recordData = this.recordData
|
update.recordData = this.recordData
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare against this.data.favicon to support favicon overrides
|
if (this.updateFavicon(resp.favicon)) {
|
||||||
const newFavicon = resp.favicon || this.data.favicon
|
update.favicon = this.getFaviconUrl()
|
||||||
if (this.updateFavicon(newFavicon)) {
|
|
||||||
// Append an updated favicon
|
|
||||||
update.favicon = newFavicon
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append a result object
|
// Append a result object
|
||||||
@ -101,7 +100,7 @@ class ServerRegistration {
|
|||||||
const payload = {
|
const payload = {
|
||||||
versions: this.versions,
|
versions: this.versions,
|
||||||
recordData: this.recordData,
|
recordData: this.recordData,
|
||||||
favicon: this.lastFavicon
|
favicon: this.getFaviconUrl()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only append graphPeakData if defined
|
// Only append graphPeakData if defined
|
||||||
@ -134,7 +133,8 @@ class ServerRegistration {
|
|||||||
message: 'Pinging...'
|
message: 'Pinging...'
|
||||||
},
|
},
|
||||||
recordData: this.recordData,
|
recordData: this.recordData,
|
||||||
graphPeakData: this.getGraphPeak()
|
graphPeakData: this.getGraphPeak(),
|
||||||
|
favicon: this.data.favicon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,13 +216,35 @@ class ServerRegistration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateFavicon (favicon) {
|
updateFavicon (favicon) {
|
||||||
|
// If data.favicon is defined, then a favicon override is present
|
||||||
|
// Disregard the incoming favicon, regardless if it is different
|
||||||
|
if (this.data.favicon) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (favicon && favicon !== this.lastFavicon) {
|
if (favicon && favicon !== this.lastFavicon) {
|
||||||
this.lastFavicon = favicon
|
this.lastFavicon = favicon
|
||||||
|
|
||||||
|
// Generate an updated hash
|
||||||
|
// This is used by #getFaviconUrl
|
||||||
|
if (!this._faviconHasher) {
|
||||||
|
this._faviconHasher = crypto.createHash('md5')
|
||||||
|
}
|
||||||
|
this.faviconHash = this._faviconHasher.update(favicon).digest('hex').toString()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFaviconUrl () {
|
||||||
|
if (this.faviconHash) {
|
||||||
|
return '/hashedfavicon?' + this.faviconHash
|
||||||
|
} else if (this.data.favicon) {
|
||||||
|
return this.data.favicon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateProtocolVersionCompat (incomingId, outgoingId, protocolIndex) {
|
updateProtocolVersionCompat (incomingId, outgoingId, protocolIndex) {
|
||||||
// If the result version matches the attempted version, the version is supported
|
// If the result version matches the attempted version, the version is supported
|
||||||
const isSuccess = incomingId === outgoingId
|
const isSuccess = incomingId === outgoingId
|
||||||
|
Loading…
Reference in New Issue
Block a user