gumdrop 0.3.10 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
 
@@ -9,8 +9,9 @@ DEFAULT_OPTIONS= {
9
9
  relative_paths: true,
10
10
  auto_run: false,
11
11
  force_reload: false,
12
- root: ".",
12
+ proxy_enabled: true,
13
13
  log_level: :info,
14
+ root: ".",
14
15
  output_dir: "./output",
15
16
  lib_dir: "./lib",
16
17
  source_dir: "./source",
@@ -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
@@ -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
- Gumdrop.log.error "[#{$$}] *Missing: #{file_path}"
54
- puts "NOT FOUND: #{file_path}"
55
- "#{file_path} Not Found"
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
 
@@ -1,5 +1,5 @@
1
1
  module Gumdrop
2
2
 
3
- VERSION = "0.3.10" unless defined?(::Gumdrop::VERSION)
3
+ VERSION = "0.4.0" unless defined?(::Gumdrop::VERSION)
4
4
 
5
5
  end
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.3.10
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: &70184358598880 !ruby/object:Gem::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: *70184358598880
24
+ version_requirements: *70152000645980
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: tilt
27
- requirement: &70184358598420 !ruby/object:Gem::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: *70184358598420
35
+ version_requirements: *70152000645100
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: active_support
38
- requirement: &70184358597980 !ruby/object:Gem::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: *70184358597980
46
+ version_requirements: *70152000644420
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: trollop
49
- requirement: &70184358597540 !ruby/object:Gem::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: *70184358597540
57
+ version_requirements: *70152000632300
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: haml
60
- requirement: &70184358597060 !ruby/object:Gem::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: *70184358597060
68
+ version_requirements: *70152000631540
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sass
71
- requirement: &70184358596360 !ruby/object:Gem::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: *70184358596360
79
+ version_requirements: *70152000631100
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: i18n
82
- requirement: &70184358595580 !ruby/object:Gem::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: *70184358595580
90
+ version_requirements: *70152000630680
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: bundle
93
- requirement: &70184358594740 !ruby/object:Gem::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: *70184358594740
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