nyara 0.0.1.pre.5 → 0.0.1.pre.6

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/example/factorial.rb +19 -0
  3. data/ext/accept.c +2 -2
  4. data/ext/event.c +48 -23
  5. data/ext/extconf.rb +2 -0
  6. data/ext/hashes.c +28 -3
  7. data/ext/http-parser/http_parser.h +1 -0
  8. data/ext/nyara.c +20 -3
  9. data/ext/nyara.h +13 -2
  10. data/ext/request.c +90 -13
  11. data/ext/request.h +8 -2
  12. data/ext/request_parse.c +135 -6
  13. data/ext/route.cc +7 -10
  14. data/ext/test_response.c +155 -0
  15. data/ext/url_encoded.c +0 -5
  16. data/lib/nyara/config.rb +5 -0
  17. data/lib/nyara/controller.rb +91 -28
  18. data/lib/nyara/cookie.rb +7 -0
  19. data/lib/nyara/flash.rb +23 -0
  20. data/lib/nyara/hashes/header_hash.rb +2 -0
  21. data/lib/nyara/nyara.rb +14 -2
  22. data/lib/nyara/part.rb +156 -0
  23. data/lib/nyara/patches/array.rb +5 -0
  24. data/lib/nyara/patches/blank.rb +128 -0
  25. data/lib/nyara/patches/json.rb +15 -0
  26. data/lib/nyara/patches/mini_support.rb +6 -0
  27. data/lib/nyara/patches/string.rb +21 -0
  28. data/lib/nyara/patches/to_query.rb +113 -0
  29. data/lib/nyara/request.rb +13 -15
  30. data/lib/nyara/route.rb +15 -80
  31. data/lib/nyara/route_entry.rb +69 -2
  32. data/lib/nyara/session.rb +66 -21
  33. data/lib/nyara/test.rb +170 -0
  34. data/lib/nyara/view.rb +5 -6
  35. data/lib/nyara.rb +7 -6
  36. data/nyara.gemspec +2 -2
  37. data/rakefile +34 -4
  38. data/readme.md +8 -1
  39. data/spec/config_spec.rb +28 -0
  40. data/spec/cpu_counter_spec.rb +9 -0
  41. data/spec/evented_io_spec.rb +1 -0
  42. data/spec/flash_spec.rb +29 -0
  43. data/spec/hashes_spec.rb +8 -0
  44. data/spec/mini_support_spec.rb +54 -0
  45. data/spec/part_spec.rb +52 -0
  46. data/spec/path_helper_spec.rb +22 -14
  47. data/spec/request_delegate_spec.rb +19 -11
  48. data/spec/route_entry_spec.rb +55 -0
  49. data/spec/session_spec.rb +69 -7
  50. data/spec/spec_helper.rb +3 -0
  51. data/spec/test_spec.rb +58 -0
  52. data/tools/hello.rb +11 -3
  53. data/tools/memcheck.rb +33 -0
  54. data/tools/s.rb +11 -0
  55. metadata +23 -7
  56. data/example/design.rb +0 -62
  57. data/example/fib.rb +0 -15
  58. data/spec/route_spec.rb +0 -84
  59. /data/ext/inc/{status_codes.inc → status_codes.h} +0 -0
data/lib/nyara/route.rb CHANGED
@@ -12,52 +12,46 @@ module Nyara
12
12
  end
13
13
 
14
14
  def compile
15
- global_path_templates = {} # "name#id" => path
16
- @path_templates = {} # klass => {any_id => path}
15
+ @global_path_templates = {} # "name#id" => path
16
+ mapped_controllers = {}
17
17
 
18
- a = @controllers.map do |scope, c|
18
+ route_entries = @controllers.flat_map do |scope, c|
19
19
  if c.is_a?(String)
20
20
  c = name2const c
21
21
  end
22
22
  name = c.controller_name || const2name(c)
23
23
  raise "#{c.inspect} is not a Nyara::Controller" unless Controller > c
24
24
 
25
- if @path_templates[c]
25
+ if mapped_controllers[c]
26
26
  raise "controller #{c.inspect} was already mapped"
27
27
  end
28
+ mapped_controllers[c] = true
28
29
 
29
- route_entries = c.preprocess_actions
30
- @path_templates[c] = {}
31
- route_entries.each do |e|
32
- id = e.id.to_s
33
- path = File.join scope, e.path
34
- global_path_templates[name + id] = path
35
- @path_templates[c][id] = path
30
+ c.compile_route_entries(scope).each do |e|
31
+ @global_path_templates[name + e.id] = e.path_template
36
32
  end
37
-
38
- [scope, c, route_entries]
39
33
  end
34
+ route_entries.sort_by! &:prefix
35
+ route_entries.reverse!
40
36
 
41
- @path_templates.keys.each do |c|
42
- @path_templates[c] = global_path_templates.merge @path_templates[c]
37
+ mapped_controllers.each do |c, _|
38
+ c.path_templates = @global_path_templates.merge c.path_templates
43
39
  end
44
40
 
45
41
  Ext.clear_route
46
- process(a).each do |entry|
47
- entry.validate
48
- Ext.register_route entry
42
+ route_entries.each do |e|
43
+ Ext.register_route e
49
44
  end
50
45
  end
51
46
 
52
- def path_template klass, id
53
- @path_templates[klass][id]
47
+ def global_path_template id
48
+ @global_path_templates[id]
54
49
  end
55
50
 
56
51
  def clear
57
52
  # gc mark fail if wrong order?
58
53
  Ext.clear_route
59
54
  @controllers = {}
60
- @path_templates = {}
61
55
  end
62
56
 
63
57
  # private
@@ -75,64 +69,5 @@ module Nyara
75
69
  name << 'Controller'
76
70
  Module.const_get name
77
71
  end
78
-
79
- def process preprocessed
80
- entries = []
81
- preprocessed.each do |(scope, controller, route_entries)|
82
- route_entries.each do |e|
83
- e = e.dup # in case there is controller used in more than 1 maps
84
- path = scope.sub /\/?$/, e.path
85
- if path.empty?
86
- path = '/'
87
- end
88
- e.prefix, suffix = analyse_path path
89
- e.suffix, e.conv = compile_re suffix
90
- e.scope = scope
91
- e.controller = controller
92
- entries << e
93
- end
94
- end
95
- entries.sort_by! &:prefix
96
- entries.reverse!
97
- entries
98
- end
99
-
100
- # returns [str_re, conv]
101
- def compile_re suffix
102
- return ['', []] unless suffix
103
- conv = []
104
- re_segs = suffix.split(/(?<=%[dfsux])|(?=%[dfsux])/).map do |s|
105
- case s
106
- when '%d'
107
- conv << :to_i
108
- '(-?[0-9]+)'
109
- when '%f'
110
- conv << :to_f
111
- # just copied from scanf
112
- '([-+]?(?:0[xX](?:\.\h+|\h+(?:\.\h*)?)[pP][-+]\d+|\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))'
113
- when '%u'
114
- conv << :to_i
115
- '([0-9]+)'
116
- when '%x'
117
- conv << :hex
118
- '(\h+)'
119
- when '%s'
120
- conv << :to_s
121
- '([^/]+)'
122
- else
123
- Regexp.quote s
124
- end
125
- end
126
- ["^#{re_segs.join}$", conv]
127
- end
128
-
129
- # split the path into parts
130
- def analyse_path path
131
- raise 'path must contain no new line' if path.index "\n"
132
- raise 'path must start with /' unless path.start_with? '/'
133
- path = path.sub(/\/$/, '') if path != '/'
134
-
135
- path.split(/(?=%[dfsux])/, 2)
136
- end
137
72
  end
138
73
  end
@@ -1,7 +1,12 @@
1
1
  module Nyara
2
2
  class RouteEntry
3
3
  REQUIRED_ATTRS = [:http_method, :scope, :prefix, :suffix, :controller, :id, :conv]
4
- attr_accessor *REQUIRED_ATTRS
4
+ attr_reader *REQUIRED_ATTRS
5
+ attr_writer :http_method, :id
6
+ # stores symbol for C conenience, and returns string for Ruby side goodness
7
+ def id
8
+ @id.to_s
9
+ end
5
10
 
6
11
  # optional
7
12
  attr_accessor :accept_exts, :accept_mimes
@@ -13,6 +18,25 @@ module Nyara
13
18
  instance_eval &p if p
14
19
  end
15
20
 
21
+ def path_template
22
+ File.join @scope, (@path.gsub '%z', '%s')
23
+ end
24
+
25
+ # compute prefix, suffix, conv
26
+ # NOTE route_entries may be inherited, so late-setting controller is necessary
27
+ def compile controller, scope
28
+ @controller = controller
29
+ @scope = scope
30
+
31
+ path = scope.sub /\/?$/, @path
32
+ if path.empty?
33
+ path = '/'
34
+ end
35
+ @prefix, suffix = analyse_path path
36
+ @suffix, @conv = compile_re suffix
37
+ end
38
+
39
+ # compute accept_exts, accept_mimes
16
40
  def set_accept_exts a
17
41
  @accept_exts = {}
18
42
  @accept_mimes = []
@@ -37,7 +61,50 @@ module Nyara
37
61
  raise ArgumentError, "missing #{attr}"
38
62
  end
39
63
  end
40
- raise ArgumentError, "id must be symbol" unless id.is_a?(Symbol)
64
+ raise ArgumentError, "id must be symbol" unless @id.is_a?(Symbol)
65
+ end
66
+
67
+ # private
68
+
69
+ # returns [str_re, conv]
70
+ def compile_re suffix
71
+ return ['', []] unless suffix
72
+ conv = []
73
+ re_segs = suffix.split(/(?<=%[dfsux])|(?=%[dfsux])/).map do |s|
74
+ case s
75
+ when '%d'
76
+ conv << :to_i
77
+ '(-?[0-9]+)'
78
+ when '%f'
79
+ conv << :to_f
80
+ # just copied from scanf
81
+ '([-+]?(?:0[xX](?:\.\h+|\h+(?:\.\h*)?)[pP][-+]\d+|\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))'
82
+ when '%u'
83
+ conv << :to_i
84
+ '([0-9]+)'
85
+ when '%x'
86
+ conv << :hex
87
+ '(\h+)'
88
+ when '%s'
89
+ conv << :to_s
90
+ '([^/]+)'
91
+ when '%z'
92
+ conv << :to_s
93
+ '(.+)'
94
+ else
95
+ Regexp.quote s
96
+ end
97
+ end
98
+ ["^#{re_segs.join}$", conv]
99
+ end
100
+
101
+ # split the path into parts
102
+ def analyse_path path
103
+ raise 'path must contain no new line' if path.index "\n"
104
+ raise 'path must start with /' unless path.start_with? '/'
105
+ path = path.sub(/\/$/, '') if path != '/'
106
+
107
+ path.split(/(?=%[dfsux])/, 2)
41
108
  end
42
109
  end
43
110
  end
data/lib/nyara/session.rb CHANGED
@@ -1,42 +1,74 @@
1
1
  module Nyara
2
- # cookie based
3
- # usually it's no need to call cache or database data a "session"
2
+ # helper module for session management, cookie based<br>
3
+ # (usually it's no need to call cache or database data a "session")<br><br>
4
+ # session is by default DSA + SHA2/SHA1 signed, sub config options are:
5
+ #
6
+ # [name] session entry name in cookie, default is +'spare_me_plz'+
7
+ # [expire] expire session after seconds. default is +nil+, which means session expires when browser is closed<br>
8
+ # [expires] same as +expire+
9
+ # [secure] - +nil+(default): if request is https, add +Secure+ option to it
10
+ # - +true+: always add +Secure+
11
+ # - +false+: always no +Secure+
12
+ # [key] DSA private key string, in der or pem format, use random if not given
13
+ # [cipher_key] if exist, use aes-256-cbc to cipher the "sig/json"<br>
14
+ # NOTE: it's no need to set +cipher_key+ if using https
15
+ #
16
+ # = example
17
+ #
18
+ # configure do
19
+ # set 'session', 'key', File.read(project_path 'config/session.key')
20
+ # set 'session', 'expire', 30 * 60
21
+ # end
22
+ #
4
23
  module Session
5
24
  extend self
6
25
 
7
26
  CIPHER_BLOCK_SIZE = 256/8
8
27
 
9
- # session is by default DSA + SHA2/SHA1 signed, sub config options are:
10
- #
11
- # - name (session entry name in cookie, default is 'spare_me_plz')
12
- # - key (DSA private key string, in der or pem format, use random if not given)
13
- # - cipher_key (if exist, use aes-256-cbc to cipher the "sig&json", the first 256bit is sliced for iv)
14
- # (it's no need to set cipher_key if using https)
15
-
16
28
  # init from config
17
29
  def init
18
- c = Config['session'] || {}
19
- @name = (c['name'] || 'spare_me_plz').to_s
30
+ c = Config['session'] ? Config['session'].dup : {}
31
+ @name = (c.delete('name') || 'spare_me_plz').to_s
20
32
 
21
33
  if c['key']
22
- @dsa = OpenSSL::PKey::DSA.new c['key']
34
+ @dsa = OpenSSL::PKey::DSA.new c.delete 'key'
23
35
  else
24
- @dsa = OpenSSL::PKey::DSA.generate 256
36
+ @dsa = generate_key
25
37
  end
26
38
 
27
39
  # DSA can sign on any digest since 1.0.0
28
40
  @dss = OpenSSL::VERSION >= '1.0.0' ? OpenSSL::Digest::SHA256 : OpenSSL::Digest::DSS1
29
41
 
30
- @cipher_key = pad_256_bit c['cipher_key']
42
+ @cipher_key = pad_256_bit c.delete 'cipher_key'
43
+
44
+ @expire = c.delete('expire') || c.delete('expires')
45
+ @secure = c.delete('secure')
46
+
47
+ unless c.empty?
48
+ raise "unknown options in Nyara::Config[:session]: #{c.inspect}"
49
+ end
31
50
  end
32
51
 
33
52
  attr_reader :name
34
53
 
35
- def encode h, cookie
54
+ # encode into a cookie hash, for test environment
55
+ def encode_to_cookie h, cookie
56
+ cookie[@name] = encode h
57
+ end
58
+
59
+ # encode to value
60
+ def encode h
36
61
  str = h.to_json
37
62
  sig = @dsa.syssign @dss.digest str
38
- str = "#{Base64.urlsafe_encode64 sig}&#{str}"
39
- cookie[@name] = @cipher_key ? cipher(str) : str
63
+ str = "#{encode64 sig}/#{encode64 str}"
64
+ @cipher_key ? cipher(str) : str
65
+ end
66
+
67
+ # encode as header line
68
+ def encode_set_cookie h, secure
69
+ secure = @secure unless @secure.nil?
70
+ expire = (Time.now + @expire).gmtime.rfc2822 if @expire
71
+ "Set-Cookie: #{@name}=#{encode h}; HttpOnly#{'; Secure' if secure}#{"; Expires=#{expire}" if expire}\r\n"
40
72
  end
41
73
 
42
74
  def decode cookie
@@ -44,11 +76,12 @@ module Nyara
44
76
  return empty_hash if str.empty?
45
77
 
46
78
  str = decipher(str) if @cipher_key
47
- sig, str = str.split '&', 2
79
+ sig, str = str.split '/', 2
48
80
  return empty_hash unless str
49
81
 
50
82
  begin
51
- sig = Base64.urlsafe_decode64 sig
83
+ sig = decode64 sig
84
+ str = decode64 str
52
85
  verified = @dsa.sysverify @dss.digest(str), sig
53
86
  if verified
54
87
  h = JSON.parse str, create_additions: false, object_class: ParamHash
@@ -64,16 +97,28 @@ module Nyara
64
97
  end
65
98
  end
66
99
 
100
+ def generate_key
101
+ OpenSSL::PKey::DSA.generate 256
102
+ end
103
+
67
104
  # private
68
105
 
106
+ def encode64 s
107
+ [s].pack('m0').tr("+/", "-_")
108
+ end
109
+
110
+ def decode64 s
111
+ s.tr("-_", "+/").unpack('m0').first
112
+ end
113
+
69
114
  def cipher str
70
115
  iv = rand(36**CIPHER_BLOCK_SIZE).to_s(36).ljust CIPHER_BLOCK_SIZE
71
116
  c = new_cipher true, iv
72
- Base64.urlsafe_encode64(iv.dup << c.update(str) << c.final)
117
+ encode64(iv.dup << c.update(str) << c.final)
73
118
  end
74
119
 
75
120
  def decipher str
76
- str = Base64.urlsafe_decode64 str
121
+ str = decode64 str
77
122
  iv = str.byteslice 0...CIPHER_BLOCK_SIZE
78
123
  str = str.byteslice CIPHER_BLOCK_SIZE..-1
79
124
  return '' if !str or str.empty?
data/lib/nyara/test.rb ADDED
@@ -0,0 +1,170 @@
1
+ module Nyara
2
+ # test helper
3
+ module Test
4
+ class Response
5
+ # whether request is success
6
+ def success?
7
+ status < 400
8
+ end
9
+
10
+ def redirect_location
11
+ if HTTP_REDIRECT_STATUS.include?(status)
12
+ header['Location']
13
+ end
14
+ end
15
+
16
+ # C-ext methods: header, body, status, initialize(data), set_cookies
17
+ end
18
+
19
+ Env = Struct.new :cookie, :session, :request, :controller, :response, :response_size_limit
20
+ class Env
21
+ # :call-seq:
22
+ #
23
+ # # change size limit of response data to 100M:
24
+ # @_env = Env.new 10**8
25
+ #
26
+ def initialize response_size_limit=5_000_000
27
+ self.response_size_limit = response_size_limit
28
+ self.cookie = ParamHash.new
29
+ self.session = ParamHash.new
30
+ end
31
+
32
+ def process_request_data data
33
+ client, server = Socket.pair :UNIX, :STREAM
34
+ self.request = Ext.request_new
35
+ Ext.request_set_fd request, server.fileno
36
+
37
+ client << data
38
+ self.controller = Ext.handle_request request
39
+ response_data = client.read_nonblock response_size_limit
40
+ self.response = Response.new response_data
41
+
42
+ # merge session
43
+ session.clear
44
+ session.merge! request.session
45
+
46
+ # merge Set-Cookie
47
+ response.set_cookies.each do |cookie_seg|
48
+ # todo distinguish delete, value and set
49
+ Ext.parse_url_encoded_seg cookie, cookie_seg, false
50
+ end
51
+
52
+ server.close
53
+ client.close
54
+ end
55
+
56
+ def http meth, path, headers={}, body_string_or_hash=''
57
+ headers = (headers || {}).dup
58
+
59
+ # serialize body
60
+ # todo build multipart for file
61
+ if body_string_or_hash.is_a?(Hash)
62
+ body = body_string_or_hash.to_param
63
+ headers['Content-Type'] = 'application/x-www-form-urlencoded'
64
+ else
65
+ body = body_string_or_hash.to_s
66
+ headers['Content-Type'] ||= 'text/plain'
67
+ end
68
+ if body.bytesize > 0
69
+ headers['Content-Length'] = body.bytesize
70
+ end
71
+
72
+ # serialize cookie / session
73
+ if headers['Cookie']
74
+ cookie.clear
75
+ cookie.merge! Cookie.decode headers
76
+ end
77
+ Session.encode_to_cookie session, cookie
78
+ headers['Cookie'] = Cookie.encode cookie
79
+
80
+ request_data = ["#{meth.upcase} #{path} HTTP/1.1\r\n"]
81
+ headers.each do |k, v|
82
+ request_data << "#{k}: #{v}\r\n"
83
+ end
84
+ request_data << "\r\n"
85
+ request_data << body
86
+ process_request_data request_data.join
87
+ end
88
+ end
89
+
90
+ def env
91
+ @_env ||= Env.new
92
+ end
93
+
94
+ # :call-seq:
95
+ #
96
+ # get '/', headers
97
+ #
98
+ def get path, header={}, body_string_or_hash=""
99
+ env.http 'GET', path, header, body_string_or_hash
100
+ end
101
+
102
+ # :call-seq:
103
+ #
104
+ # post '/', {}, page: 3
105
+ # post '/', { 'content-type' => 'application/json' }, '{"page":3}'
106
+ #
107
+ def post path, header={}, body_string_or_hash=""
108
+ env.http 'POST', path, header, body_string_or_hash
109
+ end
110
+
111
+ def put path, header={}, body_string_or_hash=""
112
+ env.http 'PUT', path, header, body_string_or_hash
113
+ end
114
+
115
+ def delete path, header={}, body_string_or_hash=""
116
+ env.http 'DELETE', path, header, body_string_or_hash
117
+ end
118
+
119
+ def patch path, header={}, body_string_or_hash=""
120
+ env.http 'PATCH', path, header, body_string_or_hash
121
+ end
122
+
123
+ def options path, header={}, body_string_or_hash=""
124
+ env.http 'OPTIONS', path, header, body_string_or_hash
125
+ end
126
+
127
+ def path_to id, *args
128
+ # similar to Controller#path_to, but without local query
129
+ if args.last.is_a?(Hash)
130
+ opts = args.pop
131
+ end
132
+
133
+ r = Route.global_path_template(id) % args
134
+
135
+ if opts
136
+ format = opts.delete :format
137
+ r << ".#{format}" if format
138
+ r << '?' << opts.to_param unless query.empty?
139
+ end
140
+ r
141
+ end
142
+
143
+ def cookie
144
+ env.cookie
145
+ end
146
+
147
+ def session
148
+ env.session
149
+ end
150
+
151
+ def request
152
+ env.request
153
+ end
154
+
155
+ def response
156
+ env.response
157
+ end
158
+
159
+ def redirect_location
160
+ env.response.redirect_location
161
+ end
162
+
163
+ def follow_redirect
164
+ # todo validate scheme and host
165
+ u = URI.parse(redirect_location)
166
+ path = [u.path, u.query].compact.join '?'
167
+ get path
168
+ end
169
+ end
170
+ end
data/lib/nyara/view.rb CHANGED
@@ -42,7 +42,7 @@ module Nyara
42
42
  end
43
43
  attr_reader :root
44
44
 
45
- # +path+ needs extension
45
+ # NOTE: +path+ needs extension
46
46
  def on_delete path
47
47
  meth = path2meth path
48
48
  Renderable.class_eval do
@@ -64,7 +64,7 @@ module Nyara
64
64
  @meth2ext.clear
65
65
  end
66
66
 
67
- # +path+ needs extension
67
+ # NOTE: +path+ needs extension<br>
68
68
  # returns dot_ext for further use
69
69
  def on_update path
70
70
  meth = path2meth path
@@ -108,7 +108,7 @@ module Nyara
108
108
  line = 1
109
109
 
110
110
  if stream_friendly
111
- Renderable.class_eval <<-RUBY, __FILE__, __LINE__ + 1
111
+ Renderable.class_eval <<-RUBY, __FILE__, __LINE__
112
112
  def render locals={}
113
113
  @_nyara_locals = locals
114
114
  src = locals.map{|k, _| "\#{k} = @_nyara_locals[:\#{k}];" }.join
@@ -119,7 +119,7 @@ module Nyara
119
119
  RUBY
120
120
  ENGINE_STREAM_FRIENDLY[ext] = true
121
121
  else
122
- Renderable.class_eval <<-RUBY, __FILE__, __LINE__ + 1
122
+ Renderable.class_eval <<-RUBY, __FILE__, __LINE__
123
123
  def render locals=nil
124
124
  Tilt[#{ext.inspect}].new(#{file}, #{line}){ @_nyara_view.in }.render self, locals
125
125
  end
@@ -278,8 +278,7 @@ RUBY
278
278
  Fiber.yield :term_close
279
279
  end
280
280
 
281
- # :nodoc:
282
- def _render
281
+ def _render # :nodoc:
283
282
  t, _ = @rest_layouts.pop
284
283
  if @rest_layouts.empty?
285
284
  @instance.send t, @locals
data/lib/nyara.rb CHANGED
@@ -1,18 +1,19 @@
1
1
  # auto run
2
2
  require_relative "nyara/nyara"
3
3
 
4
- at_exit do
5
- Nyara::Route.compile
6
- Nyara::View.init
7
- Nyara.start_server
8
- end
4
+ END {
5
+ if $!.nil? and !Nyara.config.test?
6
+ Nyara.setup
7
+ Nyara.start_server
8
+ end
9
+ }
9
10
 
10
11
  module Nyara
11
12
  class SimpleController < Controller
12
13
  end
13
14
  end
14
15
 
15
- %w[on tag get post put delete patch options].each do |m|
16
+ %w[on tag get post put delete patch options meta].each do |m|
16
17
  eval <<-RUBY
17
18
  def #{m} *xs, &blk
18
19
  Nyara::SimpleController.#{m} *xs, &blk
data/nyara.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "nyara"
3
- s.version = "0.0.1.pre.5"
3
+ s.version = "0.0.1.pre.6"
4
4
  s.author = "Zete Lui"
5
5
  s.email = "nobody@example.com"
6
6
  s.homepage = "https://github.com/luikore/nyara"
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.summary = "Fast, slim and fuzzy ruby web framework + server"
9
9
  s.description = "Fast, slim and fuzzy ruby web framework + server, based on preforked event queue and Fiber. NO rack NOR eventmachine are used."
10
10
  s.required_ruby_version = ">=2.0.0"
11
- s.licenses = ['BSD']
11
+ s.licenses = ['BSD 3-Clause']
12
12
 
13
13
  s.files = Dir.glob('{rakefile,nyara.gemspec,readme.md,**/*.{rb,h,c,cc,inc}}')
14
14
  s.files += Dir.glob('ext/http-parser/{AUTHORS,CONTRIBUTIONS,LICENSE-MIT}')
data/rakefile CHANGED
@@ -2,13 +2,13 @@ require "rake"
2
2
 
3
3
  Dir.chdir __dir__
4
4
 
5
- status_file = "ext/inc/status_codes.inc"
5
+ status_file = "ext/inc/status_codes.h"
6
6
  version_file = "ext/inc/version.inc"
7
7
  makefile = "ext/Makefile"
8
8
  extconf = "ext/extconf.rb"
9
9
 
10
10
  desc "code generate"
11
- task :gen => [status_file, version_file]
11
+ task :gen => [version_file]
12
12
 
13
13
  desc "generate #{status_file}"
14
14
  file status_file => __FILE__ do
@@ -47,6 +47,7 @@ end
47
47
  desc "generate makefile"
48
48
  file makefile => extconf do
49
49
  Dir.chdir 'ext' do
50
+ sh 'make clean' if File.exist?('Makefile')
50
51
  sh 'ruby extconf.rb'
51
52
  end
52
53
  end
@@ -112,14 +113,20 @@ end
112
113
  desc "list Nyara::Ext methods"
113
114
  task :list_ext do
114
115
  require_relative "lib/nyara/nyara"
116
+ puts_methods = lambda{|methods|
117
+ methods.each do |m|
118
+ puts "#{m} /#{Nyara::Ext.method(m).arity}"
119
+ end
120
+ }
121
+
115
122
  methods = (Nyara::Ext.methods - Module.methods).sort
116
123
  [/queue/, /route/, /parse/, /request/].each do |r|
117
124
  group = methods.grep r
118
- puts group
125
+ puts_methods[group]
119
126
  puts
120
127
  methods -= group
121
128
  end
122
- puts methods
129
+ puts_methods[methods]
123
130
  end
124
131
 
125
132
  def term_color n
@@ -158,3 +165,26 @@ task :audit_arity do
158
165
  end
159
166
  end
160
167
  end
168
+
169
+ desc "audit http_parser / multipart_parser struct size, they should be dividable by 8 so that Request fields are aligned"
170
+ task :audit_sizeof_parsers do
171
+ require "mkmf"
172
+ $CFLAGS << " -Iext/http-parser -Iext/multipart-parser-c"
173
+ {
174
+ 'http_parser' => 'http_parser.h',
175
+ 'multipart_parser*' => 'multipart_parser.h' # multipart_parser is opaque -_-
176
+ }.each do |struct, header|
177
+ have_header header
178
+ res = check_sizeof(struct, header)
179
+ if res and res % 8 == 0
180
+ puts "OK"
181
+ else
182
+ term_color 9
183
+ print "Need padding"
184
+ reset_color
185
+ puts
186
+ end
187
+ puts
188
+ end
189
+ sh 'rm', 'mkmf.log'
190
+ end