Class: Shugoi::RenderHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/shugoi/render_handler.rb

Overview

Traite la requête /__shugoi/render : vérifie token + grant, sert le HTML stocké. Parité avec renderResponseData + handleRender (render.ts).

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config, token_signer, html_store, config_cache, _pow = nil) ⇒ RenderHandler

Returns a new instance of RenderHandler.



7
8
9
10
11
12
# File 'lib/shugoi/render_handler.rb', line 7

def initialize(config, token_signer, html_store, config_cache, _pow = nil)
  @config = config
  @token_signer = token_signer
  @html_store = html_store
  @config_cache = config_cache
end

Class Method Details

.inject_referrer_policy(html) ⇒ Object

Anti-fuite du grant (parité injectReferrerPolicy de render.ts) : strict-origin-when- cross-origin (PAS no-referrer — casserait les embeds YouTube 153). Injecté dans le HTML rendu AVANT document.write, le grant n'est plus dans l'URL de la page.



51
52
53
54
55
56
57
58
59
60
# File 'lib/shugoi/render_handler.rb', line 51

def self.inject_referrer_policy(html)
  meta = '<meta name="referrer" content="strict-origin-when-cross-origin">'
  if html.include?("<head>")
    html.sub("<head>", "<head>#{meta}")
  elsif (m = html.match(/<html[^>]*>/))
    html.sub(m[0], "#{m[0]}#{meta}")
  else
    "#{meta}#{html}"
  end
end

Instance Method Details

#render_data(token, mid, grant, ip) ⇒ Hash

Returns { html: … } ou { error: "not_found" }.

Parameters:

  • token (String)

    token render

  • mid (String)

    machineId (SHA-256 du fingerprint, 64 hex)

  • grant (String)

    render-grant

  • ip (String)

Returns:

  • (Hash)

    { html: … } ou { error: "not_found" }



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/shugoi/render_handler.rb', line 19

def render_data(token, mid, grant, ip)
  return { error: "not_found" } if token.to_s.empty? || token.length < 16 || token.length > 300

  # Le token doit appartenir à CE siteKey (CRITIQUE 1 §7bis).
  tok_site_key = token.split(":")[0]
  return { error: "not_found" } if tok_site_key != @config.site_key

  # Expiration du token.
  tok_ts = token.split(":")[1].to_i
  return { error: "not_found" } if !tok_ts.zero? && Utils.now_ms - tok_ts > HtmlStore::TOKEN_TTL_MS

  # Anti-bypass token-only : grant valide requis (lié au siteKey + mid hex-64 + TTL 60s).
  return { error: "not_found" } unless @token_signer.verify_render_grant(mid, grant, token, ip, @config.site_key)

  content_replace_on = content_replace_flag?(token)
  html = @html_store.read(token)
  return { html: inject_notice(html, mid) } if html

  # Fallback content-replace OFF : renvoie le HTML du site.
  unless content_replace_on
    site_html = @html_store.site_html(tok_site_key)
    return { html: inject_notice(site_html, mid) } if site_html
  end

  return { error: "not_found" } unless @token_signer.verify_token(token)

  { error: "not_found" }
end