nyara 0.0.1.pre.9 → 0.1.pre.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/bin/nyara +3 -3
  3. data/changes +1 -0
  4. data/ext/event.c +16 -22
  5. data/ext/hashes.c +222 -4
  6. data/ext/inc/rdtsc.h +56 -0
  7. data/ext/inc/status_codes.inc +64 -0
  8. data/ext/inc/version.inc +1 -1
  9. data/ext/nyara.c +12 -10
  10. data/ext/nyara.h +5 -5
  11. data/ext/request.c +18 -24
  12. data/ext/request_parse.c +1 -1
  13. data/ext/route.cc +2 -4
  14. data/ext/url_encoded.c +51 -193
  15. data/lib/nyara/command.rb +39 -12
  16. data/lib/nyara/config.rb +10 -10
  17. data/lib/nyara/controller.rb +60 -14
  18. data/lib/nyara/cookie.rb +1 -1
  19. data/lib/nyara/hashes/config_hash.rb +2 -24
  20. data/lib/nyara/nyara.rb +33 -19
  21. data/lib/nyara/part.rb +7 -3
  22. data/lib/nyara/reload.rb +85 -0
  23. data/lib/nyara/request.rb +1 -1
  24. data/lib/nyara/route.rb +55 -19
  25. data/lib/nyara/templates/Gemfile +10 -1
  26. data/lib/nyara/templates/Rakefile +6 -1
  27. data/lib/nyara/templates/app/controllers/application_controller.rb +3 -0
  28. data/lib/nyara/templates/app/controllers/welcome_controller.rb +5 -0
  29. data/lib/nyara/templates/app/views/layouts/application.erb +12 -0
  30. data/lib/nyara/templates/app/views/welcome/index.erb +1 -0
  31. data/lib/nyara/templates/config/application.rb +34 -0
  32. data/lib/nyara/templates/config/boot.rb +4 -0
  33. data/lib/nyara/templates/config/development.rb +5 -0
  34. data/lib/nyara/templates/config/production.rb +8 -0
  35. data/lib/nyara/templates/config/test.rb +2 -0
  36. data/lib/nyara/templates/public/css/app.css +1 -0
  37. data/lib/nyara/templates/public/js/app.js +1 -0
  38. data/lib/nyara/templates/spec/spec_helper.rb +9 -0
  39. data/lib/nyara/test.rb +10 -2
  40. data/lib/nyara/view.rb +116 -67
  41. data/nyara.gemspec +3 -1
  42. data/rakefile +1 -1
  43. data/readme.md +1 -1
  44. data/spec/command_spec.rb +28 -24
  45. data/spec/config_spec.rb +24 -1
  46. data/spec/dummy/app/controllers/dummy_controller.rb +2 -0
  47. data/spec/dummy/app/models/dmmy_model.rb +2 -0
  48. data/spec/evented_io_spec.rb +2 -1
  49. data/spec/ext_route_spec.rb +2 -2
  50. data/spec/flash_spec.rb +8 -0
  51. data/spec/hashes_spec.rb +127 -0
  52. data/spec/integration_spec.rb +15 -0
  53. data/spec/path_helper_spec.rb +17 -5
  54. data/spec/performance/escape.rb +15 -4
  55. data/spec/performance/layout_render.rb +15 -10
  56. data/spec/performance/parse_accept_value.rb +24 -8
  57. data/spec/performance/parse_param.rb +14 -8
  58. data/spec/performance/performance_helper.rb +8 -21
  59. data/spec/performance_spec.rb +5 -4
  60. data/spec/route_spec.rb +7 -2
  61. data/spec/url_encoded_spec.rb +18 -74
  62. data/spec/view_spec.rb +1 -3
  63. data/spec/views/_partial.slim +1 -0
  64. data/spec/views/_partial_with_yield.erb +1 -0
  65. metadata +73 -43
  66. data/example/factorial.rb +0 -19
  67. data/example/hello.rb +0 -5
  68. data/example/project.rb +0 -11
  69. data/example/stream.rb +0 -14
  70. data/lib/nyara/controllers/public_controller.rb +0 -14
  71. data/lib/nyara/templates/config/session.key +0 -1
  72. data/tools/bench-cookie.rb +0 -22
  73. data/tools/foo.rb +0 -9
  74. data/tools/hello.rb +0 -46
  75. data/tools/memcheck.rb +0 -33
  76. data/tools/s.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: abcd7918ded6547e4edadb0746742a854f3c216b
4
- data.tar.gz: 8dfaf81082c63b6e117bfc6836210d3d6f8f9aa8
3
+ metadata.gz: 8488241a4b245171cf578a271e64cde4bcb5e992
4
+ data.tar.gz: 157848c9c7f726ebc67fbb9f63fb823274ed2312
5
5
  SHA512:
6
- metadata.gz: 00c038fe5d84059b5452c8f445e0680c95f05a81be846c73a481efe0fd1a2d50433f3511b04453187983e6fd491940c7033229757d10d5da52c91fd508c332e8
7
- data.tar.gz: 8a49ba878195450a06fe361c3d0ac57697c89f508b2c8f4ba5bb0e5a0acbcd8ff2f287cf59f38d63df4633af17c055b98ea1d6d02623318a81098b55a8b4b7b1
6
+ metadata.gz: dfc38bc4139cdae9178f69db59bffc2fa46867bb40864e8c1df13f80ca9a95707795ed2a48c9a4b3cc2c248726571cfbff062d515c2bf113095d5deafc89003f
7
+ data.tar.gz: 9d40524878b0ca0ba9d1606c9ad4f4336dc51ac042946fc53b04285dfbc8625248629522d1497cd36a1e9d95d4c4e00b8646ce0d84d8e936264bf7ca53a5eecd
data/bin/nyara CHANGED
@@ -6,12 +6,12 @@ task_name = args.shift || 'help'
6
6
 
7
7
 
8
8
  case task_name
9
- when 'help'
10
- Nyara::Command.help
11
- when '-h'
9
+ when 'help', '-h'
12
10
  Nyara::Command.help
13
11
  when '-v'
14
12
  Nyara::Command.version
15
13
  when 'new'
16
14
  Nyara::Command.new_project(*args)
15
+ when 's','server'
16
+ Nyara::Command.run_server(*args)
17
17
  end
data/changes CHANGED
@@ -1,3 +1,4 @@
1
+ 2013-07-18 add automatic reloader for development mode
1
2
  2013-07-13 add bin script `nyara`
2
3
  2013-07-10 add before filter
3
4
  2013-07-06 add worker signal management
data/ext/event.c CHANGED
@@ -46,9 +46,14 @@ static Request* curr_request;
46
46
  static bool graceful_quit = false;
47
47
 
48
48
  static VALUE _fiber_func(VALUE _, VALUE args) {
49
- VALUE instance = rb_ary_pop(args);
50
- VALUE meth = rb_ary_pop(args);
51
- rb_apply(instance, SYM2ID(meth), args);
49
+ static VALUE controller_class = Qnil;
50
+ static ID id_dispatch;
51
+ if (controller_class == Qnil) {
52
+ controller_class = rb_const_get(rb_cModule, rb_intern("Nyara"));
53
+ controller_class = rb_const_get(controller_class, rb_intern("Controller"));
54
+ id_dispatch = rb_intern("dispatch");
55
+ }
56
+ rb_apply(controller_class, id_dispatch, args);
52
57
  return Qnil;
53
58
  }
54
59
 
@@ -102,27 +107,16 @@ static void _handle_request(VALUE request) {
102
107
  // ensure action
103
108
  if (p->fiber == Qnil) {
104
109
  volatile RouteResult result = nyara_lookup_route(p->method, p->path, p->accept);
105
- nyara_summary_request(p->method, p->path, result.controller);
106
110
  if (RTEST(result.controller)) {
107
- rb_ary_push(result.args, rb_class_new_instance(1, &(p->self), result.controller));
108
- // result.args is on stack, no need to worry gc
109
- p->fiber = rb_fiber_new(_fiber_func, result.args);
110
- p->instance = RARRAY_PTR(result.args)[RARRAY_LEN(result.args) - 1];
111
- p->scope = result.scope;
112
- p->format = result.format;
113
- p->response_header = rb_class_new_instance(0, NULL, nyara_header_hash_class);
114
- p->response_header_extra_lines = rb_ary_new();
115
- nyara_request_init_env(request);
116
- } else {
117
- static const char* not_found = "HTTP/1.1 404 Not Found\r\nConnection: close\r\nContent-Length: 0\r\n\r\n";
118
- static long not_found_len = 0;
119
- if (!not_found_len) {
120
- not_found_len = strlen(not_found);
121
- }
122
- nyara_send_data(p->fd, not_found, not_found_len);
123
- nyara_detach_rid(p->rid);
124
- return;
111
+ p->instance = rb_class_new_instance(1, &(p->self), result.controller);
125
112
  }
113
+ // result.args is on stack, no need to worry gc
114
+ p->scope = result.scope;
115
+ p->format = result.format;
116
+ p->cookie = rb_class_new_instance(0, NULL, nyara_param_hash_class);
117
+ p->response_header = rb_class_new_instance(0, NULL, nyara_header_hash_class);
118
+ p->response_header_extra_lines = rb_ary_new();
119
+ p->fiber = rb_fiber_new(_fiber_func, rb_ary_new3(3, p->self, p->instance, result.args));
126
120
  }
127
121
 
128
122
  _resume_action(p);
data/ext/hashes.c CHANGED
@@ -3,18 +3,19 @@
3
3
  #include "nyara.h"
4
4
  #include <ruby/st.h>
5
5
  #include "inc/str_intern.h"
6
+ #include <ctype.h>
6
7
 
7
8
  VALUE nyara_param_hash_class;
8
9
  VALUE nyara_header_hash_class;
9
10
  VALUE nyara_config_hash_class;
10
11
 
11
12
  // stolen from hash.c
12
- int nyara_rb_hash_has_key(VALUE hash, VALUE key) {
13
+ static bool nyara_rb_hash_has_key(VALUE hash, VALUE key) {
13
14
  if (!RHASH(hash)->ntbl)
14
- return 0;
15
+ return false;
15
16
  if (st_lookup(RHASH(hash)->ntbl, key, 0))
16
- return 1;
17
- return 0;
17
+ return true;
18
+ return false;
18
19
  }
19
20
 
20
21
  // NOTE no need to add lots of methods like HashWithIndifferentAccess
@@ -41,6 +42,219 @@ static VALUE param_hash_aset(VALUE self, VALUE key, VALUE value) {
41
42
  return rb_hash_aset(self, key, value);
42
43
  }
43
44
 
45
+ // prereq: name should be already url decoded <br>
46
+ // "a[b][][c]" ==> ["a", "b", "", "c"]
47
+ static VALUE param_hash_split_name(VALUE _, VALUE name) {
48
+ Check_Type(name, T_STRING);
49
+ long len = RSTRING_LEN(name);
50
+ if (len == 0) {
51
+ rb_raise(rb_eArgError, "name should not be empty");
52
+ }
53
+ char* s = RSTRING_PTR(name);
54
+
55
+ // NOTE it's OK to compare utf-8 string with ascii chars, because utf-8 code units are either:
56
+ // - byte with 0 in highest nibble, which is ascii char
57
+ // - bytes with 1 in highest nibble, which can not be eql to any ascii char
58
+
59
+ volatile VALUE keys = rb_ary_new();
60
+ long i;
61
+ for (i = 0; i < len; i++) {
62
+ if (s[i] == '[') {
63
+ if (i == 0) {
64
+ rb_raise(rb_eArgError, "bad name (starts with '[')");
65
+ }
66
+ volatile VALUE key = rb_enc_str_new(s, i, u8_encoding);
67
+ rb_ary_push(keys, key);
68
+ i++;
69
+ break;
70
+ } else if (s[i] == ']') {
71
+ rb_raise(rb_eArgError, "bad name (unmatched ']')");
72
+ }
73
+ }
74
+
75
+ if (RARRAY_LEN(keys)) {
76
+ if (s[len - 1] != ']') {
77
+ rb_raise(rb_eArgError, "bad name (not end with ']')");
78
+ }
79
+ long last_j = i;
80
+ for (long j = last_j; j < len; j++) {
81
+ if (s[j] == ']') {
82
+ if (j == len - 1 || s[j + 1] == '[') {
83
+ volatile VALUE key = rb_enc_str_new(s + last_j, j - last_j, u8_encoding);
84
+ rb_ary_push(keys, key);
85
+ last_j = j + 2; // fine for last round
86
+ j++;
87
+ } else {
88
+ rb_raise(rb_eArgError, "bad name (']' not followed by '[')");
89
+ }
90
+ } else if (s[j] == '[') {
91
+ rb_raise(rb_eArgError, "bad name (nested '[')");
92
+ }
93
+ }
94
+ } else {
95
+ // single key
96
+ rb_ary_push(keys, name);
97
+ }
98
+ return keys;
99
+ }
100
+
101
+ // assume keys = [a, b, c] ==> self[a][b][c] = value
102
+ // blank keys will be translated as array keys.
103
+ // created hashes has the same class with output
104
+ // todo make 2 versions, one for public use
105
+ static VALUE param_hash_nested_aset(VALUE output, volatile VALUE keys, VALUE value) {
106
+ Check_Type(keys, T_ARRAY);
107
+ VALUE* arr = RARRAY_PTR(keys);
108
+ long len = RARRAY_LEN(keys);
109
+ if (!len) {
110
+ rb_raise(rb_eArgError, "aset 0 length key");
111
+ return Qnil;
112
+ }
113
+ volatile VALUE klass = rb_obj_class(output);
114
+
115
+ // first key seg
116
+ long is_hash_key = 1;
117
+
118
+ // middle key segs
119
+ for (long i = 0; i < len - 1; i++) {
120
+ long next_is_hash_key = RSTRING_LEN(arr[i + 1]);
121
+ # define NEW_CHILD(child) \
122
+ volatile VALUE child = (next_is_hash_key ? rb_class_new_instance(0, NULL, klass) : rb_ary_new());
123
+
124
+ if (is_hash_key) {
125
+ if (nyara_rb_hash_has_key(output, arr[i])) {
126
+ output = rb_hash_aref(output, arr[i]);
127
+ if (next_is_hash_key) {
128
+ if (TYPE(output) != T_HASH) {
129
+ rb_raise(rb_eRuntimeError, "hash key at:%ld conflicts with array", i + 1);
130
+ }
131
+ } else {
132
+ if (TYPE(output) != T_ARRAY) {
133
+ rb_raise(rb_eRuntimeError, "array key at:%ld conflicts with hash", i + 1);
134
+ }
135
+ }
136
+ } else {
137
+ NEW_CHILD(child);
138
+ rb_hash_aset(output, arr[i], child);
139
+ output = child;
140
+ }
141
+ } else {
142
+ NEW_CHILD(child);
143
+ rb_ary_push(output, child);
144
+ output = child;
145
+ }
146
+ is_hash_key = next_is_hash_key;
147
+ # undef NEW_CHILD
148
+ }
149
+
150
+ // terminate key seg: add value
151
+ if (is_hash_key) {
152
+ rb_hash_aset(output, arr[len - 1], value);
153
+ } else {
154
+ rb_ary_push(output, value);
155
+ }
156
+ return output;
157
+ }
158
+
159
+ // s, len is the raw kv string
160
+ // returns trailing length
161
+ static void _kv(VALUE output, const char* s, long len, bool nested_mode) {
162
+ // strip
163
+ for (; len > 0; len--, s++) {
164
+ if (!isspace(*s)) {
165
+ break;
166
+ }
167
+ }
168
+ for (; len > 0; len--) {
169
+ if (!isspace(s[len - 1])) {
170
+ break;
171
+ }
172
+ }
173
+ if (len > 0) {
174
+ volatile VALUE key = rb_enc_str_new("", 0, u8_encoding);
175
+ volatile VALUE value = rb_enc_str_new("", 0, u8_encoding);
176
+ nyara_decode_uri_kv(key, value, s, len);
177
+ if (nested_mode) {
178
+ volatile VALUE keys = param_hash_split_name(Qnil, key);
179
+ param_hash_nested_aset(output, keys, value);
180
+ } else {
181
+ rb_hash_aset(output, key, value);
182
+ }
183
+ }
184
+ }
185
+
186
+ // class method:
187
+ // insert parsing result into output
188
+ static VALUE param_hash_parse_cookie(VALUE _, VALUE output, VALUE str) {
189
+ Check_Type(output, T_HASH);
190
+ Check_Type(str, T_STRING);
191
+ if (rb_obj_is_kind_of(output, nyara_header_hash_class)) {
192
+ rb_raise(rb_eArgError, "can not parse cookie into HeaderHash");
193
+ }
194
+ const char* s = RSTRING_PTR(str);
195
+ long len = RSTRING_LEN(str);
196
+
197
+ // split with /[,;]/
198
+ // scan in reverse order because entries on the left of the cookie has greater priority
199
+ long i = len - 1;
200
+ long last_i = i;
201
+ for (; i >= 0; i--) {
202
+ if (s[i] == ',' || s[i] == ';') {
203
+ if (i < last_i) {
204
+ _kv(output, s + i + 1, last_i - i, false);
205
+ }
206
+ last_i = i - 1;
207
+ }
208
+ }
209
+ if (last_i > 0) {
210
+ _kv(output, s, last_i + 1, false);
211
+ }
212
+ return output;
213
+ }
214
+
215
+ // class method:
216
+ // insert parsing result into output
217
+ static VALUE param_hash_parse_param(VALUE _, VALUE output, VALUE str) {
218
+ Check_Type(output, T_HASH);
219
+ Check_Type(str, T_STRING);
220
+ if (rb_obj_is_kind_of(output, nyara_header_hash_class)) {
221
+ rb_raise(rb_eArgError, "can not parse param into HeaderHash");
222
+ }
223
+ const char* s = RSTRING_PTR(str);
224
+ long len = RSTRING_LEN(str);
225
+
226
+ // split with /[&;]/
227
+ long i = 0;
228
+ long last_i = i;
229
+ for (; i < len; i++) {
230
+ if (s[i] == '&' || s[i] == ';') {
231
+ if (i > last_i) {
232
+ _kv(output, s + last_i, i - last_i, true);
233
+ }
234
+ last_i = i + 1;
235
+ }
236
+ }
237
+ if (i > last_i) {
238
+ _kv(output, s + last_i, i - last_i, true);
239
+ }
240
+ return output;
241
+ }
242
+
243
+ static VALUE _tmp_str;
244
+
245
+ static VALUE _parse_query_func(VALUE output) {
246
+ param_hash_parse_param(Qnil, output, _tmp_str);
247
+ return Qnil;
248
+ }
249
+
250
+ // do not raise error
251
+ void nyara_parse_query(VALUE output, const char* s, long len) {
252
+ volatile VALUE str = rb_str_new(s, len);
253
+ _tmp_str = str;
254
+ int err = 0;
255
+ rb_protect(_parse_query_func, output, &err);
256
+ }
257
+
44
258
  void nyara_headerlize(VALUE str) {
45
259
  char* s = (char*)RSTRING_PTR(str);
46
260
  long len = RSTRING_LEN(str);
@@ -149,6 +363,10 @@ void Init_hashes(VALUE nyara) {
149
363
  rb_define_method(nyara_param_hash_class, "[]", param_hash_aref, 1);
150
364
  rb_define_method(nyara_param_hash_class, "key?", param_hash_key_p, 1);
151
365
  rb_define_method(nyara_param_hash_class, "[]=", param_hash_aset, 2);
366
+ rb_define_method(nyara_param_hash_class, "nested_aset", param_hash_nested_aset, 2);
367
+ rb_define_singleton_method(nyara_param_hash_class, "split_name", param_hash_split_name, 1);
368
+ rb_define_singleton_method(nyara_param_hash_class, "parse_param", param_hash_parse_param, 2);
369
+ rb_define_singleton_method(nyara_param_hash_class, "parse_cookie", param_hash_parse_cookie, 2);
152
370
 
153
371
  rb_define_method(nyara_header_hash_class, "[]", header_hash_aref, 1);
154
372
  rb_define_method(nyara_header_hash_class, "key?", header_hash_key_p, 1);
data/ext/inc/rdtsc.h ADDED
@@ -0,0 +1,56 @@
1
+ #ifndef __RDTSC_H_DEFINED__
2
+ #define __RDTSC_H_DEFINED__
3
+
4
+
5
+ #if defined(__i386__)
6
+
7
+ static __inline__ unsigned long long rdtsc(void)
8
+ {
9
+ unsigned long long int x;
10
+ __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
11
+ return x;
12
+ }
13
+ #elif defined(__x86_64__)
14
+
15
+ static __inline__ unsigned long long rdtsc(void)
16
+ {
17
+ unsigned hi, lo;
18
+ __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
19
+ return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
20
+ }
21
+
22
+ #elif defined(__powerpc__)
23
+
24
+ static __inline__ unsigned long long rdtsc(void)
25
+ {
26
+ unsigned long long int result=0;
27
+ unsigned long int upper, lower,tmp;
28
+ __asm__ volatile(
29
+ "0: \n"
30
+ "\tmftbu %0 \n"
31
+ "\tmftb %1 \n"
32
+ "\tmftbu %2 \n"
33
+ "\tcmpw %2,%0 \n"
34
+ "\tbne 0b \n"
35
+ : "=r"(upper),"=r"(lower),"=r"(tmp)
36
+ );
37
+ result = upper;
38
+ result = result<<32;
39
+ result = result|lower;
40
+
41
+ return(result);
42
+ }
43
+
44
+ #else
45
+
46
+ #error "No tick counter is available!"
47
+
48
+ #endif
49
+
50
+
51
+ /* $RCSfile: $ $Author: kazutomo $
52
+ * $Revision: 1.6 $ $Date: 2005/04/13 18:49:58 $
53
+ */
54
+
55
+ #endif
56
+
@@ -0,0 +1,64 @@
1
+ #define HTTP_STATUS_CODES(XX)\
2
+ XX(100, "Continue");\
3
+ XX(101, "Switching Protocols");\
4
+ XX(102, "Processing");\
5
+ XX(200, "OK");\
6
+ XX(201, "Created");\
7
+ XX(202, "Accepted");\
8
+ XX(203, "Non-Authoritative Information");\
9
+ XX(204, "No Content");\
10
+ XX(205, "Reset Content");\
11
+ XX(206, "Partial Content");\
12
+ XX(207, "Multi-Status");\
13
+ XX(208, "Already Reported");\
14
+ XX(226, "IM Used");\
15
+ XX(300, "Multiple Choices");\
16
+ XX(301, "Moved Permanently");\
17
+ XX(302, "Found");\
18
+ XX(303, "See Other");\
19
+ XX(304, "Not Modified");\
20
+ XX(305, "Use Proxy");\
21
+ XX(306, "Reserved");\
22
+ XX(307, "Temporary Redirect");\
23
+ XX(308, "Permanent Redirect");\
24
+ XX(400, "Bad Request");\
25
+ XX(401, "Unauthorized");\
26
+ XX(402, "Payment Required");\
27
+ XX(403, "Forbidden");\
28
+ XX(404, "Not Found");\
29
+ XX(405, "Method Not Allowed");\
30
+ XX(406, "Not Acceptable");\
31
+ XX(407, "Proxy Authentication Required");\
32
+ XX(408, "Request Timeout");\
33
+ XX(409, "Conflict");\
34
+ XX(410, "Gone");\
35
+ XX(411, "Length Required");\
36
+ XX(412, "Precondition Failed");\
37
+ XX(413, "Request Entity Too Large");\
38
+ XX(414, "Request-URI Too Long");\
39
+ XX(415, "Unsupported Media Type");\
40
+ XX(416, "Requested Range Not Satisfiable");\
41
+ XX(417, "Expectation Failed");\
42
+ XX(422, "Unprocessable Entity");\
43
+ XX(423, "Locked");\
44
+ XX(424, "Failed Dependency");\
45
+ XX(425, "Unassigned");\
46
+ XX(426, "Upgrade Required");\
47
+ XX(427, "Unassigned");\
48
+ XX(428, "Precondition Required");\
49
+ XX(429, "Too Many Requests");\
50
+ XX(430, "Unassigned");\
51
+ XX(431, "Request Header Fields Too Large");\
52
+ XX(500, "Internal Server Error");\
53
+ XX(501, "Not Implemented");\
54
+ XX(502, "Bad Gateway");\
55
+ XX(503, "Service Unavailable");\
56
+ XX(504, "Gateway Timeout");\
57
+ XX(505, "HTTP Version Not Supported");\
58
+ XX(506, "Variant Also Negotiates (Experimental)");\
59
+ XX(507, "Insufficient Storage");\
60
+ XX(508, "Loop Detected");\
61
+ XX(509, "Unassigned");\
62
+ XX(510, "Not Extended");\
63
+ XX(511, "Network Authentication Required");\
64
+ // end define