mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-27 22:35:10 +08:00
The `discourse-track-view-session-id` meta tag is generated inline when HTML is rendered, so when `Middleware::AnonymousCache` serves a cached response every anonymous visitor receives the same session id baked into the cached body. Browser pageview analytics that rely on this value to distinguish visitors collapse all cache-served visits into a single session. This commit introduces `Middleware::TrackViewSessionIdInjector`, a Rack middleware that performs a late-stage substitution on the outbound response body. The `ApplicationHelper#discourse_pageview_tracking_meta_tags` helper now emits a placeholder string into the meta tag and registers it on a response header. The middleware reads that header, deletes it, and replaces the placeholder in the body with a fresh `SecureRandom.alphanumeric(Middleware::RequestTracker::MAX_SESSION_ID_LENGTH)` per request, so each visitor gets a unique session id even when the underlying HTML came from cache.
24 lines
653 B
Ruby
Vendored
24 lines
653 B
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
module Middleware
|
|
class TrackViewSessionIdInjector
|
|
PLACEHOLDER_HEADER = "Discourse-Track-View-Session-Id-Placeholder"
|
|
|
|
def initialize(app, settings = {})
|
|
@app = app
|
|
end
|
|
|
|
def call(env)
|
|
status, headers, response = @app.call(env)
|
|
|
|
if placeholder = headers.delete(PLACEHOLDER_HEADER)
|
|
session_id = SecureRandom.alphanumeric(Middleware::RequestTracker::MAX_SESSION_ID_LENGTH)
|
|
parts = []
|
|
response.each { |part| parts << part.to_s.sub(placeholder, session_id) }
|
|
[status, headers, parts]
|
|
else
|
|
[status, headers, response]
|
|
end
|
|
end
|
|
end
|
|
end
|