-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Expand file tree
/
Copy pathconfig.ru
More file actions
114 lines (98 loc) · 3.07 KB
/
config.ru
File metadata and controls
114 lines (98 loc) · 3.07 KB
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
require 'rack/jekyll'
require 'yaml'
require 'rack-ssl-enforcer'
require 'rack/static'
use Rack::SslEnforcer, :except_environments => 'development'
# Rack 3 requires lower-case header names. Normalize all response headers.
class HeaderDowncaser
def initialize(app)
@app = app
end
def call(env)
status, headers, body = @app.call(env)
normalized = {}
headers.each do |k, v|
# Ensure keys are lower-case strings; values must be strings (join arrays if any)
normalized[k.to_s.downcase] = v.is_a?(Array) ? v.join("\n") : v.to_s
end
[status, normalized, body]
end
end
class PatchMethodOnly
def initialize app
@app = app
end
def call env
if Rack::Request.new(env).post?
WebhookPayloadDocHandler.new.call(env)
else
Rack::Jekyll.new.call(env)
end
end
end
app = Rack::Builder.app do
use HeaderDowncaser
map '/update_webhook_payload_doc' do
use PatchMethodOnly
end
map '/api' do
run lambda { |env|
# If the request is exactly /api (no trailing slash), redirect to /api/
return [301, { 'location' => '/api/', 'content-type' => 'text/html' }, ['']] if env['PATH_INFO'].to_s.empty?
env['PATH_INFO'] = '/' if env['PATH_INFO'] == '' # safety
root = File.expand_path('api', __dir__)
static = Rack::Static.new(-> { [404, {}, []] },
urls: [''],
root: root,
index: 'index.html')
status, headers, body = static.call(env)
# Fallback: if .css is requested but not found, try extensionless file and set proper content type
if status == 404 && env['PATH_INFO'].end_with?('.css')
rel = env['PATH_INFO'].sub(%r{^/}, '').sub(/\.css\z/, '')
candidate = File.join(root, rel)
if File.file?(candidate)
css = File.binread(candidate)
status = 200
headers = {
'content-type' => 'text/css',
'content-length' => css.bytesize.to_s
}
body = [css]
end
end
[status, headers, body]
}
end
# Ensure icon fonts requested at site root resolve to the API build output
map '/fonts' do
run lambda { |env|
root = File.expand_path('api/fonts', __dir__)
static = Rack::Static.new(-> { [404, {}, []] },
urls: [''],
root: root)
static.call(env)
}
end
# Handle images with proper binary serving
map '/user/images' do
run lambda { |env|
root = File.expand_path('_site/user/images', __dir__)
static = Rack::Static.new(-> { [404, {}, []] },
urls: [''],
root: root)
static.call(env)
}
end
# Handle all other images
map '/images' do
run lambda { |env|
root = File.expand_path('_site/images', __dir__)
static = Rack::Static.new(-> { [404, {}, []] },
urls: [''],
root: root)
static.call(env)
}
end
run Rack::Jekyll.new
end
run app