httpdisk 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,102 @@
1
+ require 'faraday'
2
+
3
+ module HTTPDisk
4
+ OPTIONS = {
5
+ dir: File.join(ENV['HOME'], 'httpdisk'),
6
+ expires_in: nil,
7
+ force: false,
8
+ force_errors: false,
9
+ }.freeze
10
+
11
+ # Middleware and main entry point.
12
+ class Client < Faraday::Middleware
13
+ attr_reader :cache, :options
14
+
15
+ def initialize(app, options = {})
16
+ super(app, options = OPTIONS.merge(options.compact))
17
+ @cache = Cache.new(options)
18
+ end
19
+
20
+ def call(env)
21
+ cache_key = CacheKey.new(env)
22
+
23
+ # hit?
24
+ if cached_response = read(cache_key, env)
25
+ return cached_response
26
+ end
27
+
28
+ # miss
29
+ perform(cache_key, env).tap do |response|
30
+ write(cache_key, env, response)
31
+ end
32
+ end
33
+
34
+ # Returns cache status for this request
35
+ def status(env)
36
+ cache_key = CacheKey.new(env)
37
+ {
38
+ url: env.url.to_s,
39
+ status: cache.status(cache_key).to_s,
40
+ key: cache_key.key,
41
+ digest: cache_key.digest,
42
+ path: cache.diskpath(cache_key),
43
+ }
44
+ end
45
+
46
+ protected
47
+
48
+ # perform the request, return Faraday::Response
49
+ def perform(cache_key, env)
50
+ app.call(env)
51
+ rescue Faraday::ConnectionFailed, Faraday::SSLError, Faraday::TimeoutError => e
52
+ # try to avoid caching proxy errors
53
+ raise e if proxy_error?(env, e)
54
+
55
+ stuff_999_response(env, e)
56
+ end
57
+
58
+ # read from cache return Faraday::Response
59
+ def read(cache_key, env)
60
+ payload = cache.read(cache_key)
61
+ return if !payload
62
+
63
+ env.tap do
64
+ _1.reason_phrase = payload.reason_phrase
65
+ _1.response_body = payload.body
66
+ _1.response_headers = payload.headers
67
+ _1.status = payload.status
68
+ end
69
+ Faraday::Response.new(env)
70
+ end
71
+
72
+ # write Faraday::Response to cache
73
+ def write(cache_key, env, response)
74
+ payload = Payload.from_response(response).tap do
75
+ _1.comment = "#{env.method.upcase} #{env.url}"
76
+ end
77
+ cache.write(cache_key, payload)
78
+ end
79
+
80
+ # stuff a 999 error into env and create a Faraday::Response
81
+ def stuff_999_response(env, err)
82
+ env.tap do
83
+ _1.reason_phrase = "#{err.class} #{err.message}"
84
+ _1.response_body = ''
85
+ _1.response_headers = Faraday::Utils::Headers.new
86
+ _1.status = HTTPDisk::ERROR_STATUS
87
+ end
88
+ Faraday::Response.new(env)
89
+ end
90
+
91
+ def proxy_error?(env, err)
92
+ proxy = env.request.proxy
93
+ return if !proxy
94
+ return if !err.is_a?(Faraday::ConnectionFailed)
95
+
96
+ err.to_s =~ /#{proxy.host}.*#{proxy.port}/
97
+ end
98
+ end
99
+ end
100
+
101
+ # register
102
+ Faraday::Middleware.register_middleware(httpdisk: HTTPDisk::Client)
@@ -0,0 +1,3 @@
1
+ module HTTPDisk
2
+ class CliError < StandardError; end
3
+ end
@@ -0,0 +1,61 @@
1
+ module HTTPDisk
2
+ class Payload
3
+ class << self
4
+ def read(f)
5
+ Payload.new.tap do |p|
6
+ # comment
7
+ p.comment = f.gets[/^# (.*)/, 1]
8
+
9
+ # status line
10
+ m = f.gets.match(%r{^HTTPDISK (\d+) (.*)$})
11
+ p.status, p.reason_phrase = m[1].to_i, m[2]
12
+
13
+ # headers
14
+ while (line = f.gets.chomp) && !line.empty?
15
+ key, value = line.split(': ', 2)
16
+ p.headers[key] = value
17
+ end
18
+
19
+ # body
20
+ p.body = f.read
21
+ end
22
+ end
23
+
24
+ def from_response(response)
25
+ Payload.new.tap do
26
+ _1.body = response.body
27
+ _1.headers = response.headers
28
+ _1.reason_phrase = response.reason_phrase
29
+ _1.status = response.status
30
+ end
31
+ end
32
+ end
33
+
34
+ attr_accessor :body, :comment, :headers, :reason_phrase, :status
35
+
36
+ def initialize
37
+ @body = ''
38
+ @comment = ''
39
+ @headers = Faraday::Utils::Headers.new
40
+ end
41
+
42
+ def error_999?
43
+ status == HTTPDisk::ERROR_STATUS
44
+ end
45
+
46
+ def write(f)
47
+ # comment
48
+ f.puts "# #{comment}"
49
+
50
+ # status line
51
+ f.puts "HTTPDISK #{status} #{reason_phrase}"
52
+
53
+ # headers
54
+ headers.each { f.puts("#{_1}: #{_2}") }
55
+ f.puts
56
+
57
+ # body
58
+ f.write(body)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ module HTTPDisk
2
+ VERSION = '0.1.0'.freeze
3
+ end
data/logo.svg ADDED
@@ -0,0 +1,12 @@
1
+ <svg width="520" height="200" viewBox="0 0 520 200" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="520" height="200" fill="#B3ECFF"/>
3
+ <path d="M101.756 127.616C101.052 127.808 99.9324 128 98.3964 128.192C96.9244 128.384 95.4524 128.48 93.9804 128.48C92.5084 128.48 91.1964 128.352 90.0444 128.096C88.9564 127.904 88.0284 127.52 87.2604 126.944C86.4924 126.368 85.9164 125.568 85.5324 124.544C85.1484 123.52 84.9564 122.176 84.9564 120.512V105.536H66.5244V127.616C65.8204 127.808 64.7004 128 63.1644 128.192C61.6924 128.384 60.2204 128.48 58.7484 128.48C57.2764 128.48 55.9644 128.352 54.8124 128.096C53.7244 127.904 52.7964 127.52 52.0284 126.944C51.2604 126.368 50.6844 125.568 50.3004 124.544C49.9164 123.52 49.7244 122.176 49.7244 120.512V69.824C50.4284 69.696 51.5484 69.536 53.0844 69.344C54.6204 69.088 56.0924 68.96 57.5004 68.96C58.9724 68.96 60.2524 69.088 61.3404 69.344C62.4924 69.536 63.4524 69.92 64.2204 70.496C64.9884 71.072 65.5644 71.872 65.9484 72.896C66.3324 73.92 66.5244 75.264 66.5244 76.928V92.288H84.9564V69.824C85.6604 69.696 86.7804 69.536 88.3164 69.344C89.8524 69.088 91.3244 68.96 92.7324 68.96C94.2044 68.96 95.4844 69.088 96.5724 69.344C97.7244 69.536 98.6844 69.92 99.4524 70.496C100.22 71.072 100.796 71.872 101.18 72.896C101.564 73.92 101.756 75.264 101.756 76.928V127.616Z" fill="#0186B3"/>
4
+ <path d="M111.536 83.264C111.088 82.56 110.672 81.6 110.288 80.384C109.904 79.168 109.712 77.888 109.712 76.544C109.712 74.048 110.256 72.256 111.344 71.168C112.496 70.08 113.968 69.536 115.76 69.536H157.616C158.064 70.24 158.48 71.2 158.864 72.416C159.248 73.632 159.44 74.912 159.44 76.256C159.44 78.752 158.864 80.544 157.712 81.632C156.624 82.72 155.184 83.264 153.392 83.264H142.736V127.616C142.032 127.808 140.912 128 139.376 128.192C137.904 128.384 136.432 128.48 134.96 128.48C133.488 128.48 132.176 128.352 131.024 128.096C129.936 127.904 129.008 127.52 128.24 126.944C127.472 126.368 126.896 125.568 126.512 124.544C126.128 123.52 125.936 122.176 125.936 120.512V83.264H111.536Z" fill="#0186B3"/>
5
+ <path d="M165.818 83.264C165.37 82.56 164.954 81.6 164.57 80.384C164.186 79.168 163.994 77.888 163.994 76.544C163.994 74.048 164.538 72.256 165.626 71.168C166.778 70.08 168.25 69.536 170.042 69.536H211.898C212.346 70.24 212.762 71.2 213.146 72.416C213.53 73.632 213.722 74.912 213.722 76.256C213.722 78.752 213.146 80.544 211.994 81.632C210.906 82.72 209.466 83.264 207.674 83.264H197.018V127.616C196.314 127.808 195.194 128 193.658 128.192C192.186 128.384 190.714 128.48 189.242 128.48C187.77 128.48 186.458 128.352 185.306 128.096C184.218 127.904 183.29 127.52 182.522 126.944C181.754 126.368 181.178 125.568 180.794 124.544C180.41 123.52 180.218 122.176 180.218 120.512V83.264H165.818Z" fill="#0186B3"/>
6
+ <path d="M243.641 96.8C246.329 96.8 248.377 96.192 249.785 94.976C251.257 93.696 251.993 91.776 251.993 89.216C251.993 86.784 251.225 84.928 249.689 83.648C248.217 82.304 246.041 81.632 243.161 81.632C242.137 81.632 241.273 81.664 240.569 81.728C239.929 81.728 239.257 81.792 238.553 81.92V96.8H243.641ZM238.649 127.616C237.945 127.808 236.825 128 235.289 128.192C233.817 128.384 232.345 128.48 230.873 128.48C229.401 128.48 228.089 128.352 226.937 128.096C225.849 127.904 224.921 127.52 224.153 126.944C223.385 126.368 222.809 125.568 222.425 124.544C222.041 123.52 221.849 122.176 221.849 120.512V75.296C221.849 73.952 222.201 72.928 222.905 72.224C223.673 71.456 224.697 70.848 225.977 70.4C228.153 69.632 230.617 69.088 233.369 68.768C236.185 68.384 239.001 68.192 241.817 68.192C250.649 68.192 257.401 70.08 262.073 73.856C266.745 77.632 269.081 82.752 269.081 89.216C269.081 92.352 268.569 95.2 267.545 97.76C266.585 100.256 265.113 102.432 263.129 104.288C261.209 106.08 258.745 107.488 255.737 108.512C252.793 109.472 249.369 109.952 245.465 109.952H238.649V127.616Z" fill="#0186B3"/>
7
+ <path d="M294.335 115.52C295.039 115.648 295.903 115.776 296.927 115.904C297.951 115.968 298.911 116 299.807 116C301.983 116 303.967 115.68 305.759 115.04C307.615 114.4 309.183 113.408 310.463 112.064C311.807 110.72 312.831 108.992 313.535 106.88C314.303 104.704 314.687 102.112 314.687 99.104C314.687 93.344 313.343 89.024 310.655 86.144C307.967 83.2 304.383 81.728 299.903 81.728C299.007 81.728 298.079 81.76 297.119 81.824C296.223 81.888 295.295 81.984 294.335 82.112V115.52ZM299.711 129.536C298.623 129.536 297.375 129.504 295.967 129.44C294.559 129.376 293.087 129.248 291.551 129.056C290.079 128.864 288.575 128.608 287.039 128.288C285.567 128.032 284.191 127.648 282.911 127.136C279.391 125.792 277.631 123.456 277.631 120.128V75.296C277.631 73.952 277.983 72.928 278.687 72.224C279.455 71.456 280.479 70.848 281.759 70.4C284.511 69.504 287.423 68.928 290.495 68.672C293.567 68.352 296.319 68.192 298.751 68.192C303.743 68.192 308.255 68.8 312.287 70.016C316.383 71.232 319.871 73.12 322.751 75.68C325.695 78.176 327.967 81.344 329.567 85.184C331.167 89.024 331.967 93.568 331.967 98.816C331.967 103.936 331.199 108.416 329.663 112.256C328.127 116.032 325.919 119.232 323.039 121.856C320.223 124.416 316.831 126.336 312.863 127.616C308.895 128.896 304.511 129.536 299.711 129.536Z" fill="#0186B3"/>
8
+ <path d="M358.368 127.616C357.664 127.808 356.544 128 355.008 128.192C353.536 128.384 352.064 128.48 350.592 128.48C349.12 128.48 347.808 128.352 346.656 128.096C345.568 127.904 344.64 127.52 343.872 126.944C343.104 126.368 342.528 125.568 342.144 124.544C341.76 123.52 341.568 122.176 341.568 120.512V69.824C342.272 69.696 343.392 69.536 344.928 69.344C346.464 69.088 347.936 68.96 349.344 68.96C350.816 68.96 352.096 69.088 353.184 69.344C354.336 69.536 355.296 69.92 356.064 70.496C356.832 71.072 357.408 71.872 357.792 72.896C358.176 73.92 358.368 75.264 358.368 76.928V127.616Z" fill="#0186B3"/>
9
+ <path d="M387.33 104.864C384.514 103.904 381.954 102.944 379.65 101.984C377.346 100.96 375.362 99.744 373.698 98.336C372.034 96.928 370.722 95.264 369.762 93.344C368.866 91.36 368.418 88.96 368.418 86.144C368.418 80.704 370.498 76.352 374.658 73.088C378.882 69.824 384.77 68.192 392.322 68.192C395.074 68.192 397.634 68.384 400.002 68.768C402.37 69.152 404.386 69.76 406.05 70.592C407.778 71.36 409.122 72.384 410.082 73.664C411.042 74.88 411.522 76.32 411.522 77.984C411.522 79.648 411.138 81.088 410.37 82.304C409.602 83.456 408.674 84.448 407.586 85.28C406.178 84.384 404.29 83.616 401.922 82.976C399.554 82.272 396.962 81.92 394.146 81.92C391.266 81.92 389.154 82.336 387.81 83.168C386.466 83.936 385.794 84.928 385.794 86.144C385.794 87.104 386.21 87.904 387.042 88.544C387.874 89.12 389.122 89.664 390.786 90.176L395.874 91.808C401.89 93.728 406.498 96.192 409.698 99.2C412.962 102.144 414.594 106.176 414.594 111.296C414.594 116.736 412.45 121.152 408.162 124.544C403.874 127.872 397.57 129.536 389.25 129.536C386.306 129.536 383.554 129.28 380.994 128.768C378.498 128.32 376.29 127.648 374.37 126.752C372.514 125.792 371.042 124.64 369.954 123.296C368.93 121.888 368.418 120.288 368.418 118.496C368.418 116.64 368.962 115.072 370.05 113.792C371.138 112.448 372.322 111.424 373.602 110.72C375.394 112.128 377.57 113.344 380.13 114.368C382.754 115.392 385.602 115.904 388.674 115.904C391.81 115.904 394.018 115.424 395.298 114.464C396.578 113.504 397.218 112.384 397.218 111.104C397.218 109.824 396.706 108.864 395.682 108.224C394.658 107.52 393.218 106.848 391.362 106.208L387.33 104.864Z" fill="#0186B3"/>
10
+ <path d="M440.589 106.4V127.616C439.885 127.808 438.765 128 437.229 128.192C435.693 128.384 434.189 128.48 432.717 128.48C431.245 128.48 429.933 128.352 428.781 128.096C427.693 127.904 426.765 127.52 425.997 126.944C425.229 126.368 424.653 125.568 424.269 124.544C423.885 123.52 423.693 122.176 423.693 120.512V69.824C424.397 69.696 425.517 69.536 427.053 69.344C428.589 69.088 430.061 68.96 431.469 68.96C432.941 68.96 434.221 69.088 435.309 69.344C436.461 69.536 437.421 69.92 438.189 70.496C438.957 71.072 439.533 71.872 439.917 72.896C440.301 73.92 440.493 75.264 440.493 76.928V92.192L460.461 69.248C464.813 69.248 467.917 70.08 469.773 71.744C471.693 73.344 472.653 75.264 472.653 77.504C472.653 79.168 472.237 80.736 471.405 82.208C470.573 83.68 469.229 85.344 467.373 87.2L455.373 99.2C456.973 100.992 458.637 102.848 460.365 104.768C462.157 106.688 463.885 108.576 465.549 110.432C467.277 112.224 468.909 113.952 470.445 115.616C472.045 117.28 473.421 118.72 474.573 119.936C474.573 121.344 474.317 122.592 473.805 123.68C473.293 124.768 472.589 125.696 471.693 126.464C470.861 127.232 469.901 127.808 468.813 128.192C467.725 128.576 466.573 128.768 465.357 128.768C462.733 128.768 460.589 128.128 458.925 126.848C457.261 125.504 455.661 123.936 454.125 122.144L440.589 106.4Z" fill="#0186B3"/>
11
+ <rect x="0.5" y="0.5" width="519" height="199" stroke="black" stroke-opacity="0.5"/>
12
+ </svg>
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: httpdisk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Doppelt
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-04-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday-cookie_jar
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday_middleware
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: slop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.8'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '4.8'
69
+ description: httpdisk works with faraday to aggressively cache responses on disk.
70
+ email: amd@gurge.com
71
+ executables:
72
+ - httpdisk
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".github/workflows/test.yml"
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - LICENSE
81
+ - README.md
82
+ - Rakefile
83
+ - bin/httpdisk
84
+ - examples.rb
85
+ - httpdisk.gemspec
86
+ - lib/httpdisk.rb
87
+ - lib/httpdisk/cache.rb
88
+ - lib/httpdisk/cache_key.rb
89
+ - lib/httpdisk/cli.rb
90
+ - lib/httpdisk/cli_slop.rb
91
+ - lib/httpdisk/client.rb
92
+ - lib/httpdisk/error.rb
93
+ - lib/httpdisk/payload.rb
94
+ - lib/httpdisk/version.rb
95
+ - logo.svg
96
+ homepage: http://github.com/gurgeous/httpdisk
97
+ licenses:
98
+ - MIT
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: 2.7.0
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubygems_version: 3.1.4
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: httpdisk - disk cache for faraday
119
+ test_files: []