hayabusa 0.0.20 → 0.0.22

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/Gemfile CHANGED
@@ -10,6 +10,7 @@ gem "datet"
10
10
  gem "http2"
11
11
  gem "tpool"
12
12
  gem "fcgi"
13
+ gem "ruby_process"
13
14
 
14
15
  # Add dependencies to develop your gem here.
15
16
  # Include everything needed to run rake, tests, features, etc.
@@ -18,5 +19,6 @@ group :development do
18
19
  gem "rspec", ">= 2.3.0"
19
20
  gem "bundler", ">= 1.0.0"
20
21
  gem "jeweler", "~> 1.6.3"
22
+ gem "rmagick"
21
23
  gem "sqlite3" if RUBY_ENGINE != "jruby"
22
24
  end
@@ -1,49 +1,54 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- datet (0.0.20)
5
- diff-lcs (1.1.3)
4
+ datet (0.0.25)
5
+ diff-lcs (1.2.4)
6
6
  erubis (2.7.0)
7
- fcgi (0.8.8)
7
+ fcgi (0.9.1)
8
8
  git (1.2.5)
9
- http2 (0.0.12)
10
- i18n (0.6.1)
9
+ http2 (0.0.21)
11
10
  jeweler (1.6.4)
12
11
  bundler (~> 1.0)
13
12
  git (>= 1.2.5)
14
13
  rake
15
- json (1.7.5)
16
- knjrbfw (0.0.99)
14
+ json (1.8.0)
15
+ knjrbfw (0.0.105)
17
16
  datet
18
17
  http2
19
18
  php4r
19
+ ruby_process
20
20
  tsafe
21
21
  wref
22
- mail (2.4.4)
23
- i18n (>= 0.4.0)
22
+ mail (2.5.4)
24
23
  mime-types (~> 1.16)
25
24
  treetop (~> 1.4.8)
26
- mime-types (1.19)
27
- php4r (0.0.3)
25
+ mime-types (1.23)
26
+ php4r (0.0.4)
28
27
  datet
29
28
  http2
29
+ string-strtr
30
30
  polyglot (0.3.3)
31
- rake (0.9.2.2)
32
- rspec (2.11.0)
33
- rspec-core (~> 2.11.0)
34
- rspec-expectations (~> 2.11.0)
35
- rspec-mocks (~> 2.11.0)
36
- rspec-core (2.11.1)
37
- rspec-expectations (2.11.3)
38
- diff-lcs (~> 1.1.3)
39
- rspec-mocks (2.11.3)
40
- sqlite3 (1.3.6)
31
+ rake (10.1.0)
32
+ rmagick (2.13.2)
33
+ rspec (2.13.0)
34
+ rspec-core (~> 2.13.0)
35
+ rspec-expectations (~> 2.13.0)
36
+ rspec-mocks (~> 2.13.0)
37
+ rspec-core (2.13.1)
38
+ rspec-expectations (2.13.0)
39
+ diff-lcs (>= 1.1.3, < 2.0)
40
+ rspec-mocks (2.13.1)
41
+ ruby_process (0.0.8)
42
+ tsafe
43
+ wref
44
+ sqlite3 (1.3.7)
45
+ string-strtr (0.0.3)
41
46
  tpool (0.0.4)
42
- treetop (1.4.10)
47
+ treetop (1.4.14)
43
48
  polyglot
44
49
  polyglot (>= 0.3.1)
45
50
  tsafe (0.0.11)
46
- wref (0.0.5)
51
+ wref (0.0.6)
47
52
 
48
53
  PLATFORMS
49
54
  ruby
@@ -58,6 +63,8 @@ DEPENDENCIES
58
63
  json
59
64
  knjrbfw
60
65
  mail
66
+ rmagick
61
67
  rspec (>= 2.3.0)
68
+ ruby_process
62
69
  sqlite3
63
70
  tpool
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.20
1
+ 0.0.22
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{hayabusa}
8
- s.version = "0.0.20"
7
+ s.name = "hayabusa"
8
+ s.version = "0.0.22"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kasper Johansen"]
12
- s.date = %q{2012-10-12}
13
- s.description = %q{A threadded web/app-server that focuses on threadding, shared ressources, speed and more.}
14
- s.email = %q{k@spernj.org}
12
+ s.date = "2013-06-28"
13
+ s.description = "A threadded web/app-server that focuses on threadding, shared ressources, speed and more."
14
+ s.email = "k@spernj.org"
15
15
  s.executables = ["check_running.rb", "hayabusa_benchmark.rb", "hayabusa_cgi.rb", "hayabusa_fcgi.fcgi", "hayabusa_fcgi.rb", "hayabusa_fcgi_server.rb", "hayabusa_spec_restart.rb", "knjappserver_start.rb"]
16
16
  s.extra_rdoc_files = [
17
17
  "LICENSE.txt",
@@ -96,6 +96,7 @@ Gem::Specification.new do |s|
96
96
  "pages/spec_vars_header.rhtml",
97
97
  "pages/spec_vars_post.rhtml",
98
98
  "pages/spec_vars_post_fileupload.rhtml",
99
+ "pages/testpic.jpeg",
99
100
  "pages/tests.rhtml",
100
101
  "pages/threadded_content_test.rhtml",
101
102
  "spec/fcgi_multiple_processes_spec.rb",
@@ -103,11 +104,11 @@ Gem::Specification.new do |s|
103
104
  "spec/spec_helper.rb",
104
105
  "spec/test_upload.xlsx"
105
106
  ]
106
- s.homepage = %q{http://github.com/kaspernj/hayabusa}
107
+ s.homepage = "http://github.com/kaspernj/hayabusa"
107
108
  s.licenses = ["MIT"]
108
109
  s.require_paths = ["lib"]
109
- s.rubygems_version = %q{1.6.2}
110
- s.summary = %q{A threadded web/app-server that supports stand-alone, CGI and FCGI-modes.}
110
+ s.rubygems_version = "1.8.23"
111
+ s.summary = "A threadded web/app-server that supports stand-alone, CGI and FCGI-modes."
111
112
 
112
113
  if s.respond_to? :specification_version then
113
114
  s.specification_version = 3
@@ -120,10 +121,12 @@ Gem::Specification.new do |s|
120
121
  s.add_runtime_dependency(%q<http2>, [">= 0"])
121
122
  s.add_runtime_dependency(%q<tpool>, [">= 0"])
122
123
  s.add_runtime_dependency(%q<fcgi>, [">= 0"])
124
+ s.add_runtime_dependency(%q<ruby_process>, [">= 0"])
123
125
  s.add_development_dependency(%q<json>, [">= 0"])
124
126
  s.add_development_dependency(%q<rspec>, [">= 2.3.0"])
125
127
  s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
126
128
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.3"])
129
+ s.add_development_dependency(%q<rmagick>, [">= 0"])
127
130
  s.add_development_dependency(%q<sqlite3>, [">= 0"])
128
131
  else
129
132
  s.add_dependency(%q<knjrbfw>, [">= 0"])
@@ -133,10 +136,12 @@ Gem::Specification.new do |s|
133
136
  s.add_dependency(%q<http2>, [">= 0"])
134
137
  s.add_dependency(%q<tpool>, [">= 0"])
135
138
  s.add_dependency(%q<fcgi>, [">= 0"])
139
+ s.add_dependency(%q<ruby_process>, [">= 0"])
136
140
  s.add_dependency(%q<json>, [">= 0"])
137
141
  s.add_dependency(%q<rspec>, [">= 2.3.0"])
138
142
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
139
143
  s.add_dependency(%q<jeweler>, ["~> 1.6.3"])
144
+ s.add_dependency(%q<rmagick>, [">= 0"])
140
145
  s.add_dependency(%q<sqlite3>, [">= 0"])
141
146
  end
142
147
  else
@@ -147,10 +152,12 @@ Gem::Specification.new do |s|
147
152
  s.add_dependency(%q<http2>, [">= 0"])
148
153
  s.add_dependency(%q<tpool>, [">= 0"])
149
154
  s.add_dependency(%q<fcgi>, [">= 0"])
155
+ s.add_dependency(%q<ruby_process>, [">= 0"])
150
156
  s.add_dependency(%q<json>, [">= 0"])
151
157
  s.add_dependency(%q<rspec>, [">= 2.3.0"])
152
158
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
153
159
  s.add_dependency(%q<jeweler>, ["~> 1.6.3"])
160
+ s.add_dependency(%q<rmagick>, [">= 0"])
154
161
  s.add_dependency(%q<sqlite3>, [">= 0"])
155
162
  end
156
163
  end
@@ -34,7 +34,7 @@ class Hayabusa
34
34
  :default_filetype => "text/html",
35
35
  :max_requests_working => 20,
36
36
  :size_send => 1024,
37
- :cleaner_timeout => 300,
37
+ :cleaner_timeout => 60,
38
38
  :mailing_time => 30
39
39
  }.merge(config)
40
40
 
@@ -52,20 +52,20 @@ class Hayabusa
52
52
  [:Tpool, "tpool"]
53
53
  ]
54
54
 
55
- gems.each do |gem|
56
- if Kernel.const_defined?(gem[0])
57
- puts "Gem already loaded: '#{gem[1]}'." if @debug
55
+ gems.each do |gem_i|
56
+ if Kernel.const_defined?(gem_i[0])
57
+ puts "Gem already loaded: '#{gem_i[1]}'." if @debug
58
58
  next
59
59
  end
60
60
 
61
- fpath = "#{@@path}/../../#{gem[1]}/lib/#{gem[1]}.rb"
61
+ fpath = "#{@@path}/../../#{gem_i[1]}/lib/#{gem_i[1]}.rb"
62
62
 
63
63
  if File.exists?(fpath)
64
64
  puts "Loading custom gem-path: '#{fpath}'." if @debug
65
65
  require fpath
66
66
  else
67
- puts "Loading gem: '#{gem[1]}'." if @debug
68
- require gem[1]
67
+ puts "Loading gem: '#{gem_i[1]}'." if @debug
68
+ require gem_i[1]
69
69
  end
70
70
  end
71
71
 
@@ -544,4 +544,4 @@ class Hayabusa
544
544
 
545
545
  return @translations
546
546
  end
547
- end
547
+ end
@@ -110,8 +110,7 @@ class Hayabusa::Cgi_session < Hayabusa::Client_session
110
110
  rescue SystemExit
111
111
  #do nothing - ignore.
112
112
  rescue Timeout::Error
113
- @resp.status = 500
114
- print "The request timed out."
113
+ @resp.status = 408
115
114
  end
116
115
  end
117
116
 
@@ -22,6 +22,14 @@ class Hayabusa::Client_session
22
22
  @cgroup.force_content(newcont)
23
23
  end
24
24
 
25
+ #Forces the output to be read from a file.
26
+ def force_fileread(fpath)
27
+ raise "Invalid filepath given: '#{fpath}'." if !fpath || !File.exists?(fpath)
28
+ @resp.chunked = false
29
+ @resp.header("Content-Length", File.size(fpath))
30
+ @cgroup.new_io(:type => :file, :path => fpath)
31
+ end
32
+
25
33
  #Creates a new Hayabusa::Binding-object and returns the binding for that object.
26
34
  def create_binding
27
35
  return Hayabusa::Http_session::Page_environment.new(:httpsession => self, :hb => @hb).get_binding
@@ -82,6 +90,7 @@ class Hayabusa::Client_session
82
90
  if @handlers_cache.key?(@ext)
83
91
  @hb.log_puts("Calling handler.") if @debug
84
92
  @handlers_cache[@ext].call(self)
93
+ @hb.log_puts("Called handler.") if @debug
85
94
  else
86
95
  #check if we should use a handler for this request.
87
96
  @config[:handlers].each do |handler_info|
@@ -125,7 +134,7 @@ class Hayabusa::Client_session
125
134
  end
126
135
  end
127
136
 
128
- @cgroup.new_io(:type => :file, :path => @page_path)
137
+ self.force_fileread(@page_path)
129
138
  end
130
139
  end
131
140
  end
@@ -133,8 +142,8 @@ class Hayabusa::Client_session
133
142
  rescue SystemExit
134
143
  #do nothing - ignore.
135
144
  rescue Timeout::Error
136
- @resp.status = 500
137
- print "The request timed out."
145
+ @resp.status = 408
146
+ @hb.log_puts "The request timed out."
138
147
  end
139
148
  end
140
149
 
@@ -144,10 +153,7 @@ class Hayabusa::Client_session
144
153
  @hb.log_puts "#{__id__} - Served '#{@meta["REQUEST_URI"]}' in #{Time.now.to_f - @time_start} secs (#{@resp.status})." if @debug
145
154
  @time_start = nil
146
155
  @cgroup.join
147
-
148
- @hb.events.call(:request_done, {
149
- :httpsession => self
150
- }) if @hb.events
156
+ @hb.events.call(:request_done, :httpsession => self) if @hb.events
151
157
  @httpsession_var = {}
152
158
  end
153
- end
159
+ end
@@ -20,7 +20,7 @@ class Hayabusa::Erb_handler
20
20
  httpsess.resp.status = 500 if eruby.error
21
21
  end
22
22
 
23
- #Handels the event when an error in the eruby-instance occurs.
23
+ # Handels the event when an error in the eruby-instance occurs.
24
24
  def on_error(e)
25
25
  _hb.handle_error(e)
26
26
  end
@@ -9,7 +9,6 @@ class Hayabusa
9
9
 
10
10
  def clean
11
11
  self.clean_sessions
12
- self.clean_autorestart
13
12
  end
14
13
 
15
14
  def clean_autorestart
@@ -108,18 +107,17 @@ class Hayabusa
108
107
  #Clean up various inactive sessions.
109
108
  session_not_ids = []
110
109
  time_check = Time.now.to_i - 300
111
- newsessions = {}
112
- @sessions.each do |session_hash, session_data|
110
+ @sessions.delete_if do |session_hash, session_data|
113
111
  session_data[:dbobj].flush
114
112
 
115
- if session_data[:time_lastused].to_i > time_check
116
- newsessions[session_hash] = session_data
113
+ if session_data[:dbobj].date_lastused.to_i > time_check
117
114
  session_not_ids << session_data[:dbobj].id
115
+ false
116
+ else
117
+ true
118
118
  end
119
119
  end
120
120
 
121
- @sessions = newsessions
122
-
123
121
  self.log_puts("Delete sessions...") if @debug
124
122
  @ob.list(:Session, {"id_not" => session_not_ids, "date_lastused_below" => (Time.now - 5356800)}) do |session|
125
123
  idhash = session[:idhash]
@@ -116,7 +116,7 @@ class Hayabusa
116
116
  begin
117
117
  block.call
118
118
  rescue => e
119
- self.alert(e.message).back
119
+ Knj::Web.alert(e.message).back
120
120
  end
121
121
  end
122
122
 
@@ -60,17 +60,17 @@ class Hayabusa
60
60
 
61
61
  #Use subprocessing to avoid the mail-framework (activesupport and so on, also possible memory leaks in those large frameworks).
62
62
  self.log_puts("Starting subprocess for mailing.") if @debug
63
- Knj::Process_meta.new("debug" => @debug, "debug_err" => true, "id" => "hayabusa_mailing") do |subproc|
64
- subproc.static("Object", "require", "rubygems")
65
- subproc.static("Object", "require", "mail")
66
- subproc.static("Object", "require", "#{@config[:knjrbfw_path]}knjrbfw")
67
- subproc.static("Object", "require", "knj/autoload")
63
+ Ruby_process::Cproxy.run do |data|
64
+ subproc = data[:subproc]
65
+ subproc.static(:Object, :require, "rubygems")
66
+ subproc.static(:Object, :require, "mail")
67
+ subproc.static(:Object, :require, "#{Knj.knjrbfw_path}/../knjrbfw.rb")
68
68
 
69
69
  self.log_puts("Flushing emails.") if @debug
70
70
  @mails_waiting.each do |mail|
71
71
  begin
72
72
  self.log_puts("Sending email: #{mail.__id__}") if @debug
73
- if mail.send("proc" => subproc)
73
+ if mail.send(:proc => subproc)
74
74
  self.log_puts("Email sent: #{mail.__id__}") if @debug
75
75
  @mails_waiting.delete(mail)
76
76
  end
@@ -119,25 +119,19 @@ class Hayabusa
119
119
  def send(args = {})
120
120
  @args[:hb].log_puts("Sending mail '#{__id__}'.") if @args[:hb].debug
121
121
 
122
- if args["proc"]
123
- args["proc"].static("Object", "require", "knj/mailobj")
124
- mail = args["proc"].new("Knj::Mailobj", @args[:hb].config[:smtp_args])
125
- mail._pm_send_noret("to=", @args[:to])
126
- mail._pm_send_noret("subject=", @args[:subject]) if @args[:subject]
127
- mail._pm_send_noret("html=", Knj::Strings.email_str_safe(@args[:html])) if @args[:html]
128
- mail._pm_send_noret("text=", Knj::Strings.email_str_safe(@args[:text])) if @args[:text]
129
- mail._pm_send_noret("from=", @args[:from])
130
- mail._pm_send_noret("send")
122
+ if args[:proc]
123
+ mail = args[:proc].new("Knj::Mailobj", @args[:hb].config[:smtp_args])
131
124
  else
132
125
  mail = Knj::Mailobj.new(@args[:hb].config[:smtp_args])
133
- mail.to = @args[:to]
134
- mail.subject = @args[:subject] if @args[:subject]
135
- mail.html = Knj::Strings.email_str_safe(@args[:html]) if @args[:html]
136
- mail.text = Knj::Strings.email_str_safe(@args[:text]) if @args[:text]
137
- mail.from = @args[:from]
138
- mail.send
139
126
  end
140
127
 
128
+ mail.to = @args[:to]
129
+ mail.subject = @args[:subject] if @args[:subject]
130
+ mail.html = Knj::Strings.email_str_safe(@args[:html]) if @args[:html]
131
+ mail.text = Knj::Strings.email_str_safe(@args[:text]) if @args[:text]
132
+ mail.from = @args[:from]
133
+ mail.send
134
+
141
135
  @args[:status] = :sent
142
136
  @args[:hb].log_puts("Sent email #{self.__id__}") if @args[:hb].debug
143
137
  return true
@@ -1,4 +1,6 @@
1
1
  class Hayabusa
2
+ attr_reader :sessions
3
+
2
4
  def initialize_sessions
3
5
  @sessions = Tsafe::MonHash.new
4
6
  end
@@ -13,8 +15,11 @@ class Hayabusa
13
15
  session = @ob.add(:Session, {
14
16
  :idhash => idhash,
15
17
  :user_agent => meta["HTTP_USER_AGENT"],
16
- :ip => ip
18
+ :ip => ip,
19
+ :date_lastused => Time.now
17
20
  })
21
+ else
22
+ session[:date_lastused] = Time.now
18
23
  end
19
24
 
20
25
  hash = {}
@@ -28,8 +33,6 @@ class Hayabusa
28
33
  end
29
34
 
30
35
  raise ArgumentError, "Invalid IP." if ip != "bot" and !session.remember? and ip.to_s != session[:ip].to_s
31
-
32
- @sessions[idhash][:time_lastused] = Time.now
33
36
  return [session, hash]
34
37
  end
35
38
 
@@ -16,10 +16,10 @@ class Hayabusa
16
16
  end
17
17
 
18
18
  #Inits the thread so it has access to the appserver and various magic methods can be used.
19
- def thread_init(thread = nil)
20
- thread = Thread.current if thread == nil
19
+ def thread_init(thread = Thread.current)
21
20
  thread[:hayabusa] = {} if !thread[:hayabusa]
22
21
  thread[:hayabusa][:hb] = self
22
+ return nil
23
23
  end
24
24
 
25
25
  #Spawns a new thread with access to magic methods, _db-method and various other stuff in the appserver.
@@ -72,7 +72,7 @@ class Hayabusa
72
72
  thread[:hayabusa][:hb] = self
73
73
 
74
74
  begin
75
- block.call
75
+ return block.call
76
76
  ensure
77
77
  @ob.db.free_thread if @ob.db.opts[:threadsafe]
78
78
  @db_handler.free_thread if @db_handler.opts[:threadsafe]
@@ -100,7 +100,7 @@ class Hayabusa
100
100
 
101
101
  #Urlencodes a string.
102
102
  #===Examples
103
- # _hb.redirect("mypage.rhtml?arg=#{_hb.urlenc(value_variable)}")
103
+ # Knj::Web.redirect("mypage.rhtml?arg=#{_hb.urlenc(value_variable)}")
104
104
  def urlenc(str)
105
105
  return Knj::Web.urlenc(str)
106
106
  end
@@ -64,7 +64,7 @@ class Hayabusa::Fcgi
64
64
  end
65
65
 
66
66
  if hayabusa_conf[:debug]
67
- @fcgi_proxy[:fp_log] = File.open("/tmp/hayabusa_#{hayabusa_conf[:hayabusa][:title]}_#{Process.pid}.log", "w")
67
+ @fcgi_proxy[:fp_log] = File.open("/tmp/hayabusa_#{hayabusa_conf[:title]}_#{Process.pid}.log", "w")
68
68
  @fcgi_proxy[:fp_log].sync = true
69
69
  end
70
70
  rescue
@@ -82,31 +82,35 @@ class Hayabusa::Http_session < Hayabusa::Client_session
82
82
  @handler.socket_parse(@socket)
83
83
  end
84
84
 
85
- @hb.log_puts "#{__id__} - Done parsing from socket." if @debug
86
-
87
- while @hb.paused? #Check if we should be waiting with executing the pending request.
88
- @hb.log_puts "#{__id__} - Paused! (#{@hb.paused}) - sleeping." if @debug
89
- sleep 0.1
90
- end
91
-
92
- break if @hb.should_restart
93
-
94
- if max_requests_working and @httpserver
95
- while @httpserver.working_count.to_i >= max_requests_working
96
- @hb.log_puts "#{__id__} - Maximum amounts of requests are working (#{@httpserver.working_count}, #{max_requests_working}) - sleeping." if @debug
85
+ begin
86
+ @hb.log_puts "#{__id__} - Done parsing from socket." if @debug
87
+
88
+ while @hb.paused? #Check if we should be waiting with executing the pending request.
89
+ @hb.log_puts "#{__id__} - Paused! (#{@hb.paused}) - sleeping." if @debug
97
90
  sleep 0.1
98
91
  end
99
- end
100
-
101
- #Reserve database connections.
102
- @hb.db_handler.get_and_register_thread if @hb.db_handler.opts[:threadsafe]
103
- @hb.ob.db.get_and_register_thread if @hb.ob.db.opts[:threadsafe]
104
-
105
- @working = true
106
- @hb.log_puts "#{__id__} - Serving." if @debug
107
-
108
- @httpserver.count_block do
109
- self.serve
92
+
93
+ break if @hb.should_restart
94
+
95
+ if max_requests_working and @httpserver
96
+ while @httpserver.working_count.to_i >= max_requests_working
97
+ @hb.log_puts "#{__id__} - Maximum amounts of requests are working (#{@httpserver.working_count}, #{max_requests_working}) - sleeping." if @debug
98
+ sleep 0.1
99
+ end
100
+ end
101
+
102
+ #Reserve database connections.
103
+ @hb.db_handler.get_and_register_thread if @hb.db_handler.opts[:threadsafe]
104
+ @hb.ob.db.get_and_register_thread if @hb.ob.db.opts[:threadsafe]
105
+
106
+ @working = true
107
+ @hb.log_puts "#{__id__} - Serving." if @debug
108
+
109
+ @httpserver.count_block do
110
+ self.serve
111
+ end
112
+ ensure
113
+ @handler.delete_tempfiles
110
114
  end
111
115
  ensure
112
116
  @hb.log_puts "#{__id__} - Closing request." if @debug
@@ -132,11 +136,11 @@ class Hayabusa::Http_session < Hayabusa::Client_session
132
136
  end
133
137
 
134
138
  def self.finalize(id)
135
- @hb.log_puts "Http_session finalize #{id}." if @debug
139
+ @hb.log_puts "Hayabusa: Http_session finalize #{id}." if @debug
136
140
  end
137
141
 
138
142
  def destruct
139
- @hb.log_puts "Http_session destruct (#{@httpserver.http_sessions.length})" if @debug and @httpserver and @httpserver.http_sessions
143
+ @hb.log_puts "Hayabusa: Http_session destruct (#{@httpserver.http_sessions.length})" if @debug and @httpserver and @httpserver.http_sessions
140
144
 
141
145
  begin
142
146
  @socket.close if !@socket.closed?
@@ -153,7 +157,7 @@ class Hayabusa::Http_session < Hayabusa::Client_session
153
157
  end
154
158
 
155
159
  def serve
156
- @hb.log_puts "Generating meta, cookie, get, post and headers." if @debug
160
+ @hb.log_puts "Hayabusa: Generating meta, cookie, get, post and headers." if @debug
157
161
  @meta = @handler.meta.merge(@socket_meta)
158
162
  @cookie = @handler.cookie
159
163
  @get = @handler.get
@@ -184,7 +188,7 @@ class Hayabusa::Http_session < Hayabusa::Client_session
184
188
  @browser = Knj::Web.browser(@meta)
185
189
  @ip = @hb.ip(:meta => @meta)
186
190
 
187
- @hb.log_puts "Figuring out session-ID, session-object and more." if @debug
191
+ @hb.log_puts "Hayabusa: Figuring out session-ID, session-object and more." if @debug
188
192
  if @cookie["HayabusaSession"].to_s.length > 0
189
193
  @session_id = @cookie["HayabusaSession"]
190
194
  elsif @browser["browser"] == "bot"
@@ -213,7 +217,7 @@ class Hayabusa::Http_session < Hayabusa::Client_session
213
217
  end
214
218
 
215
219
  if @config.key?(:logging) and @config[:logging][:access_db]
216
- @hb.log_puts "Doing access-logging." if @debug
220
+ @hb.log_puts "Hayabusa: Doing access-logging." if @debug
217
221
  @ips = [@meta["REMOTE_ADDR"]]
218
222
  @ips << @meta["HTTP_X_FORWARDED_FOR"].split(",")[0].strip if @meta["HTTP_X_FORWARDED_FOR"]
219
223
  @hb.logs_access_pending << {
@@ -3,7 +3,7 @@
3
3
  #This class handels the adding of content and writing to socket. Since this can be done with multiple threads and multiple IO's it can get complicated.
4
4
  class Hayabusa::Http_session::Contentgroup
5
5
  attr_reader :done, :cur_data
6
- attr_accessor :chunked, :socket
6
+ attr_accessor :chunked, :socket, :content_length, :length_written
7
7
  NL = "\r\n"
8
8
 
9
9
  def initialize(args = {})
@@ -13,6 +13,8 @@ class Hayabusa::Http_session::Contentgroup
13
13
  @httpsession = args[:httpsession]
14
14
  @mutex = Mutex.new
15
15
  @debug = false
16
+ @length_written = args[:length_written] ? args[:length_written] : 0
17
+ @content_length = args[:content_length]
16
18
  end
17
19
 
18
20
  def init
@@ -30,6 +32,7 @@ class Hayabusa::Http_session::Contentgroup
30
32
  @done = false
31
33
  @thread = nil
32
34
  @forced = false
35
+ @length_written = 0
33
36
 
34
37
  @mutex.synchronize do
35
38
  self.new_io
@@ -55,7 +58,7 @@ class Hayabusa::Http_session::Contentgroup
55
58
  end
56
59
 
57
60
  def new_thread
58
- cgroup = Hayabusa::Http_session::Contentgroup.new(:socket => @socket, :chunked => @chunked)
61
+ cgroup = Hayabusa::Http_session::Contentgroup.new(:socket => @socket, :chunked => @chunked, :content_length => @content_length)
59
62
  cgroup.init
60
63
 
61
64
  @mutex.synchronize do
@@ -92,6 +95,8 @@ class Hayabusa::Http_session::Contentgroup
92
95
  STDERR.puts "Error while writing."
93
96
  STDERR.puts e.inspect
94
97
  STDERR.puts e.backtrace
98
+
99
+ raise e
95
100
  end
96
101
  end
97
102
  end
@@ -125,7 +130,12 @@ class Hayabusa::Http_session::Contentgroup
125
130
 
126
131
  @ios.each do |data|
127
132
  if data.is_a?(Hayabusa::Http_session::Contentgroup)
133
+ data.length_written = @length_written
134
+ data.content_length = @content_length
135
+ data.chunked = @chunked
128
136
  data.write_to_socket
137
+
138
+ @length_written += data.length_written
129
139
  elsif data.key?(:str)
130
140
  if data[:str].is_a?(Hash) and data[:str][:type] == :file
131
141
  File.open(data[:str][:path], "r") do |file|
@@ -136,6 +146,8 @@ class Hayabusa::Http_session::Contentgroup
136
146
  break
137
147
  end
138
148
 
149
+ add_to_length_written(buf.bytesize)
150
+
139
151
  if @chunked
140
152
  @socket.write("#{buf.length.to_s(16)}#{NL}#{buf}#{NL}")
141
153
  else
@@ -157,6 +169,7 @@ class Hayabusa::Http_session::Contentgroup
157
169
  #512 could take a long time for big pages. 16384 seems to be an optimal number.
158
170
  str.each_slice(16384) do |slice|
159
171
  buf = slice.pack("C*")
172
+ add_to_length_written(buf.bytesize)
160
173
 
161
174
  if @chunked
162
175
  @socket.write("#{buf.length.to_s(16)}#{NL}#{buf}#{NL}")
@@ -173,4 +186,10 @@ class Hayabusa::Http_session::Contentgroup
173
186
 
174
187
  count += 1
175
188
  end
189
+
190
+ # Adds the given size to the length written and raises an exception if it exceeds the sat content-length.
191
+ def add_to_length_written(size)
192
+ @length_written += size
193
+ raise "Content-Length overwritten: #{@length_written}, #{@content_length}" if @content_length != nil && @length_written > @content_length
194
+ end
176
195
  end
@@ -17,6 +17,7 @@ class Hayabusa::Http_session::Post_multipart
17
17
  @clength = 0
18
18
  @headers = {}
19
19
  @counts = {}
20
+ @files_arr = args[:files_arr]
20
21
  str_crlf = nil
21
22
 
22
23
  @args[:io].each do |line|
@@ -112,7 +113,11 @@ class Hayabusa::Http_session::Post_multipart
112
113
  return nil
113
114
  end
114
115
 
115
- @data.close(false) if @data.is_a?(Tempfile)
116
+ if @data.is_a?(Tempfile)
117
+ @data.close(false)
118
+ @files_arr << @data.path if @data.respond_to?(:path)
119
+ end
120
+
116
121
  raise "No 'content-disposition' was given (#{@headers}) (#{@data})." if !@name
117
122
 
118
123
  if @fname
@@ -203,4 +208,8 @@ class Hayabusa::Http_session::Post_multipart::File_upload
203
208
  def to_json(*args)
204
209
  raise "File_upload-objects should not be converted to json."
205
210
  end
211
+
212
+ def unset
213
+
214
+ end
206
215
  end
@@ -7,7 +7,7 @@ end
7
7
 
8
8
  #This class parses the various HTTP requests into easy programmable objects. Get, post, cookie, meta and so on...
9
9
  class Hayabusa::Http_session::Request
10
- attr_reader :get, :post, :cookie, :meta, :page_path, :headers, :http_version, :read, :clength, :speed, :percent, :secs_left
10
+ attr_reader :get, :post, :cookie, :files_arr, :meta, :page_path, :headers, :http_version, :read, :clength, :speed, :percent, :secs_left
11
11
 
12
12
  #Sets the various required data on the object. Hayabusa, crlf and arguments.
13
13
  def initialize(args)
@@ -79,6 +79,7 @@ class Hayabusa::Http_session::Request
79
79
 
80
80
  @page_path = "#{@hb.config[:doc_root]}/#{page_filepath}"
81
81
  @get = Knj::Web.parse_urlquery(uri[:query], :urldecode => true, :force_utf8 => true)
82
+ @files_arr = []
82
83
 
83
84
  if @get["_hb_httpsession_id"]
84
85
  @hb.httpsessions_ids[@get["_hb_httpsession_id"]] = @args[:httpsession]
@@ -187,7 +188,8 @@ class Hayabusa::Http_session::Request
187
188
  post_treated = Hayabusa::Http_session::Post_multipart.new(
188
189
  :io => post_data,
189
190
  :boundary => match[1],
190
- :crlf => @crlf
191
+ :crlf => @crlf,
192
+ :files_arr => @files_arr
191
193
  ).return
192
194
  post_data.close(true)
193
195
 
@@ -237,4 +239,12 @@ class Hayabusa::Http_session::Request
237
239
  Knj::Web.parse_name(seton, varname, value, args)
238
240
  end
239
241
  end
242
+
243
+ #Deletes all tempfiles created by this object. This is useually called from Http_session at the end of a request.
244
+ def delete_tempfiles
245
+ @files_arr.delete_if do |tempfile_path|
246
+ File.unlink(tempfile_path) if File.exists?(tempfile_path)
247
+ true
248
+ end
249
+ end
240
250
  end
@@ -21,6 +21,7 @@ class Hayabusa::Http_session::Response
21
21
  401 => "Unauthorized",
22
22
  403 => "Forbidden",
23
23
  404 => "Not Found",
24
+ 408 => "Request Timeout",
24
25
  500 => "Internal Server Error"
25
26
  }
26
27
  NL = "\r\n"
@@ -40,29 +41,18 @@ class Hayabusa::Http_session::Response
40
41
  @trailers = []
41
42
  @skip_statuscode = true if args[:mode] == :cgi
42
43
  @session_cookie = args[:cookie]
43
-
44
44
  @headers_sent = false
45
45
  @headers_trailing = {}
46
-
47
46
  @mode = args[:mode]
47
+ @cookies = []
48
48
 
49
49
  @headers = {
50
50
  "date" => ["Date", Time.now.httpdate]
51
51
  }
52
52
 
53
- @headers_11 = {
54
- "Connection" => "Keep-Alive"
55
- }
56
53
  if args[:mode] != :cgi and (!args.key?(:chunked) or args[:chunked])
57
- @headers_11["Transfer-Encoding"] = "chunked"
54
+ @chunked = true
58
55
  end
59
-
60
- #Socket-timeout is currently broken in JRuby.
61
- if RUBY_ENGINE != "jruby"
62
- @headers_11["Keep-Alive"] = "timeout=15, max=30"
63
- end
64
-
65
- @cookies = []
66
56
  end
67
57
 
68
58
  def header(key, val)
@@ -70,19 +60,48 @@ class Hayabusa::Http_session::Response
70
60
  raise "Value contains more lines than 1 (#{lines})." if lines > 1
71
61
 
72
62
  if !@headers_sent
73
- @headers[key.to_s.downcase] = [key, val]
63
+ @headers[key.to_s.downcase.strip] = [key, val]
74
64
  else
75
65
  raise "Headers already sent and given header was not in trailing headers: '#{key}'." if @trailers.index(key) == nil
76
- @headers_trailing[key.to_s.downcase] = [key, val]
66
+ @headers_trailing[key.to_s.downcase.strip] = [key, val]
77
67
  end
78
68
  end
79
69
 
70
+ # Returns the value of a header.
71
+ def get_header_value(header)
72
+ header_p = header.to_s.downcase.strip
73
+
74
+ gothrough = [@headers, @headers_trailing]
75
+ gothrough.each do |headers|
76
+ headers.each do |key, val|
77
+ return val[1] if header_p == key
78
+ end
79
+ end
80
+
81
+ return nil
82
+ end
83
+
84
+ # Returns true if the given header-name is sat.
85
+ def has_header?(header)
86
+ header_p = header.to_s.downcase.strip
87
+ return @headers.key?(header_p) || @headers_trailing.key?(header_p)
88
+ end
89
+
80
90
  def cookie(cookie)
81
91
  @cookies << cookie
82
92
  @session_cookie[cookie["name"]] = cookie["value"]
83
93
  end
84
94
 
85
95
  def header_str
96
+ if @http_version == "1.1" && @chunked
97
+ self.header("Connection", "Keep-Alive")
98
+ self.header("Transfer-Encoding", "chunked")
99
+ elsif @http_version == "1.1" && get_header_value("content-length").to_i > 0
100
+ self.header("Connection", "Keep-Alive")
101
+ end
102
+
103
+ self.header("Keep-Alive", "timeout=15, max=30") if self.get_header_value("connection") == "Keep-Alive"
104
+
86
105
  if @skip_statuscode
87
106
  res = ""
88
107
  else
@@ -102,10 +121,6 @@ class Hayabusa::Http_session::Response
102
121
  end
103
122
 
104
123
  if @http_version == "1.1"
105
- @headers_11.each do |key, val|
106
- res << "#{key}: #{val}#{NL}"
107
- end
108
-
109
124
  @trailers.each do |trailer|
110
125
  res << "Trailer: #{trailer}#{NL}"
111
126
  end
@@ -121,8 +136,17 @@ class Hayabusa::Http_session::Response
121
136
  end
122
137
 
123
138
  def write
124
- @headers_sent = true
139
+ # Write headers to socket.
125
140
  @socket.write(self.header_str)
141
+ @headers_sent = true
142
+ @cgroup.chunked = @chunked
143
+
144
+ # Set the content-length on the content-group to enable write-lenght-validation.
145
+ if self.has_header?("content-length")
146
+ @cgroup.content_length = self.get_header_value("content-length").to_i
147
+ else
148
+ @cgroup.content_length = nil
149
+ end
126
150
 
127
151
  if @status == 304
128
152
  #do nothing.
@@ -138,12 +162,19 @@ class Hayabusa::Http_session::Response
138
162
  @socket.write(NL)
139
163
  else
140
164
  @cgroup.write_to_socket
141
- @socket.write("#{NL}#{NL}") if @mode != :cgi
142
165
  end
143
166
  end
144
167
 
168
+ # Validate that no more has been written than given in content-length, since that will corrupt the client.
169
+ if self.has_header?("content-length")
170
+ length = cgroup.length_written
171
+ content_length = self.get_header_value("content-length").to_i
172
+ raise "More written than given in content-length: #{length}, #{content_length}" if length != content_length
173
+ end
174
+
175
+ # Close socket if that should be done.
145
176
  if @close and @mode != :cgi
146
- @hb.log_puts("Closing socket.")
177
+ @hb.log_puts("Hauabusa: Closing socket.")
147
178
  @socket.close
148
179
  end
149
180
  end
@@ -1,7 +1,14 @@
1
1
  <%
2
2
  if _get["choice"] == "dogarbagecollect"
3
+ _hb.clean
3
4
  GC.start
4
- _hb.redirect("?show=debug_memory_usage")
5
+
6
+ #Clean all Knj::Objects used in the application.
7
+ ObjectSpace.each_object(Knj::Objects) do |objects|
8
+ objects.clean_all
9
+ end
10
+
11
+ Knj::Web.redirect("?show=debug_memory_usage")
5
12
  end
6
13
  %>
7
14
 
@@ -11,6 +18,22 @@
11
18
  <input type="button" value="Garbage collect" onclick="location.href='?show=debug_memory_usage&amp;choice=dogarbagecollect';" />
12
19
  </div>
13
20
 
21
+ <h1>Hayabusa sessions</h1>
22
+ <table style="width: 600px;">
23
+ <tbody>
24
+ <tr>
25
+ <td>Active sessions</td>
26
+ <td><%=_hb.num(_hb.sessions.length, 0)%></td>
27
+ </tr>
28
+ <tr>
29
+ <td>Total sessions</td>
30
+ <td><%=_hb.num(_hb.ob.list(:Session, "count" => true), 0)%>
31
+ </tr>
32
+ </tbody>
33
+ </table>
34
+
35
+ <br />
36
+
14
37
  <%
15
38
  Knj::Memory_analyzer.new.write
16
39
  %>
Binary file
@@ -63,21 +63,56 @@ describe "Hayabusa" do
63
63
 
64
64
  raise "Expected thread-pool-priority to be '-3' but it wasnt: '#{$appserver.threadpool.args[:priority]}'." if $appserver.threadpool.args[:priority] != -3
65
65
 
66
- http = Http2.new(:host => "localhost", :port => 80, :encoding_gzip => false, :debug => false)
66
+ http = Http2.new(:host => "localhost", :port => 80, :encoding_gzip => false, :debug => false) rescue nil
67
67
 
68
68
  $testmodes = [{
69
69
  :name => :standalone,
70
70
  :path_pre => "",
71
- :http => Http2.new(:host => "localhost", :port => 1515)
72
- },{
73
- :name => :cgi,
74
- :path_pre => "hayabusa_cgi_test/",
75
- :http => http
76
- },{
77
- :name => :fcgi,
78
- :path_pre => "hayabusa_fcgi_test/",
79
- :http => http
71
+ :http => Http2.new(:host => "localhost", :port => 1515, :debug => false)
80
72
  }]
73
+
74
+ if http
75
+ $testmodes += [{
76
+ :name => :cgi,
77
+ :path_pre => "hayabusa_cgi_test/",
78
+ :http => http
79
+ },{
80
+ :name => :fcgi,
81
+ :path_pre => "hayabusa_fcgi_test/",
82
+ :http => http
83
+ }]
84
+ end
85
+ end
86
+
87
+ it "should be able to get multiple pictures" do
88
+ require "base64"
89
+ require "RMagick"
90
+
91
+ # Symlink 'image.rhtml' first.
92
+ img_from_path = "#{Knj.knjrbfw_path}/webscripts/image.rhtml"
93
+ img_to_path = "#{File.realpath("#{File.dirname(__FILE__)}/../pages")}/image.rhtml"
94
+
95
+ raise "Invalid from path: '#{img_from_path}'." unless File.exists?(img_from_path)
96
+
97
+ File.unlink(img_to_path) if File.symlink?(img_to_path)
98
+ File.symlink(img_from_path, img_to_path)
99
+
100
+ begin
101
+ $testmodes.each do |tdata|
102
+ 5.times do
103
+ path = "#{File.dirname(__FILE__)}/../pages/testpic.jpeg"
104
+
105
+ res = tdata[:http].get("#{tdata[:path_pre]}testpic.jpeg")
106
+ res.body.bytesize.should eql(File.size(path))
107
+
108
+ res.body.bytes.to_a.should eql(File.read(path).bytes.to_a)
109
+
110
+ res = tdata[:http].get("#{tdata[:path_pre]}image.rhtml?force=true&path64=#{Base64.encode64("testpic.jpeg").to_s.strip}")
111
+ end
112
+ end
113
+ ensure
114
+ File.unlink(img_to_path) if File.exists?(img_to_path)
115
+ end
81
116
  end
82
117
 
83
118
  #it "should be able to handle custom urls" do
@@ -128,8 +163,6 @@ describe "Hayabusa" do
128
163
  end
129
164
  end
130
165
 
131
- if false
132
-
133
166
  it "should be able to handle a GET-request." do
134
167
  $testmodes.each do |tdata|
135
168
  res = tdata[:http].get("#{tdata[:path_pre]}spec.rhtml")
@@ -356,8 +389,6 @@ describe "Hayabusa" do
356
389
  end
357
390
  end
358
391
 
359
- end
360
-
361
392
  it "should be able to stop." do
362
393
  $appserver.stop
363
394
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hayabusa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.20
4
+ version: 0.0.22
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-12 00:00:00.000000000 +02:00
13
- default_executable:
12
+ date: 2013-06-28 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: knjrbfw
17
- requirement: &23615180 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
19
  - - ! '>='
@@ -22,10 +21,15 @@ dependencies:
22
21
  version: '0'
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *23615180
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
26
30
  - !ruby/object:Gem::Dependency
27
31
  name: erubis
28
- requirement: &23614160 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
29
33
  none: false
30
34
  requirements:
31
35
  - - ! '>='
@@ -33,10 +37,15 @@ dependencies:
33
37
  version: '0'
34
38
  type: :runtime
35
39
  prerelease: false
36
- version_requirements: *23614160
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
37
46
  - !ruby/object:Gem::Dependency
38
47
  name: mail
39
- requirement: &23613380 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
40
49
  none: false
41
50
  requirements:
42
51
  - - ! '>='
@@ -44,10 +53,15 @@ dependencies:
44
53
  version: '0'
45
54
  type: :runtime
46
55
  prerelease: false
47
- version_requirements: *23613380
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
48
62
  - !ruby/object:Gem::Dependency
49
63
  name: datet
50
- requirement: &23612560 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
51
65
  none: false
52
66
  requirements:
53
67
  - - ! '>='
@@ -55,10 +69,15 @@ dependencies:
55
69
  version: '0'
56
70
  type: :runtime
57
71
  prerelease: false
58
- version_requirements: *23612560
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
59
78
  - !ruby/object:Gem::Dependency
60
79
  name: http2
61
- requirement: &23611880 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
62
81
  none: false
63
82
  requirements:
64
83
  - - ! '>='
@@ -66,10 +85,15 @@ dependencies:
66
85
  version: '0'
67
86
  type: :runtime
68
87
  prerelease: false
69
- version_requirements: *23611880
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
70
94
  - !ruby/object:Gem::Dependency
71
95
  name: tpool
72
- requirement: &23611160 !ruby/object:Gem::Requirement
96
+ requirement: !ruby/object:Gem::Requirement
73
97
  none: false
74
98
  requirements:
75
99
  - - ! '>='
@@ -77,10 +101,31 @@ dependencies:
77
101
  version: '0'
78
102
  type: :runtime
79
103
  prerelease: false
80
- version_requirements: *23611160
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
81
110
  - !ruby/object:Gem::Dependency
82
111
  name: fcgi
83
- requirement: &23610420 !ruby/object:Gem::Requirement
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: ruby_process
128
+ requirement: !ruby/object:Gem::Requirement
84
129
  none: false
85
130
  requirements:
86
131
  - - ! '>='
@@ -88,10 +133,15 @@ dependencies:
88
133
  version: '0'
89
134
  type: :runtime
90
135
  prerelease: false
91
- version_requirements: *23610420
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
92
142
  - !ruby/object:Gem::Dependency
93
143
  name: json
94
- requirement: &23609720 !ruby/object:Gem::Requirement
144
+ requirement: !ruby/object:Gem::Requirement
95
145
  none: false
96
146
  requirements:
97
147
  - - ! '>='
@@ -99,10 +149,15 @@ dependencies:
99
149
  version: '0'
100
150
  type: :development
101
151
  prerelease: false
102
- version_requirements: *23609720
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
103
158
  - !ruby/object:Gem::Dependency
104
159
  name: rspec
105
- requirement: &23609120 !ruby/object:Gem::Requirement
160
+ requirement: !ruby/object:Gem::Requirement
106
161
  none: false
107
162
  requirements:
108
163
  - - ! '>='
@@ -110,10 +165,15 @@ dependencies:
110
165
  version: 2.3.0
111
166
  type: :development
112
167
  prerelease: false
113
- version_requirements: *23609120
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: 2.3.0
114
174
  - !ruby/object:Gem::Dependency
115
175
  name: bundler
116
- requirement: &23606820 !ruby/object:Gem::Requirement
176
+ requirement: !ruby/object:Gem::Requirement
117
177
  none: false
118
178
  requirements:
119
179
  - - ! '>='
@@ -121,10 +181,15 @@ dependencies:
121
181
  version: 1.0.0
122
182
  type: :development
123
183
  prerelease: false
124
- version_requirements: *23606820
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: 1.0.0
125
190
  - !ruby/object:Gem::Dependency
126
191
  name: jeweler
127
- requirement: &23606100 !ruby/object:Gem::Requirement
192
+ requirement: !ruby/object:Gem::Requirement
128
193
  none: false
129
194
  requirements:
130
195
  - - ~>
@@ -132,10 +197,31 @@ dependencies:
132
197
  version: 1.6.3
133
198
  type: :development
134
199
  prerelease: false
135
- version_requirements: *23606100
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - ~>
204
+ - !ruby/object:Gem::Version
205
+ version: 1.6.3
206
+ - !ruby/object:Gem::Dependency
207
+ name: rmagick
208
+ requirement: !ruby/object:Gem::Requirement
209
+ none: false
210
+ requirements:
211
+ - - ! '>='
212
+ - !ruby/object:Gem::Version
213
+ version: '0'
214
+ type: :development
215
+ prerelease: false
216
+ version_requirements: !ruby/object:Gem::Requirement
217
+ none: false
218
+ requirements:
219
+ - - ! '>='
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
136
222
  - !ruby/object:Gem::Dependency
137
223
  name: sqlite3
138
- requirement: &23605540 !ruby/object:Gem::Requirement
224
+ requirement: !ruby/object:Gem::Requirement
139
225
  none: false
140
226
  requirements:
141
227
  - - ! '>='
@@ -143,7 +229,12 @@ dependencies:
143
229
  version: '0'
144
230
  type: :development
145
231
  prerelease: false
146
- version_requirements: *23605540
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ none: false
234
+ requirements:
235
+ - - ! '>='
236
+ - !ruby/object:Gem::Version
237
+ version: '0'
147
238
  description: A threadded web/app-server that focuses on threadding, shared ressources,
148
239
  speed and more.
149
240
  email: k@spernj.org
@@ -239,13 +330,13 @@ files:
239
330
  - pages/spec_vars_header.rhtml
240
331
  - pages/spec_vars_post.rhtml
241
332
  - pages/spec_vars_post_fileupload.rhtml
333
+ - pages/testpic.jpeg
242
334
  - pages/tests.rhtml
243
335
  - pages/threadded_content_test.rhtml
244
336
  - spec/fcgi_multiple_processes_spec.rb
245
337
  - spec/hayabusa_spec.rb
246
338
  - spec/spec_helper.rb
247
339
  - spec/test_upload.xlsx
248
- has_rdoc: true
249
340
  homepage: http://github.com/kaspernj/hayabusa
250
341
  licenses:
251
342
  - MIT
@@ -261,7 +352,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
261
352
  version: '0'
262
353
  segments:
263
354
  - 0
264
- hash: -2750597640536201998
355
+ hash: 4203364333015306411
265
356
  required_rubygems_version: !ruby/object:Gem::Requirement
266
357
  none: false
267
358
  requirements:
@@ -270,7 +361,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
270
361
  version: '0'
271
362
  requirements: []
272
363
  rubyforge_project:
273
- rubygems_version: 1.6.2
364
+ rubygems_version: 1.8.23
274
365
  signing_key:
275
366
  specification_version: 3
276
367
  summary: A threadded web/app-server that supports stand-alone, CGI and FCGI-modes.