nyara 0.0.1.pre.9 → 0.1.pre.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 (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