indexboost-rails 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +54 -0
- data/indexboost-rails.gemspec +18 -0
- data/lib/indexboost/middleware.rb +95 -0
- data/lib/indexboost-rails.rb +5 -0
- metadata +90 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a12049408abec0e580ce7986070fb0eb9c2cd1f0afe9ef7b2f83ebf4401907c9
|
|
4
|
+
data.tar.gz: aa39809870273dc0d846872f186b417a9a43e5b763c2e5984acd3db1e0e8dbdf
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 28603508bbd4942417a9a8c1aead80240f9dbf354c73bfdc57ba902d00779a6f49cbb6a403ec79c0b5b1fa45d7532a9a338ca7d9da5503538f0c483bd47a690c
|
|
7
|
+
data.tar.gz: 8cd4d44057088b3a4bf015b8753c1f0f910009e0e596ed3f77e54e730a5275b67d91bddf24217cebbb8b1490195e9cbe0ad9c48b1ca93343760275b1a74698f4
|
data/README.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# indexboost-rails
|
|
2
|
+
|
|
3
|
+
IndexBoost Render Rack middleware for **Ruby on Rails** and any Rack-compatible framework.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
# Gemfile
|
|
9
|
+
gem "indexboost-rails"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bundle install
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
# config/application.rb
|
|
20
|
+
require "indexboost-rails"
|
|
21
|
+
|
|
22
|
+
module MyApp
|
|
23
|
+
class Application < Rails::Application
|
|
24
|
+
config.middleware.insert_before 0, IndexBoost::Middleware,
|
|
25
|
+
token: ENV.fetch("INDEXBOOST_TOKEN")
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# .env
|
|
32
|
+
INDEXBOOST_TOKEN=your_token_here
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Options
|
|
36
|
+
|
|
37
|
+
| Option | Default | Description |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| `token` | **required** | Render token from app.getindexboost.com |
|
|
40
|
+
| `service_url` | `https://render.getindexboost.com` | Override render URL |
|
|
41
|
+
| `timeout` | `30` | HTTP timeout in seconds |
|
|
42
|
+
| `ignored_paths` | `[/^\/api\//, /^\/rails\//]` | Array of Regexp to skip |
|
|
43
|
+
|
|
44
|
+
## Sinatra / plain Rack
|
|
45
|
+
|
|
46
|
+
```ruby
|
|
47
|
+
require "indexboost-rails"
|
|
48
|
+
|
|
49
|
+
use IndexBoost::Middleware, token: ENV.fetch("INDEXBOOST_TOKEN")
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## License
|
|
53
|
+
|
|
54
|
+
MIT
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Gem::Specification.new do |spec|
|
|
2
|
+
spec.name = "indexboost-rails"
|
|
3
|
+
spec.version = "1.0.0"
|
|
4
|
+
spec.authors = ["IndexBoost"]
|
|
5
|
+
spec.email = ["support@getindexboost.com"]
|
|
6
|
+
spec.summary = "IndexBoost Render middleware for Ruby on Rails"
|
|
7
|
+
spec.description = "Rack middleware that intercepts crawler requests and serves rendered HTML from render.getindexboost.com."
|
|
8
|
+
spec.homepage = "https://getindexboost.com/docs/integrations/rails"
|
|
9
|
+
spec.license = "MIT"
|
|
10
|
+
|
|
11
|
+
spec.required_ruby_version = ">= 3.1"
|
|
12
|
+
spec.files = Dir["lib/**/*", "README.md", "*.gemspec"]
|
|
13
|
+
|
|
14
|
+
spec.add_dependency "rack", ">= 2.0"
|
|
15
|
+
|
|
16
|
+
spec.add_development_dependency "rack-test"
|
|
17
|
+
spec.add_development_dependency "minitest"
|
|
18
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require "net/http"
|
|
2
|
+
require "uri"
|
|
3
|
+
|
|
4
|
+
module IndexBoost
|
|
5
|
+
# Rack middleware that intercepts crawler requests and serves rendered
|
|
6
|
+
# HTML from the IndexBoost render service.
|
|
7
|
+
#
|
|
8
|
+
# Usage in config/application.rb:
|
|
9
|
+
#
|
|
10
|
+
# config.middleware.insert_before 0, IndexBoost::Middleware,
|
|
11
|
+
# token: ENV.fetch("INDEXBOOST_TOKEN")
|
|
12
|
+
#
|
|
13
|
+
class Middleware
|
|
14
|
+
CRAWLERS = /googlebot|bingbot|gptbot|claudebot|perplexitybot|duckduckbot|
|
|
15
|
+
slurp|naverbot|yandexbot|baiduspider|facebookexternalhit|
|
|
16
|
+
twitterbot|linkedinbot|whatsapp|telegrambot|applebot|rogerbot|
|
|
17
|
+
semrushbot|ahrefsbot|bytespider|dotbot|mj12bot|pinterestbot/ix
|
|
18
|
+
|
|
19
|
+
STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff|woff2|
|
|
20
|
+
ttf|eot|otf|pdf|zip|xml|map|txt|json|csv|gz|br)$/ix
|
|
21
|
+
|
|
22
|
+
DEFAULT_SERVICE_URL = "https://render.getindexboost.com"
|
|
23
|
+
|
|
24
|
+
# @param app [#call] The next Rack app
|
|
25
|
+
# @param token [String] IndexBoost render token (required)
|
|
26
|
+
# @option options [String] :service_url Override render URL
|
|
27
|
+
# @option options [Integer] :timeout HTTP timeout in seconds (default 30)
|
|
28
|
+
# @option options [Array] :ignored_paths Array of Regexp to skip
|
|
29
|
+
def initialize(app, token:, **options)
|
|
30
|
+
raise ArgumentError, "[IndexBoost] token is required" if token.nil? || token.empty?
|
|
31
|
+
|
|
32
|
+
@app = app
|
|
33
|
+
@token = token
|
|
34
|
+
@service_url = options.fetch(:service_url, DEFAULT_SERVICE_URL).chomp("/")
|
|
35
|
+
@timeout = options.fetch(:timeout, 30)
|
|
36
|
+
@ignored_paths = options.fetch(:ignored_paths, [%r{^/api/}, %r{^/rails/}])
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def call(env)
|
|
40
|
+
return @app.call(env) unless should_render?(env)
|
|
41
|
+
|
|
42
|
+
html = fetch_rendered(env)
|
|
43
|
+
return @app.call(env) if html.nil?
|
|
44
|
+
|
|
45
|
+
[
|
|
46
|
+
200,
|
|
47
|
+
{
|
|
48
|
+
"Content-Type" => "text/html; charset=utf-8",
|
|
49
|
+
"X-IndexBoost-Rendered" => "true",
|
|
50
|
+
"Cache-Control" => "public, max-age=3600",
|
|
51
|
+
},
|
|
52
|
+
[html],
|
|
53
|
+
]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def should_render?(env)
|
|
59
|
+
return false unless env["REQUEST_METHOD"] == "GET"
|
|
60
|
+
|
|
61
|
+
path = env["PATH_INFO"].to_s
|
|
62
|
+
return false if STATIC_EXTENSIONS.match?(path)
|
|
63
|
+
|
|
64
|
+
@ignored_paths.each { |p| return false if p.match?(path) }
|
|
65
|
+
|
|
66
|
+
ua = env["HTTP_USER_AGENT"].to_s
|
|
67
|
+
CRAWLERS.match?(ua)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def fetch_rendered(env)
|
|
71
|
+
scheme = env["rack.url_scheme"] || "https"
|
|
72
|
+
host = env["HTTP_HOST"] || env["SERVER_NAME"]
|
|
73
|
+
path = env["REQUEST_URI"] || env["PATH_INFO"]
|
|
74
|
+
full_url = "#{scheme}://#{host}#{path}"
|
|
75
|
+
|
|
76
|
+
render_uri = URI("#{@service_url}/?url=#{URI.encode_uri_component(full_url)}")
|
|
77
|
+
|
|
78
|
+
request = Net::HTTP::Get.new(render_uri)
|
|
79
|
+
request["X-INDEXBOOST-TOKEN"] = @token
|
|
80
|
+
request["X-Original-User-Agent"] = env["HTTP_USER_AGENT"].to_s
|
|
81
|
+
|
|
82
|
+
http = Net::HTTP.new(render_uri.host, render_uri.port)
|
|
83
|
+
http.use_ssl = render_uri.scheme == "https"
|
|
84
|
+
http.read_timeout = @timeout
|
|
85
|
+
http.open_timeout = 10
|
|
86
|
+
|
|
87
|
+
response = http.request(request)
|
|
88
|
+
return nil unless response.is_a?(Net::HTTPSuccess)
|
|
89
|
+
|
|
90
|
+
response.body
|
|
91
|
+
rescue StandardError
|
|
92
|
+
nil
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: indexboost-rails
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- IndexBoost
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-04-16 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rack
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rack-test
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: minitest
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
description: Rack middleware that intercepts crawler requests and serves rendered
|
|
56
|
+
HTML from render.getindexboost.com.
|
|
57
|
+
email:
|
|
58
|
+
- support@getindexboost.com
|
|
59
|
+
executables: []
|
|
60
|
+
extensions: []
|
|
61
|
+
extra_rdoc_files: []
|
|
62
|
+
files:
|
|
63
|
+
- README.md
|
|
64
|
+
- indexboost-rails.gemspec
|
|
65
|
+
- lib/indexboost-rails.rb
|
|
66
|
+
- lib/indexboost/middleware.rb
|
|
67
|
+
homepage: https://getindexboost.com/docs/integrations/rails
|
|
68
|
+
licenses:
|
|
69
|
+
- MIT
|
|
70
|
+
metadata: {}
|
|
71
|
+
post_install_message:
|
|
72
|
+
rdoc_options: []
|
|
73
|
+
require_paths:
|
|
74
|
+
- lib
|
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '3.1'
|
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
|
+
requirements:
|
|
82
|
+
- - ">="
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: '0'
|
|
85
|
+
requirements: []
|
|
86
|
+
rubygems_version: 3.5.22
|
|
87
|
+
signing_key:
|
|
88
|
+
specification_version: 4
|
|
89
|
+
summary: IndexBoost Render middleware for Ruby on Rails
|
|
90
|
+
test_files: []
|