File: middleware.rb

package info (click to toggle)
ruby-browser 5.3.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 872 kB
  • sloc: ruby: 4,752; makefile: 13
file content (70 lines) | stat: -rw-r--r-- 1,554 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# frozen_string_literal: true

require "uri"
require_relative "middleware/context"

module Browser
  class Middleware
    # Detect the most common assets.
    ASSETS_REGEX =
      /\.(css|png|jpe?g|gif|js|svg|ico|flv|mov|m4v|ogg|swf)\z/i.freeze

    # Detect the ACCEPT header. IE8 send */*.
    ACCEPT_REGEX = %r{(text/html|\*/\*)}.freeze

    def initialize(app, &block)
      raise ArgumentError, "Browser::Middleware requires a block" unless block

      @app = app
      @block = block
    end

    def call(env)
      request = Rack::Request.new(env)

      # Only apply verification on HTML requests.
      # This ensures that images, CSS and JavaScript
      # will be rendered.
      return run_app(env) unless process?(request)

      path = catch(:redirected) do
        Context.new(request).instance_eval(&@block)
      end

      # No path, no match.
      return run_app(env) unless path

      resolve_redirection(env, request.path, path)
    end

    def resolve_redirection(env, current_path, path)
      uri = URI.parse(path)

      if uri.path == current_path
        run_app(env)
      else
        redirect(path)
      end
    end

    def redirect(path)
      [302, {"Content-Type" => "text/html", "Location" => path}, []]
    end

    def run_app(env)
      @app.call(env)
    end

    def process?(request)
      html?(request) && !assets?(request)
    end

    def html?(request)
      request.env["HTTP_ACCEPT"].to_s.match(ACCEPT_REGEX)
    end

    def assets?(request)
      request.path.match(ASSETS_REGEX)
    end
  end
end