middleman-proxy 0.0.1

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.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in middleman-proxy.gemspec
4
+ gemspec
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,204 @@
1
+ # ===========================================================================
2
+ # Original Project: Abbot - SproutCore Build Tools
3
+ # Copyright: ©2009 Apple Inc.
4
+ # portions copyright @2006-2011 Strobe Inc.
5
+ # and contributors
6
+ # ===========================================================================
7
+
8
+ begin
9
+ require 'net/https'
10
+ Middleman::HTTPS_ENABLED = true
11
+ rescue LoadError => e
12
+ require 'net/http'
13
+ Middleman::HTTPS_ENABLED = false
14
+ end
15
+
16
+ module Middleman
17
+ module Features
18
+ module Proxy
19
+
20
+ class << self
21
+ def registered(app)
22
+ app.extend ClassMethods
23
+ app.use Middleman::Features::Proxy::Rack
24
+ end
25
+ alias :included :registered
26
+ end
27
+
28
+ class Collection
29
+ def initialize(app)
30
+ @app = app
31
+ end
32
+
33
+ def self.proxies
34
+ @@proxies ||= {}
35
+ end
36
+
37
+ def self.add(path, options={})
38
+ @@proxies ||= {}
39
+ @@proxies[path] = options
40
+ end
41
+ end
42
+
43
+ module ClassMethods
44
+ # Proxies requests to the path
45
+ #
46
+ #
47
+ # require 'middleman-proxy'
48
+ # activate :proxy
49
+ #
50
+ # proxy '/an_api_path', :to => "your-api-hostname.com"
51
+ # proxy '/ssl_api_path', :to => "your-other-api-hostname.com", :secure => true
52
+ def proxy(path, options={})
53
+ Middleman::Features::Proxy::Collection.add(path, options)
54
+ end
55
+ end
56
+
57
+ # Rack application proxies requests as needed for the given project.
58
+ class Rack
59
+
60
+ def initialize(app)
61
+ @app = app
62
+ end
63
+
64
+ def call(env)
65
+ url = env['PATH_INFO']
66
+
67
+ @proxies = Middleman::Features::Proxy::Collection.proxies
68
+ @proxies.each do |proxy, value|
69
+ if url.match(/^#{Regexp.escape(proxy.to_s)}/)
70
+ return handle_proxy(value, proxy.to_s, env)
71
+ end
72
+ end
73
+
74
+ @app.call(env)
75
+ end
76
+
77
+ def handle_proxy(proxy, proxy_url, env)
78
+ if proxy[:secure] && !Middleman::HTTPS_ENABLED
79
+ $stderr.puts "~ WARNING: HTTPS is not supported on your system, using HTTP instead.\n"
80
+ $stderr.puts" If you are using Ubuntu, you can run `apt-get install libopenssl-ruby`\n"
81
+ proxy[:secure] = false
82
+ end
83
+
84
+ origin_host = env['SERVER_NAME'] # capture the origin host for cookies
85
+ http_method = env['REQUEST_METHOD'].to_s.downcase
86
+ url = env['PATH_INFO']
87
+ params = env['QUERY_STRING']
88
+
89
+ # collect headers...
90
+ headers = {}
91
+ env.each do |key, value|
92
+ next unless key =~ /^HTTP_/
93
+ key = key.gsub(/^HTTP_/,'').downcase.sub(/^\w/){|l| l.upcase}.gsub(/_(\w)/){|l| "-#{$1.upcase}"} # remove HTTP_, dasherize and titleize
94
+ if !key.eql? "Version"
95
+ headers[key] = value
96
+ end
97
+ end
98
+
99
+ # Rack documentation says CONTENT_TYPE and CONTENT_LENGTH aren't prefixed by HTTP_
100
+ headers['Content-Type'] = env['CONTENT_TYPE'] if env['CONTENT_TYPE']
101
+
102
+ length = env['CONTENT_LENGTH']
103
+ headers['Content-Length'] = length if length
104
+
105
+ http_host, http_port = proxy[:to].split(':')
106
+ http_port = proxy[:secure] ? '443' : '80' if http_port.nil?
107
+
108
+ # added 4/23/09 per Charles Jolley, corrects problem
109
+ # when making requests to virtual hosts
110
+ headers['Host'] = "#{http_host}:#{http_port}"
111
+
112
+ if proxy[:url]
113
+ url = url.sub(/^#{Regexp.escape proxy_url}/, proxy[:url])
114
+ end
115
+
116
+ http_path = [url]
117
+ http_path << params if params && params.size>0
118
+ http_path = http_path.join('?')
119
+
120
+ response = nil
121
+ no_body_method = %w(get copy head move options trace)
122
+
123
+ done = false
124
+ tries = 0
125
+ until done
126
+ http = ::Net::HTTP.new(http_host, http_port)
127
+
128
+ if proxy[:secure]
129
+ http.use_ssl = true
130
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
131
+ end
132
+
133
+ http.start do |web|
134
+ if no_body_method.include?(http_method)
135
+ response = web.send(http_method, http_path, headers)
136
+ else
137
+ http_body = env['rack.input']
138
+ http_body.rewind # May not be necessary but can't hurt
139
+
140
+ req = Net::HTTPGenericRequest.new(http_method.upcase,
141
+ true, true, http_path, headers)
142
+ req.body_stream = http_body if length.to_i > 0
143
+ response = web.request(req)
144
+ end
145
+ end
146
+
147
+ status = response.code # http status code
148
+ protocol = proxy[:secure] ? 'https' : 'http'
149
+
150
+ $stderr.puts "~ PROXY: #{http_method.upcase} #{status} #{url} -> #{protocol}://#{http_host}:#{http_port}#{http_path}\n"
151
+
152
+ # display and construct specific response headers
153
+ response_headers = {}
154
+ ignore_headers = ['transfer-encoding', 'keep-alive', 'connection']
155
+ response.each do |key, value|
156
+ next if ignore_headers.include?(key.downcase)
157
+ # If this is a cookie, strip out the domain. This technically may
158
+ # break certain scenarios where services try to set cross-domain
159
+ # cookies, but those services should not be doing that anyway...
160
+ value.gsub!(/domain=[^\;]+\;? ?/,'') if key.downcase == 'set-cookie'
161
+ # Location headers should rewrite the hostname if it is included.
162
+ value.gsub!(/^http:\/\/#{http_host}(:[0-9]+)?\//, "http://#{http_host}/") if key.downcase == 'location'
163
+ # content-length is returning char count not bytesize
164
+ if key.downcase == 'content-length'
165
+ if response.body.respond_to?(:bytesize)
166
+ value = response.body.bytesize.to_s
167
+ elsif response.body.respond_to?(:size)
168
+ value = response.body.size.to_s
169
+ else
170
+ value = '0'
171
+ end
172
+ end
173
+
174
+ $stderr << " #{key}: #{value}\n"
175
+ response_headers[key] = value
176
+ end
177
+
178
+ if [301, 302, 303, 307].include?(status.to_i) && proxy[:redirect] != false
179
+ $stderr.puts '~ REDIRECTING: '+response_headers['location']+"\n"
180
+
181
+ uri = URI.parse(response_headers['location']);
182
+ http_host = uri.host
183
+ http_port = uri.port
184
+ http_path = uri.path
185
+ http_path += '?'+uri.query if uri.query
186
+
187
+ tries += 1
188
+ if tries > 10
189
+ raise "Too many redirects!"
190
+ end
191
+ else
192
+ done = true
193
+ end
194
+ end
195
+
196
+ # Thin doesn't like null bodies
197
+ response_body = response.body || ''
198
+
199
+ return [status, ::Rack::Utils::HeaderHash.new(response_headers), [response_body]]
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,5 @@
1
+ module Middleman
2
+ module Proxy
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "middleman-proxy/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "middleman-proxy"
7
+ s.version = Middleman::Proxy::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Thomas Reynolds"]
10
+ s.email = ["me@tdreyno.com"]
11
+ s.homepage = "https://github.com/tdreyno/middleman-proxy"
12
+ s.summary = %q{Remote Data for your Middleman Project}
13
+
14
+ s.rubyforge_project = "middleman-proxy"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency("middleman", ["~> 2.0.0"])
22
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: middleman-proxy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Thomas Reynolds
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-10 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: middleman
16
+ requirement: &70172523644140 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70172523644140
25
+ description:
26
+ email:
27
+ - me@tdreyno.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - Rakefile
35
+ - lib/middleman-proxy.rb
36
+ - lib/middleman-proxy/.DS_Store
37
+ - lib/middleman-proxy/version.rb
38
+ - middleman-proxy.gemspec
39
+ homepage: https://github.com/tdreyno/middleman-proxy
40
+ licenses: []
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project: middleman-proxy
59
+ rubygems_version: 1.8.10
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Remote Data for your Middleman Project
63
+ test_files: []