Last active
March 1, 2016 23:10
-
-
Save marktabler/120a2150065781f1e642 to your computer and use it in GitHub Desktop.
Middleware Content Proxy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ContentProxy | |
def initialize(app) | |
@app = app | |
end | |
def should_use_cms? | |
# Some logic goes here, examining the request path and making the determination | |
# about whether to render using the CMS engine or let the request bubble up | |
# to the Rails app. This example looks for URIs starting with "/blog" | |
env['REQUEST_URI'] =~ /^\/blog/ | |
end | |
def cms_path_for_request | |
# Some logic goes here, translating the request path to the CMS path. If I want | |
# to let the URI "my-rails-server.com/blog/posts" to display content from | |
# "my-content-server.com/posts", then I would use something like this: | |
env['REQUEST_URI'] = env['REQUEST_URI'].gsub(/^\/blog/, '/') | |
end | |
def call(env) | |
response = Rack::Response.new | |
# Instead of being the middle-man for POST and admin operations, we'll just redirect | |
# admins to the actual CMS site. This catches /cms/ghost as well as /ghost | |
if env['REQUEST_URI'] =~ /^(\/cms)?\/ghost/ | |
response.redirect('https://my-content-server.com/ghost') | |
return response.finish | |
end | |
# Special case for CSS files (which otherwise will not transfer correctly) | |
if env['REQUEST_URI'] =~ /\.css/ | |
response.headers["Content-Type"] = "text/css" | |
end | |
if should_use_cms? | |
content_path = cms_path_for_request | |
uri = URI.join("https://my-content-server.com", content_path) | |
# This is the main part of the solution - we're grabbing a full HTTP response from the CMS server, | |
# and responding to our users' requests with it. We're also passing status codes like 200 or 404 | |
# through, so if we happen to get a page-not-found, we don't respond with an error body and a 200 (OK) status. | |
content = HTTParty.get(uri) | |
response.status = content.code | |
response.body = [content.body] | |
response.finish | |
else | |
status, headers, response = @app.call(env) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is an edited / streamlined version of code I'm writing for a production app. I haven't run this in a Ruby interpreter so I can't guarantee it's typo-free, but this is the gist of how we're handling the problem of presenting CMS content as if it's part of our Rails app.