read-only-mode 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 789458ccf4c3a3659e0f5ff50b69f5ce25dec31eedf1d6828b58b57bbb14c3eb
4
+ data.tar.gz: 33b10e31a9daf2d6a5d02ff77672781adb199571149d44b0ad3c7f3327bca895
5
+ SHA512:
6
+ metadata.gz: 05e8f74a2c93cbf9e4c907e80b24c4c2f81644adf166642d419f77d27fb765595c2fc22a8009b32e3eaf841adba5e0eefef0ce0e6ae0e3942f699862c64f57ae
7
+ data.tar.gz: c8dcc9577f73b9652f77f7dd9efe348926dca038b71eaad7a56fc988b8af23fe0342157f73f166148f79b92299c47e766856f177388992461217e0e1aa14f9e6
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Initial release
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # Read Only Mode
2
+
3
+ A simple ruby gem for adding read only maintenance mode to your Rails / Rack applications.
4
+
5
+ When read only mode is enabled, all non GET / HEAD requests will be rejected with a 503 Service Unavailable response. Additionally the 503 response will be given in case a GET request would raise a `PG::ReadOnlySqlTransaction` error.
6
+
7
+ ## Installation
8
+
9
+ Add the line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem "read_only_mode"
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ Read only mode is enabled via environment variables. There are two options, either:
18
+
19
+ Set `READ_ONLY_MODE=true`
20
+
21
+ Or...
22
+
23
+ Set `PGOPTIONS="-c default_transaction_read_only=on"` (or any other string containing `default_transaction_read_only=on`).
24
+
25
+ The `PGOPTIONS` approach is recommended for applications using Postgres as this will prevent any write queries from being executed.
26
+
27
+ ### Rack integration
28
+
29
+ Rails applications will automatically use the middleware via a Railtie. For other Rack applications, you can add the middleware manually:
30
+
31
+ ```ruby
32
+ use ReadOnlyMode::Middleware if ReadOnlyMode.enabled?
33
+ ```
34
+
35
+ ## Configuration
36
+
37
+ You can customize the HTML / JSON responses returned when read only mode is enabled via some simple setters:
38
+
39
+ ```ruby
40
+ ReadOnlyMode.html_response = File.read("path/to/your/read_only.html")
41
+ ReadOnlyMode.json_response = { error: "Maintenance in progress" }.to_json
42
+ ```
data/lib/middleware.rb ADDED
@@ -0,0 +1,28 @@
1
+ module ReadOnlyMode
2
+ class Middleware
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ if env["REQUEST_METHOD"] == "GET" || env["REQUEST_METHOD"] == "HEAD"
9
+ @app.call(env)
10
+ else
11
+ render_503(env)
12
+ end
13
+ rescue PG::ReadOnlySqlTransaction
14
+ render_503(env)
15
+ end
16
+
17
+ private
18
+
19
+ # 503 Service Unavailable with HTML or JSON depending on accept header
20
+ def render_503(env)
21
+ if env["HTTP_ACCEPT"] == "application/json"
22
+ [503, { "content-type" => "application/json; charset=utf-8" }, [ReadOnlyMode.json_response]]
23
+ else
24
+ [503, { "content-type" => "text/html; charset=utf-8" }, [ReadOnlyMode.html_response]]
25
+ end
26
+ end
27
+ end
28
+ end
data/lib/railtie.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ReadOnlyMode
4
+ class Railtie < Rails::Railtie
5
+ initializer "read-only-mode.configure_rails_initialization" do |app|
6
+ app.middleware.insert_before 0, ReadOnlyMode::Middleware if ReadOnlyMode.enabled?
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Read-only maintenance in progress</title>
5
+ </head>
6
+ <body style="height: 100vh; background: linear-gradient(198deg, rgba(242,242,242,1) 0%, rgba(239,251,255,1) 100%); font-family: sans-serif; text-align: center;">
7
+ <div style="display: flex; height: 100vh">
8
+ <div style="margin: auto; height: 250px;">
9
+ <h1 style="font-weight: 200; color: #2c3647">Maintenance in progress</h1>
10
+ <p style="line-height: 1.8rem; color: #555a64">This app is undergoing maintenance right now.<br>Some actions are unavailable.<br>Please check back later 🙏</p>
11
+ </div>
12
+ </div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module ReadOnlyMode
6
+ DEFALT_HTML_RESPONSE = File.read(File.expand_path("read-only-mode.html", __dir__))
7
+ DEFAULT_JSON_RESPONSE = { error: "Application is in read-only maintenance mode. Please try again later." }.to_json
8
+
9
+ def self.enabled?
10
+ ENV["READ_ONLY_MODE"] == "true" || ENV["PGOPTIONS"]&.include?("default_transaction_read_only=on")
11
+ end
12
+
13
+ def self.html_response=(html_response)
14
+ @html_response = html_response
15
+ end
16
+
17
+ def self.html_response
18
+ @html_response ||= DEFALT_HTML_RESPONSE
19
+ end
20
+
21
+ def self.json_response=(json_response)
22
+ @json_response = json_response
23
+ end
24
+
25
+ def self.json_response
26
+ @json_response ||= DEFAULT_JSON_RESPONSE
27
+ end
28
+ end
29
+
30
+ require_relative "middleware"
31
+ require_relative "railtie" if defined? Rails::Railtie
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "read-only-mode"
3
+ spec.version = "0.1.0"
4
+ spec.authors = ["David Backeus"]
5
+ spec.email = ["david.backeus@mynewsdesk.com"]
6
+ spec.summary = "Simple read-only maintenance mode for Rails and Rack based web applications"
7
+ spec.homepage = "https://github.com/reclaim-the-stack/read-only-mode"
8
+ spec.license = "MIT"
9
+ spec.metadata = {
10
+ "homepage_uri" => spec.homepage,
11
+ "source_code_uri" => spec.homepage,
12
+ "changelog_uri" => "#{spec.homepage}/blob/master/CHANGELOG.md"
13
+ }
14
+ spec.files = %w[README.md CHANGELOG.md read-only-mode.gemspec] + Dir["lib/**/*"]
15
+
16
+ spec.required_ruby_version = ">= 2.7.0"
17
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: read-only-mode
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - David Backeus
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-02-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - david.backeus@mynewsdesk.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - CHANGELOG.md
21
+ - README.md
22
+ - lib/middleware.rb
23
+ - lib/railtie.rb
24
+ - lib/read-only-mode.html
25
+ - lib/read-only-mode.rb
26
+ - read-only-mode.gemspec
27
+ homepage: https://github.com/reclaim-the-stack/read-only-mode
28
+ licenses:
29
+ - MIT
30
+ metadata:
31
+ homepage_uri: https://github.com/reclaim-the-stack/read-only-mode
32
+ source_code_uri: https://github.com/reclaim-the-stack/read-only-mode
33
+ changelog_uri: https://github.com/reclaim-the-stack/read-only-mode/blob/master/CHANGELOG.md
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 2.7.0
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements: []
49
+ rubygems_version: 3.5.0.dev
50
+ signing_key:
51
+ specification_version: 4
52
+ summary: Simple read-only maintenance mode for Rails and Rack based web applications
53
+ test_files: []