serverside 0.1.59 → 0.2.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.
Files changed (48) hide show
  1. data/CHANGELOG +21 -1
  2. data/Rakefile +69 -40
  3. data/bin/serverside +7 -15
  4. data/doc/rdoc/classes/Daemon.html +18 -18
  5. data/doc/rdoc/classes/Daemon/Base.html +8 -6
  6. data/doc/rdoc/classes/Daemon/Cluster.html +36 -36
  7. data/doc/rdoc/classes/Daemon/Cluster/PidFile.html +20 -18
  8. data/doc/rdoc/classes/Daemon/PidFile.html +12 -12
  9. data/doc/rdoc/classes/Object.html +151 -0
  10. data/doc/rdoc/classes/Proc.html +151 -0
  11. data/doc/rdoc/classes/ServerSide.html +69 -0
  12. data/doc/rdoc/classes/ServerSide/Application.html +43 -11
  13. data/doc/rdoc/classes/ServerSide/Application/Base.html +30 -30
  14. data/doc/rdoc/classes/ServerSide/Application/Static.html +20 -18
  15. data/doc/rdoc/classes/ServerSide/Connection.html +3 -3
  16. data/doc/rdoc/classes/ServerSide/Connection/Base.html +142 -99
  17. data/doc/rdoc/classes/ServerSide/Connection/Const.html +11 -13
  18. data/doc/rdoc/classes/ServerSide/Connection/Router.html +464 -0
  19. data/doc/rdoc/classes/ServerSide/Server.html +8 -6
  20. data/doc/rdoc/classes/ServerSide/StaticFiles.html +75 -43
  21. data/doc/rdoc/classes/ServerSide/StaticFiles/Const.html +5 -0
  22. data/doc/rdoc/classes/String.html +20 -18
  23. data/doc/rdoc/classes/Symbol.html +2 -0
  24. data/doc/rdoc/created.rid +1 -1
  25. data/doc/rdoc/files/CHANGELOG.html +32 -2
  26. data/doc/rdoc/files/lib/serverside/application_rb.html +1 -1
  27. data/doc/rdoc/files/lib/serverside/connection_rb.html +1 -1
  28. data/doc/rdoc/files/lib/serverside/core_ext_rb.html +1 -1
  29. data/doc/rdoc/files/lib/serverside/daemon_rb.html +1 -1
  30. data/doc/rdoc/files/lib/serverside/routing_rb.html +101 -0
  31. data/doc/rdoc/files/lib/serverside/static_rb.html +1 -1
  32. data/doc/rdoc/fr_class_index.html +3 -1
  33. data/doc/rdoc/fr_file_index.html +1 -0
  34. data/doc/rdoc/fr_method_index.html +49 -33
  35. data/lib/serverside/application.rb +17 -4
  36. data/lib/serverside/connection.rb +23 -3
  37. data/lib/serverside/core_ext.rb +16 -1
  38. data/lib/serverside/routing.rb +119 -0
  39. data/lib/serverside/static.rb +9 -23
  40. data/test/functional/routing_server.rb +14 -0
  41. data/test/functional/routing_server_test.rb +41 -0
  42. data/test/functional/static_server_test.rb +8 -2
  43. data/test/unit/connection_test.rb +13 -0
  44. data/test/unit/core_ext_test.rb +14 -0
  45. data/test/unit/routing_test.rb +171 -0
  46. data/test/unit/static_test.rb +34 -1
  47. metadata +10 -3
  48. data/doc/rdoc/classes/ServerSide/Connection/Static.html +0 -172
@@ -3,14 +3,20 @@ require 'net/http'
3
3
 
4
4
  class StaticServerTest < Test::Unit::TestCase
5
5
 
6
+ class StaticServer < ServerSide::Connection::Base
7
+ def respond
8
+ serve_static('.'/@path)
9
+ end
10
+ end
11
+
6
12
  def test_basic
7
- t = Thread.new {ServerSide::Server.new('0.0.0.0', 17654, ServerSide::Connection::Static)}
13
+ t = Thread.new {ServerSide::Server.new('0.0.0.0', 17654, StaticServer)}
8
14
  sleep 0.1
9
15
 
10
16
  h = Net::HTTP.new('localhost', 17654)
11
17
  resp, data = h.get('/qqq.zzz', nil)
12
18
  assert_equal 404, resp.code.to_i
13
- assert_equal "Couldn't open file /qqq.zzz.", data
19
+ assert_equal "File not found.", data
14
20
 
15
21
  h = Net::HTTP.new('localhost', 17654)
16
22
  resp, data = h.get("/#{__FILE__}", nil)
@@ -190,4 +190,17 @@ class ConnectionTest < Test::Unit::TestCase
190
190
  assert_equal "HTTP/1.1 404\r\nConnection: close\r\nContent-Type: text/html\r\nSet-Cookie: abc=123\r\n\r\nhey there",
191
191
  r.conn.read
192
192
  end
193
+
194
+ def test_redirect
195
+ r = DummyConnection3.new
196
+ r.conn = StringIO.new
197
+ r.redirect('http://mau.com/132')
198
+ r.conn.rewind
199
+ assert_equal "HTTP/1.1 302\r\nConnection: close\r\nLocation: http://mau.com/132\r\n\r\n", r.conn.read
200
+
201
+ r.conn = StringIO.new
202
+ r.redirect('http://www.google.com/search?q=meaning%20of%20life', true)
203
+ r.conn.rewind
204
+ assert_equal "HTTP/1.1 301\r\nConnection: close\r\nLocation: http://www.google.com/search?q=meaning%20of%20life\r\n\r\n", r.conn.read
205
+ end
193
206
  end
@@ -29,4 +29,18 @@ class SymbolTest < Test::Unit::TestCase
29
29
  assert_equal 'yow_za', :yow_za.to_s
30
30
  assert_equal :yow_za.to_s.object_id, :yow_za.to_s.object_id
31
31
  end
32
+ end
33
+
34
+ class ProcTest < Test::Unit::TestCase
35
+ def test_proc_tag
36
+ l = lambda {puts "hello"}
37
+ assert_equal 'proc_' + l.object_id.to_s(36).sub('-', '_'), l.proc_tag
38
+ end
39
+ end
40
+
41
+ class ObjectTest < Test::Unit::TestCase
42
+ def test_const_tag
43
+ v = "mau mau"
44
+ assert_equal 'C' + v.object_id.to_s(36).upcase.sub('-', '_'), v.const_tag
45
+ end
32
46
  end
@@ -0,0 +1,171 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require 'stringio'
3
+
4
+ class ServerSide::Connection::Router
5
+ attr_accessor :t, :parameters
6
+
7
+ def self.rules
8
+ @@rules
9
+ end
10
+
11
+ def self.remove_rules
12
+ @@rules = nil
13
+ end
14
+
15
+ def self.reset_rules
16
+ @@rules = []
17
+ end
18
+
19
+ def self.reset_respond
20
+ define_method(:respond) {nil}
21
+ end
22
+ end
23
+
24
+ class RoutingTest < Test::Unit::TestCase
25
+ R = ServerSide::Connection::Router
26
+
27
+ def test_has_routes?
28
+ R.remove_rules
29
+ assert_nil R.has_routes?
30
+ R.reset_rules
31
+ assert_equal false, R.has_routes?
32
+ R.route('/controller/:action/:id') {}
33
+ assert_equal true, R.has_routes?
34
+ end
35
+
36
+ def test_route
37
+ l1 = lambda {1 + 1}
38
+ R.reset_rules
39
+ R.route('/controller/:action/:id', &l1)
40
+ assert_equal 1, R.rules.length
41
+ assert_equal({:path => '/controller/:action/:id'}, R.rules[0][0])
42
+ assert_equal l1, R.rules[0][1]
43
+
44
+ l2 = lambda {2 + 2}
45
+ R.route(:host => '^static\..+', &l2)
46
+ assert_equal 2, R.rules.length
47
+ assert_equal({:host => '^static\..+'}, R.rules[0][0])
48
+ assert_equal l2, R.rules[0][1]
49
+ assert_equal({:path => '/controller/:action/:id'}, R.rules[1][0])
50
+ assert_equal l1, R.rules[1][1]
51
+
52
+ l3 = lambda {3 + 3}
53
+ l4 = lambda {4 + 4}
54
+
55
+ R.route(l3, &l4)
56
+ assert_equal 3, R.rules.length
57
+ assert_equal l3, R.rules[0][0]
58
+ assert_equal l4, R.rules[0][1]
59
+ assert_equal({:host => '^static\..+'}, R.rules[1][0])
60
+ assert_equal l2, R.rules[1][1]
61
+ assert_equal({:path => '/controller/:action/:id'}, R.rules[2][0])
62
+ assert_equal l1, R.rules[2][1]
63
+ end
64
+
65
+ def test_compile_rules
66
+ R.reset_rules
67
+ R.reset_respond
68
+
69
+ assert_equal nil, R.new(StringIO.new).respond
70
+ R.rules << [{:t => 'abc'}, lambda{1}]
71
+ R.rules << [{:t => 'def'}, lambda{2}]
72
+ R.route_default {3}
73
+ R.compile_rules
74
+ r = R.new(StringIO.new)
75
+ r.t = 'abc'
76
+ assert_equal 1, r.respond
77
+ r.t = 'def'
78
+ assert_equal 2, r.respond
79
+ r.t = ''
80
+ assert_equal 3, r.respond
81
+ end
82
+
83
+ def test_rule_to_statement
84
+ l1 = lambda {1 + 1}
85
+ l2 = lambda {2 + 2}
86
+ s = R.rule_to_statement(l1, l2)
87
+ assert_equal "return #{l2.proc_tag} if #{l1.proc_tag}\n" ,s
88
+ r = R.new(StringIO.new)
89
+ assert_equal true, r.respond_to?(l1.proc_tag)
90
+ assert_equal true, r.respond_to?(l2.proc_tag)
91
+
92
+ l3 = lambda {3 + 3}
93
+ s = R.rule_to_statement({:path => '/.*'}, l3)
94
+ assert_not_nil s =~ /^return\s#{l3.proc_tag}\sif\s\(@path\s=~\s(.*)\)\n$/, s
95
+ assert_equal /\/.*/, eval("R::#{$1}")
96
+ assert_equal true, r.respond_to?(l3.proc_tag)
97
+
98
+ l4 = lambda {4 + 4}
99
+ s = R.rule_to_statement({:path => '/controller', :host => 'static'}, l4)
100
+ assert_not_nil s =~ /^return\s#{l4.proc_tag}\sif\s\(.+\)&&\(.+\)\n$/
101
+ assert_not_nil s =~ /\(@path\s=~\s([^\)]+)\)/
102
+ assert_equal /\/controller/, eval("R::#{$1}")
103
+ assert_not_nil s =~ /\(@host\s=~\s([^\)]+)\)/
104
+ assert_equal /static/, eval("R::#{$1}")
105
+ assert_equal true, r.respond_to?(l4.proc_tag)
106
+
107
+ l5 = lambda {5 + 5}
108
+ s = R.rule_to_statement({:path => ['/x', '/y']}, l5)
109
+ assert_not_nil s =~ /^return\s#{l5.proc_tag}\sif\s\(\(@path\s=~\s(.*)\)\|\|\(@path\s=~\s(.*)\)\)\n$/
110
+ assert_equal /\/x/, eval("R::#{$1}")
111
+ assert_equal /\/y/, eval("R::#{$2}")
112
+ assert_equal true, r.respond_to?(l5.proc_tag)
113
+ end
114
+
115
+ def test_condition_part
116
+ s = R.condition_part(:t, 'abc')
117
+ assert_not_nil s =~ /^\(@t\s=~\s(.*)\)$/
118
+ assert_equal /abc/, eval("R::#{$1}")
119
+
120
+ s = R.condition_part(:t, ':action/:id')
121
+ assert_not_nil s =~ /^\((.*)\)$/
122
+ tag = $1
123
+ r = R.new(StringIO.new)
124
+ assert_equal true, r.respond_to?(tag)
125
+ r.parameters = {}
126
+ r.t = 'abc'
127
+ assert_equal false, r.send(tag)
128
+ r.t = 'show/16'
129
+ assert_equal true, r.send(tag)
130
+ assert_equal 'show', r.parameters[:action]
131
+ assert_equal '16', r.parameters[:id]
132
+ end
133
+
134
+ def test_define_proc
135
+ l1 = lambda {1 + 1}
136
+ tag = R.define_proc(&l1)
137
+ assert_kind_of Symbol, tag
138
+ assert_equal l1.proc_tag.to_sym, tag
139
+ r = R.new(StringIO.new)
140
+ assert 2, r.send(tag)
141
+ end
142
+
143
+ def test_cache_constant
144
+ c = rand(100000)
145
+ tag = R.cache_constant(c)
146
+ assert_kind_of String, tag
147
+ assert_equal c.const_tag, tag
148
+ assert_equal c, eval("R::#{tag}")
149
+ end
150
+
151
+ def test_route_default
152
+ R.route_default {'mau m'}
153
+ assert_equal 'mau m', R.new(StringIO.new).default_handler
154
+
155
+ R.route_default {654321}
156
+ assert_equal 654321, R.new(StringIO.new).default_handler
157
+ end
158
+
159
+ def test_serverside_route
160
+ R.reset_rules
161
+ ServerSide.route(:path => 'abc') {1 + 1}
162
+ assert_equal 1, R.rules.length
163
+ assert_equal({:path => 'abc'}, R.rules[0][0])
164
+ assert_equal 2, R.rules[0][1].call
165
+ end
166
+
167
+ def test_serverside_route_default
168
+ ServerSide.route_default {1234}
169
+ assert_equal 1234, R.new(StringIO.new).default_handler
170
+ end
171
+ end
@@ -3,7 +3,7 @@ require 'stringio'
3
3
  require 'fileutils'
4
4
 
5
5
  class ConnectionTest < Test::Unit::TestCase
6
- class Dummy < ServerSide::Connection::Static
6
+ class Dummy < ServerSide::Connection::Base
7
7
  def self.static_files
8
8
  @@static_files
9
9
  end
@@ -140,4 +140,37 @@ class ConnectionTest < Test::Unit::TestCase
140
140
  assert_not_nil resp =~ /<a href="#{dir/fn}">(#{fn})<\/a>/
141
141
  end
142
142
  end
143
+
144
+ def test_serve_static
145
+ dir = File.dirname(__FILE__)
146
+
147
+ c = Dummy.new
148
+ c.conn = StringIO.new
149
+ c.path = dir
150
+ c.serve_static(dir)
151
+ c.conn.rewind
152
+ resp = c.conn.read
153
+
154
+ Dir.entries(dir).each do |fn|
155
+ next if fn == '.'
156
+ assert_not_nil resp =~ /<a href="#{dir/fn}">(#{fn})<\/a>/
157
+ end
158
+
159
+ c.conn = StringIO.new
160
+ c.serve_file(__FILE__)
161
+ c.conn.rewind
162
+ resp = c.conn.read
163
+
164
+ # normal response
165
+ assert_equal '200', /HTTP\/1.1\s(.*)\r\n/.match(resp)[1]
166
+ fc = IO.read(__FILE__)
167
+ stat = File.stat(__FILE__)
168
+ etag = (ServerSide::StaticFiles::Const::ETagFormat %
169
+ [stat.mtime.to_i, stat.size, stat.ino])
170
+ assert_equal etag, /ETag:\s(.*)\r\n/.match(resp)[1]
171
+ assert_equal ServerSide::StaticFiles::Const::MaxAge,
172
+ /Cache-Control:\s(.*)\r\n/.match(resp)[1]
173
+ assert_equal stat.size.to_s,
174
+ /Content-Length:\s(.*)\r\n/.match(resp)[1]
175
+ end
143
176
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: serverside
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.59
7
- date: 2006-08-22 00:00:00 +03:00
6
+ version: 0.2.0
7
+ date: 2006-08-28 00:00:00 +03:00
8
8
  summary: Performance-oriented web framework.
9
9
  require_paths:
10
10
  - lib
@@ -54,7 +54,10 @@ files:
54
54
  - doc/rdoc/files/lib/serverside/connection_rb.html
55
55
  - doc/rdoc/files/lib/serverside/cluster_rb.html
56
56
  - doc/rdoc/files/lib/serverside/static_rb.html
57
+ - doc/rdoc/files/lib/serverside/routing_rb.html
57
58
  - doc/rdoc/classes/Symbol.html
59
+ - doc/rdoc/classes/Proc.html
60
+ - doc/rdoc/classes/Object.html
58
61
  - doc/rdoc/classes/String.html
59
62
  - doc/rdoc/classes/Daemon.html
60
63
  - doc/rdoc/classes/Daemon
@@ -77,7 +80,7 @@ files:
77
80
  - doc/rdoc/classes/ServerSide/Application/Static.html
78
81
  - doc/rdoc/classes/ServerSide/Connection/Const.html
79
82
  - doc/rdoc/classes/ServerSide/Connection/Base.html
80
- - doc/rdoc/classes/ServerSide/Connection/Static.html
83
+ - doc/rdoc/classes/ServerSide/Connection/Router.html
81
84
  - test/unit
82
85
  - test/test_helper.rb
83
86
  - test/functional
@@ -88,10 +91,13 @@ files:
88
91
  - test/unit/connection_test.rb
89
92
  - test/unit/cluster_test.rb
90
93
  - test/unit/static_test.rb
94
+ - test/unit/routing_test.rb
91
95
  - test/functional/primitive_static_server_test.rb
92
96
  - test/functional/static_server_test.rb
93
97
  - test/functional/static_profile.rb
94
98
  - test/functional/static_rfuzz.rb
99
+ - test/functional/routing_server.rb
100
+ - test/functional/routing_server_test.rb
95
101
  - lib/serverside.rb
96
102
  - lib/serverside
97
103
  - lib/serverside/server.rb
@@ -101,6 +107,7 @@ files:
101
107
  - lib/serverside/connection.rb
102
108
  - lib/serverside/cluster.rb
103
109
  - lib/serverside/static.rb
110
+ - lib/serverside/routing.rb
104
111
  - CHANGELOG
105
112
  test_files: []
106
113
 
@@ -1,172 +0,0 @@
1
- <?xml version="1.0" encoding="iso-8859-1"?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
-
6
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
- <head>
8
- <title>Class: ServerSide::Connection::Static</title>
9
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
- <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
- <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
12
- <script type="text/javascript">
13
- // <![CDATA[
14
-
15
- function popupCode( url ) {
16
- window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
- }
18
-
19
- function toggleCode( id ) {
20
- if ( document.getElementById )
21
- elem = document.getElementById( id );
22
- else if ( document.all )
23
- elem = eval( "document.all." + id );
24
- else
25
- return false;
26
-
27
- elemStyle = elem.style;
28
-
29
- if ( elemStyle.display != "block" ) {
30
- elemStyle.display = "block"
31
- } else {
32
- elemStyle.display = "none"
33
- }
34
-
35
- return true;
36
- }
37
-
38
- // Make codeblocks hidden by default
39
- document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
-
41
- // ]]>
42
- </script>
43
-
44
- </head>
45
- <body>
46
-
47
-
48
-
49
- <div id="classHeader">
50
- <table class="header-table">
51
- <tr class="top-aligned-row">
52
- <td><strong>Class</strong></td>
53
- <td class="class-name-in-header">ServerSide::Connection::Static</td>
54
- </tr>
55
- <tr class="top-aligned-row">
56
- <td><strong>In:</strong></td>
57
- <td>
58
- <a href="../../../files/lib/serverside/static_rb.html">
59
- lib/serverside/static.rb
60
- </a>
61
- <br />
62
- </td>
63
- </tr>
64
-
65
- <tr class="top-aligned-row">
66
- <td><strong>Parent:</strong></td>
67
- <td>
68
- <a href="Base.html">
69
- Base
70
- </a>
71
- </td>
72
- </tr>
73
- </table>
74
- </div>
75
- <!-- banner header -->
76
-
77
- <div id="bodyContent">
78
-
79
-
80
-
81
- <div id="contextContent">
82
-
83
- <div id="description">
84
- <p>
85
- A connection type for serving static files.
86
- </p>
87
-
88
- </div>
89
-
90
-
91
- </div>
92
-
93
- <div id="method-list">
94
- <h3 class="section-bar">Methods</h3>
95
-
96
- <div class="name-list">
97
- <a href="#M000033">respond</a>&nbsp;&nbsp;
98
- </div>
99
- </div>
100
-
101
- </div>
102
-
103
-
104
- <!-- if includes -->
105
- <div id="includes">
106
- <h3 class="section-bar">Included Modules</h3>
107
-
108
- <div id="includes-list">
109
- <span class="include-name"><a href="../StaticFiles.html">StaticFiles</a></span>
110
- </div>
111
- </div>
112
-
113
- <div id="section">
114
-
115
-
116
-
117
-
118
-
119
-
120
-
121
-
122
- <!-- if method_list -->
123
- <div id="methods">
124
- <h3 class="section-bar">Public Instance methods</h3>
125
-
126
- <div id="method-M000033" class="method-detail">
127
- <a name="M000033"></a>
128
-
129
- <div class="method-heading">
130
- <a href="#M000033" class="method-signature">
131
- <span class="method-name">respond</span><span class="method-args">()</span>
132
- </a>
133
- </div>
134
-
135
- <div class="method-description">
136
- <p>
137
- Responds with a file&#8217;s content or a directory listing. If the path
138
- does not exist, a 404 response is rendered.
139
- </p>
140
- <p><a class="source-toggle" href="#"
141
- onclick="toggleCode('M000033-source');return false;">[Source]</a></p>
142
- <div class="method-source-code" id="M000033-source">
143
- <pre>
144
- <span class="ruby-comment cmt"># File lib/serverside/static.rb, line 83</span>
145
- 83: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">respond</span>
146
- 84: <span class="ruby-identifier">fn</span> = <span class="ruby-value str">'./%s'</span> <span class="ruby-operator">%</span> <span class="ruby-ivar">@path</span>
147
- 85: <span class="ruby-keyword kw">if</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">file?</span>(<span class="ruby-identifier">fn</span>)
148
- 86: <span class="ruby-identifier">serve_file</span>(<span class="ruby-identifier">fn</span>)
149
- 87: <span class="ruby-keyword kw">elsif</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">directory?</span>(<span class="ruby-identifier">fn</span>)
150
- 88: <span class="ruby-identifier">serve_dir</span>(<span class="ruby-identifier">fn</span>)
151
- 89: <span class="ruby-keyword kw">else</span>
152
- 90: <span class="ruby-identifier">send_response</span>(<span class="ruby-value">404</span>, <span class="ruby-value str">'text'</span>, <span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">FileNotFound</span> <span class="ruby-operator">%</span> <span class="ruby-ivar">@path</span>)
153
- 91: <span class="ruby-keyword kw">end</span>
154
- 92: <span class="ruby-keyword kw">end</span>
155
- </pre>
156
- </div>
157
- </div>
158
- </div>
159
-
160
-
161
- </div>
162
-
163
-
164
- </div>
165
-
166
-
167
- <div id="validator-badges">
168
- <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
169
- </div>
170
-
171
- </body>
172
- </html>