gumdrop 0.3.10 → 0.4.0
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.
- data/ChangeLog.md +3 -0
- data/lib/gumdrop.rb +2 -1
- data/lib/gumdrop/proxy_handler.rb +153 -0
- data/lib/gumdrop/server.rb +63 -5
- data/lib/gumdrop/version.rb +1 -1
- metadata +18 -17
data/ChangeLog.md
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# v0.4
|
2
|
+
- Added support for special dev proxy at /-proxy/ENDPOINT_URL -- Useful for working with external (non-CORS) apis/websites. Enabled by default. To disable, set Gumdrop.config.proxy_enabled= false
|
3
|
+
|
1
4
|
# v0.3.10
|
2
5
|
- Added 'ignore' dsl command -- keeps the node in the memory, but doesn't render/copy it on build.
|
3
6
|
|
data/lib/gumdrop.rb
CHANGED
@@ -0,0 +1,153 @@
|
|
1
|
+
#
|
2
|
+
# Based on code from MiddleMan Proxy:
|
3
|
+
# https://github.com/middleman/middleman-proxy/blob/master/lib/middleman-proxy.rb
|
4
|
+
#
|
5
|
+
# Which in turn looks to be based on Apple Code:
|
6
|
+
# # ===========================================================================
|
7
|
+
# # Original Project: Abbot - SproutCore Build Tools
|
8
|
+
# # Copyright: ©2009 Apple Inc.
|
9
|
+
# # portions copyright @2006-2011 Strobe Inc.
|
10
|
+
# # and contributors
|
11
|
+
# # ===========================================================================
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'net/https'
|
15
|
+
HTTPS_ENABLED = true
|
16
|
+
rescue LoadError => e
|
17
|
+
require 'net/http'
|
18
|
+
HTTPS_ENABLED = false
|
19
|
+
end
|
20
|
+
|
21
|
+
#require "net/http"
|
22
|
+
require "uri"
|
23
|
+
|
24
|
+
module Gumdrop
|
25
|
+
|
26
|
+
def self.handle_proxy(proxy, proxy_url, env)
|
27
|
+
if proxy[:secure] && !HTTPS_ENABLED
|
28
|
+
$stderr.puts "~ WARNING: HTTPS is not supported on your system, using HTTP instead.\n"
|
29
|
+
$stderr.puts" If you are using Ubuntu, you can run `apt-get install libopenssl-ruby`\n"
|
30
|
+
proxy[:secure] = false
|
31
|
+
end
|
32
|
+
|
33
|
+
origin_host = env['SERVER_NAME'] # capture the origin host for cookies
|
34
|
+
http_method = env['REQUEST_METHOD'].to_s.downcase
|
35
|
+
url = proxy[:path_info] #proxy_url #env['PATH_INFO']
|
36
|
+
params = env['QUERY_STRING']
|
37
|
+
|
38
|
+
puts "PROXY: -> #{url}"
|
39
|
+
|
40
|
+
# collect headers...
|
41
|
+
headers = {}
|
42
|
+
env.each do |key, value|
|
43
|
+
next unless key =~ /^HTTP_/
|
44
|
+
key = key.gsub(/^HTTP_/,'').downcase.sub(/^\w/){|l| l.upcase}.gsub(/_(\w)/){|l| "-#{$1.upcase}"} # remove HTTP_, dasherize and titleize
|
45
|
+
if !key.eql? "Version"
|
46
|
+
headers[key] = value
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Rack documentation says CONTENT_TYPE and CONTENT_LENGTH aren't prefixed by HTTP_
|
51
|
+
headers['Content-Type'] = env['CONTENT_TYPE'] if env['CONTENT_TYPE']
|
52
|
+
|
53
|
+
length = env['CONTENT_LENGTH']
|
54
|
+
headers['Content-Length'] = length if length
|
55
|
+
|
56
|
+
http_host, http_port = proxy[:to].split(':')
|
57
|
+
http_port = proxy[:secure] ? '443' : '80' if http_port.nil?
|
58
|
+
|
59
|
+
# added 4/23/09 per Charles Jolley, corrects problem
|
60
|
+
# when making requests to virtual hosts
|
61
|
+
headers['Host'] = "#{http_host}:#{http_port}"
|
62
|
+
|
63
|
+
if proxy[:url]
|
64
|
+
url = url.sub(/^#{Regexp.escape proxy_url}/, proxy[:url])
|
65
|
+
end
|
66
|
+
|
67
|
+
http_path = [url]
|
68
|
+
http_path << params if params && params.size>0
|
69
|
+
http_path = http_path.join('?')
|
70
|
+
|
71
|
+
response = nil
|
72
|
+
no_body_method = %w(get copy head move options trace)
|
73
|
+
|
74
|
+
done = false
|
75
|
+
tries = 0
|
76
|
+
until done
|
77
|
+
http = ::Net::HTTP.new(http_host, http_port)
|
78
|
+
|
79
|
+
if proxy[:secure]
|
80
|
+
http.use_ssl = true
|
81
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
82
|
+
end
|
83
|
+
|
84
|
+
http.start do |web|
|
85
|
+
if no_body_method.include?(http_method)
|
86
|
+
response = web.send(http_method, http_path, headers)
|
87
|
+
else
|
88
|
+
http_body = env['rack.input']
|
89
|
+
http_body.rewind # May not be necessary but can't hurt
|
90
|
+
|
91
|
+
req = Net::HTTPGenericRequest.new(http_method.upcase,
|
92
|
+
true, true, http_path, headers)
|
93
|
+
req.body_stream = http_body if length.to_i > 0
|
94
|
+
response = web.request(req)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
status = response.code # http status code
|
99
|
+
protocol = proxy[:secure] ? 'https' : 'http'
|
100
|
+
|
101
|
+
$stderr.puts "~ PROXY: #{http_method.upcase} #{status} #{url} -> #{protocol}://#{http_host}:#{http_port}#{http_path}\n"
|
102
|
+
|
103
|
+
# display and construct specific response headers
|
104
|
+
response_headers = {}
|
105
|
+
ignore_headers = ['transfer-encoding', 'keep-alive', 'connection']
|
106
|
+
response.each do |key, value|
|
107
|
+
next if ignore_headers.include?(key.downcase)
|
108
|
+
# If this is a cookie, strip out the domain. This technically may
|
109
|
+
# break certain scenarios where services try to set cross-domain
|
110
|
+
# cookies, but those services should not be doing that anyway...
|
111
|
+
value.gsub!(/domain=[^\;]+\;? ?/,'') if key.downcase == 'set-cookie'
|
112
|
+
# Location headers should rewrite the hostname if it is included.
|
113
|
+
value.gsub!(/^http:\/\/#{http_host}(:[0-9]+)?\//, "http://#{http_host}/") if key.downcase == 'location'
|
114
|
+
# content-length is returning char count not bytesize
|
115
|
+
if key.downcase == 'content-length'
|
116
|
+
if response.body.respond_to?(:bytesize)
|
117
|
+
value = response.body.bytesize.to_s
|
118
|
+
elsif response.body.respond_to?(:size)
|
119
|
+
value = response.body.size.to_s
|
120
|
+
else
|
121
|
+
value = '0'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
$stderr << " #{key}: #{value}\n"
|
126
|
+
response_headers[key] = value
|
127
|
+
end
|
128
|
+
|
129
|
+
if [301, 302, 303, 307].include?(status.to_i) && proxy[:redirect] != false
|
130
|
+
$stderr.puts '~ REDIRECTING: '+response_headers['location']+"\n"
|
131
|
+
|
132
|
+
uri = URI.parse(response_headers['location']);
|
133
|
+
http_host = uri.host
|
134
|
+
http_port = uri.port
|
135
|
+
http_path = uri.path
|
136
|
+
http_path += '?'+uri.query if uri.query
|
137
|
+
|
138
|
+
tries += 1
|
139
|
+
if tries > 10
|
140
|
+
raise "Too many redirects!"
|
141
|
+
end
|
142
|
+
else
|
143
|
+
done = true
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Thin doesn't like null bodies
|
148
|
+
response_body = response.body || ''
|
149
|
+
#::Rack::Utils::HeaderHash.new(response_headers)
|
150
|
+
return [status.to_i, response_headers, response_body.to_s]
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
data/lib/gumdrop/server.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'sinatra/base'
|
4
4
|
require 'logger'
|
5
5
|
|
6
|
-
|
7
6
|
module Gumdrop
|
8
7
|
|
9
8
|
class Server < Sinatra::Base
|
@@ -18,6 +17,48 @@ module Gumdrop
|
|
18
17
|
# end
|
19
18
|
|
20
19
|
Gumdrop.run dry_run:true, log:server_log
|
20
|
+
|
21
|
+
if Gumdrop.config.proxy_enabled
|
22
|
+
require 'gumdrop/proxy_handler'
|
23
|
+
Gumdrop.report 'Enabled proxy at /-proxy/*', :info
|
24
|
+
get '/-proxy/*' do
|
25
|
+
proxy_to= params[:splat][0]
|
26
|
+
proxy_parts= proxy_to.split('/')
|
27
|
+
host= proxy_parts.shift
|
28
|
+
path_info= "/#{proxy_parts.join('/')}"
|
29
|
+
#puts "HOST: #{host} PATH_INFO: #{path_info}"
|
30
|
+
opts={ :to=>host, :path_info=>path_info }
|
31
|
+
Gumdrop.handle_proxy opts, proxy_to, env
|
32
|
+
end
|
33
|
+
post '/-proxy/*' do
|
34
|
+
proxy_to= params[:splat][0]
|
35
|
+
proxy_parts= proxy_to.split('/')
|
36
|
+
host= proxy_parts.shift
|
37
|
+
path_info= "/#{proxy_parts.join('/')}"
|
38
|
+
#puts "HOST: #{host} PATH_INFO: #{path_info}"
|
39
|
+
opts={ :to=>host, :path_info=>path_info }
|
40
|
+
Gumdrop.handle_proxy opts, proxy_to, env
|
41
|
+
end
|
42
|
+
delete '/-proxy/*' do
|
43
|
+
proxy_to= params[:splat][0]
|
44
|
+
proxy_parts= proxy_to.split('/')
|
45
|
+
host= proxy_parts.shift
|
46
|
+
path_info= "/#{proxy_parts.join('/')}"
|
47
|
+
#puts "HOST: #{host} PATH_INFO: #{path_info}"
|
48
|
+
opts={ :to=>host, :path_info=>path_info }
|
49
|
+
Gumdrop.handle_proxy opts, proxy_to, env
|
50
|
+
end
|
51
|
+
put '/-proxy/*' do
|
52
|
+
proxy_to= params[:splat][0]
|
53
|
+
proxy_parts= proxy_to.split('/')
|
54
|
+
host= proxy_parts.shift
|
55
|
+
path_info= "/#{proxy_parts.join('/')}"
|
56
|
+
#puts "HOST: #{host} PATH_INFO: #{path_info}"
|
57
|
+
opts={ :to=>host, :path_info=>path_info }
|
58
|
+
Gumdrop.handle_proxy opts, proxy_to, env
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
21
62
|
|
22
63
|
get '/*' do
|
23
64
|
file_path= get_content_path params[:splat].join('/')
|
@@ -50,9 +91,26 @@ module Gumdrop
|
|
50
91
|
send_file File.join( source_base_path, file_path)
|
51
92
|
end
|
52
93
|
else
|
53
|
-
|
54
|
-
puts "
|
55
|
-
|
94
|
+
# uri_path= params[:splat].join('/')
|
95
|
+
# puts "LOOKING FOR: #{uri_path}"
|
96
|
+
# if uri_path =~ /^\-proxy\/(.*)$/
|
97
|
+
# uri= URI.parse "http://#{$1}"
|
98
|
+
#
|
99
|
+
# puts "PROXY TO: #{uri}"
|
100
|
+
#
|
101
|
+
# http = Net::HTTP.new(uri.host, uri.port)
|
102
|
+
# response = http.request(Net::HTTP::Get.new(uri.request_uri))
|
103
|
+
#
|
104
|
+
# #[response.code, response.body]
|
105
|
+
# #halt response.code, {}, response.body.to_s
|
106
|
+
# puts "Responded with: #{response.body.to_s}"
|
107
|
+
# #response
|
108
|
+
# [response.code.to_i, {}, response.body.to_s]
|
109
|
+
# else
|
110
|
+
Gumdrop.log.error "[#{$$}] *Missing: #{file_path}"
|
111
|
+
puts "NOT FOUND: #{file_path}"
|
112
|
+
"#{file_path} Not Found"
|
113
|
+
# end
|
56
114
|
end
|
57
115
|
end
|
58
116
|
|
@@ -71,7 +129,7 @@ module Gumdrop
|
|
71
129
|
end
|
72
130
|
|
73
131
|
if Gumdrop.config.auto_run
|
74
|
-
Gumdrop.run dry_run:true
|
132
|
+
#Gumdrop.run dry_run:true
|
75
133
|
run!
|
76
134
|
end
|
77
135
|
|
data/lib/gumdrop/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gumdrop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2011-07-22 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sinatra
|
16
|
-
requirement: &
|
16
|
+
requirement: &70152000645980 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70152000645980
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: tilt
|
27
|
-
requirement: &
|
27
|
+
requirement: &70152000645100 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70152000645100
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: active_support
|
38
|
-
requirement: &
|
38
|
+
requirement: &70152000644420 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70152000644420
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: trollop
|
49
|
-
requirement: &
|
49
|
+
requirement: &70152000632300 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70152000632300
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: haml
|
60
|
-
requirement: &
|
60
|
+
requirement: &70152000631540 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70152000631540
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: sass
|
71
|
-
requirement: &
|
71
|
+
requirement: &70152000631100 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70152000631100
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: i18n
|
82
|
-
requirement: &
|
82
|
+
requirement: &70152000630680 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70152000630680
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: bundle
|
93
|
-
requirement: &
|
93
|
+
requirement: &70152000630200 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ! '>='
|
@@ -98,7 +98,7 @@ dependencies:
|
|
98
98
|
version: '0'
|
99
99
|
type: :runtime
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70152000630200
|
102
102
|
description: A simple cms/prototyping tool.
|
103
103
|
email: matt@elucidata.net
|
104
104
|
executables:
|
@@ -148,6 +148,7 @@ files:
|
|
148
148
|
- lib/gumdrop/hash_object.rb
|
149
149
|
- lib/gumdrop/logging.rb
|
150
150
|
- lib/gumdrop/pager.rb
|
151
|
+
- lib/gumdrop/proxy_handler.rb
|
151
152
|
- lib/gumdrop/server.rb
|
152
153
|
- lib/gumdrop/stitch_compilers.rb
|
153
154
|
- lib/gumdrop/stitch_ex.rb
|