rsense-server 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/Gemfile +14 -0
  4. data/Guardfile +5 -0
  5. data/LICENSE.txt +1 -0
  6. data/README.md +51 -0
  7. data/Rakefile +9 -0
  8. data/bin/_rsense.rb +115 -0
  9. data/config/puma.rb +2 -0
  10. data/lib/rsense/server/code.rb +38 -0
  11. data/lib/rsense/server/command/completion_result.rb +11 -0
  12. data/lib/rsense/server/command/special_meth.rb +18 -0
  13. data/lib/rsense/server/command/type_inference_method.rb +24 -0
  14. data/lib/rsense/server/command.rb +239 -0
  15. data/lib/rsense/server/config.rb +70 -0
  16. data/lib/rsense/server/gem_path.rb +18 -0
  17. data/lib/rsense/server/listeners/find_definition_event_listener.rb +91 -0
  18. data/lib/rsense/server/listeners/where_event_listener.rb +39 -0
  19. data/lib/rsense/server/load_path.rb +62 -0
  20. data/lib/rsense/server/options.rb +85 -0
  21. data/lib/rsense/server/parser.rb +17 -0
  22. data/lib/rsense/server/path_info.rb +17 -0
  23. data/lib/rsense/server/project.rb +24 -0
  24. data/lib/rsense/server/version.rb +5 -0
  25. data/lib/rsense/server.rb +18 -0
  26. data/rsense-server.gemspec +35 -0
  27. data/spec/fixtures/config_fixture/.rsense +4 -0
  28. data/spec/fixtures/deeply/nested/thing.rb +0 -0
  29. data/spec/fixtures/find_def_sample.json +10 -0
  30. data/spec/fixtures/sample.json +10 -0
  31. data/spec/fixtures/test_gem/.gitignore +22 -0
  32. data/spec/fixtures/test_gem/Gemfile +4 -0
  33. data/spec/fixtures/test_gem/LICENSE.txt +22 -0
  34. data/spec/fixtures/test_gem/README.md +29 -0
  35. data/spec/fixtures/test_gem/Rakefile +2 -0
  36. data/spec/fixtures/test_gem/lib/sample/version.rb +3 -0
  37. data/spec/fixtures/test_gem/lib/sample.rb +16 -0
  38. data/spec/fixtures/test_gem/sample.gemspec +23 -0
  39. data/spec/fixtures/test_gem/test.json +10 -0
  40. data/spec/rsense/server/code_spec.rb +44 -0
  41. data/spec/rsense/server/command/special_meth_spec.rb +23 -0
  42. data/spec/rsense/server/command_spec.rb +108 -0
  43. data/spec/rsense/server/config_spec.rb +27 -0
  44. data/spec/rsense/server/gem_path_spec.rb +16 -0
  45. data/spec/rsense/server/load_path_spec.rb +63 -0
  46. data/spec/rsense/server/options_spec.rb +33 -0
  47. data/spec/rsense/server/path_info_spec.rb +11 -0
  48. data/spec/rsense/server/project_spec.rb +18 -0
  49. data/spec/rsense/server_spec.rb +7 -0
  50. data/spec/spec_helper.rb +16 -0
  51. data/vendor/gems/puma-2.8.2-java/COPYING +55 -0
  52. data/vendor/gems/puma-2.8.2-java/DEPLOYMENT.md +92 -0
  53. data/vendor/gems/puma-2.8.2-java/Gemfile +17 -0
  54. data/vendor/gems/puma-2.8.2-java/History.txt +532 -0
  55. data/vendor/gems/puma-2.8.2-java/LICENSE +26 -0
  56. data/vendor/gems/puma-2.8.2-java/Manifest.txt +68 -0
  57. data/vendor/gems/puma-2.8.2-java/README.md +251 -0
  58. data/vendor/gems/puma-2.8.2-java/Rakefile +158 -0
  59. data/vendor/gems/puma-2.8.2-java/bin/puma +10 -0
  60. data/vendor/gems/puma-2.8.2-java/bin/puma-wild +17 -0
  61. data/vendor/gems/puma-2.8.2-java/bin/pumactl +12 -0
  62. data/vendor/gems/puma-2.8.2-java/docs/config.md +0 -0
  63. data/vendor/gems/puma-2.8.2-java/docs/nginx.md +80 -0
  64. data/vendor/gems/puma-2.8.2-java/docs/signals.md +42 -0
  65. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/PumaHttp11Service.java +17 -0
  66. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/ext_help.h +15 -0
  67. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/extconf.rb +8 -0
  68. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.c +1225 -0
  69. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.h +64 -0
  70. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.java.rl +161 -0
  71. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.rl +146 -0
  72. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser_common.rl +54 -0
  73. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/io_buffer.c +155 -0
  74. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/mini_ssl.c +195 -0
  75. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/org/jruby/puma/Http11.java +225 -0
  76. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/org/jruby/puma/Http11Parser.java +488 -0
  77. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/org/jruby/puma/MiniSSL.java +289 -0
  78. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/puma_http11.c +491 -0
  79. data/vendor/gems/puma-2.8.2-java/lib/puma/accept_nonblock.rb +23 -0
  80. data/vendor/gems/puma-2.8.2-java/lib/puma/app/status.rb +59 -0
  81. data/vendor/gems/puma-2.8.2-java/lib/puma/binder.rb +298 -0
  82. data/vendor/gems/puma-2.8.2-java/lib/puma/capistrano.rb +86 -0
  83. data/vendor/gems/puma-2.8.2-java/lib/puma/cli.rb +587 -0
  84. data/vendor/gems/puma-2.8.2-java/lib/puma/client.rb +289 -0
  85. data/vendor/gems/puma-2.8.2-java/lib/puma/cluster.rb +389 -0
  86. data/vendor/gems/puma-2.8.2-java/lib/puma/compat.rb +18 -0
  87. data/vendor/gems/puma-2.8.2-java/lib/puma/configuration.rb +377 -0
  88. data/vendor/gems/puma-2.8.2-java/lib/puma/const.rb +165 -0
  89. data/vendor/gems/puma-2.8.2-java/lib/puma/control_cli.rb +251 -0
  90. data/vendor/gems/puma-2.8.2-java/lib/puma/daemon_ext.rb +25 -0
  91. data/vendor/gems/puma-2.8.2-java/lib/puma/delegation.rb +11 -0
  92. data/vendor/gems/puma-2.8.2-java/lib/puma/detect.rb +4 -0
  93. data/vendor/gems/puma-2.8.2-java/lib/puma/events.rb +130 -0
  94. data/vendor/gems/puma-2.8.2-java/lib/puma/io_buffer.rb +7 -0
  95. data/vendor/gems/puma-2.8.2-java/lib/puma/java_io_buffer.rb +45 -0
  96. data/vendor/gems/puma-2.8.2-java/lib/puma/jruby_restart.rb +83 -0
  97. data/vendor/gems/puma-2.8.2-java/lib/puma/minissl.rb +148 -0
  98. data/vendor/gems/puma-2.8.2-java/lib/puma/null_io.rb +34 -0
  99. data/vendor/gems/puma-2.8.2-java/lib/puma/puma_http11.jar +0 -0
  100. data/vendor/gems/puma-2.8.2-java/lib/puma/rack_default.rb +7 -0
  101. data/vendor/gems/puma-2.8.2-java/lib/puma/rack_patch.rb +45 -0
  102. data/vendor/gems/puma-2.8.2-java/lib/puma/reactor.rb +183 -0
  103. data/vendor/gems/puma-2.8.2-java/lib/puma/runner.rb +146 -0
  104. data/vendor/gems/puma-2.8.2-java/lib/puma/server.rb +801 -0
  105. data/vendor/gems/puma-2.8.2-java/lib/puma/single.rb +102 -0
  106. data/vendor/gems/puma-2.8.2-java/lib/puma/tcp_logger.rb +32 -0
  107. data/vendor/gems/puma-2.8.2-java/lib/puma/thread_pool.rb +185 -0
  108. data/vendor/gems/puma-2.8.2-java/lib/puma/util.rb +9 -0
  109. data/vendor/gems/puma-2.8.2-java/lib/puma.rb +14 -0
  110. data/vendor/gems/puma-2.8.2-java/lib/rack/handler/puma.rb +66 -0
  111. data/vendor/gems/puma-2.8.2-java/puma.gemspec +55 -0
  112. data/vendor/gems/puma-2.8.2-java/test/test_app_status.rb +92 -0
  113. data/vendor/gems/puma-2.8.2-java/test/test_cli.rb +173 -0
  114. data/vendor/gems/puma-2.8.2-java/test/test_config.rb +26 -0
  115. data/vendor/gems/puma-2.8.2-java/test/test_http10.rb +27 -0
  116. data/vendor/gems/puma-2.8.2-java/test/test_http11.rb +144 -0
  117. data/vendor/gems/puma-2.8.2-java/test/test_integration.rb +165 -0
  118. data/vendor/gems/puma-2.8.2-java/test/test_iobuffer.rb +38 -0
  119. data/vendor/gems/puma-2.8.2-java/test/test_minissl.rb +25 -0
  120. data/vendor/gems/puma-2.8.2-java/test/test_null_io.rb +31 -0
  121. data/vendor/gems/puma-2.8.2-java/test/test_persistent.rb +238 -0
  122. data/vendor/gems/puma-2.8.2-java/test/test_puma_server.rb +323 -0
  123. data/vendor/gems/puma-2.8.2-java/test/test_rack_handler.rb +10 -0
  124. data/vendor/gems/puma-2.8.2-java/test/test_rack_server.rb +141 -0
  125. data/vendor/gems/puma-2.8.2-java/test/test_tcp_rack.rb +42 -0
  126. data/vendor/gems/puma-2.8.2-java/test/test_thread_pool.rb +156 -0
  127. data/vendor/gems/puma-2.8.2-java/test/test_unix_socket.rb +39 -0
  128. data/vendor/gems/puma-2.8.2-java/test/test_ws.rb +89 -0
  129. data/vendor/gems/puma-2.8.2-java/tools/jungle/README.md +9 -0
  130. data/vendor/gems/puma-2.8.2-java/tools/jungle/init.d/README.md +54 -0
  131. data/vendor/gems/puma-2.8.2-java/tools/jungle/init.d/puma +332 -0
  132. data/vendor/gems/puma-2.8.2-java/tools/jungle/init.d/run-puma +3 -0
  133. data/vendor/gems/puma-2.8.2-java/tools/jungle/upstart/README.md +61 -0
  134. data/vendor/gems/puma-2.8.2-java/tools/jungle/upstart/puma-manager.conf +31 -0
  135. data/vendor/gems/puma-2.8.2-java/tools/jungle/upstart/puma.conf +63 -0
  136. data/vendor/gems/puma-2.8.2-java/tools/trickletest.rb +45 -0
  137. metadata +389 -0
@@ -0,0 +1,491 @@
1
+ /**
2
+ * Copyright (c) 2005 Zed A. Shaw
3
+ * You can redistribute it and/or modify it under the same terms as Ruby.
4
+ */
5
+
6
+ #define RSTRING_NOT_MODIFIED 1
7
+
8
+ #include "ruby.h"
9
+ #include "ext_help.h"
10
+ #include <assert.h>
11
+ #include <string.h>
12
+ #include "http11_parser.h"
13
+
14
+ #ifndef MANAGED_STRINGS
15
+
16
+ #ifndef RSTRING_PTR
17
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
18
+ #endif
19
+ #ifndef RSTRING_LEN
20
+ #define RSTRING_LEN(s) (RSTRING(s)->len)
21
+ #endif
22
+
23
+ #define rb_extract_chars(e, sz) (*sz = RSTRING_LEN(e), RSTRING_PTR(e))
24
+ #define rb_free_chars(e) /* nothing */
25
+
26
+ #endif
27
+
28
+ static VALUE eHttpParserError;
29
+
30
+ #define HTTP_PREFIX "HTTP_"
31
+ #define HTTP_PREFIX_LEN (sizeof(HTTP_PREFIX) - 1)
32
+
33
+ static VALUE global_request_method;
34
+ static VALUE global_request_uri;
35
+ static VALUE global_fragment;
36
+ static VALUE global_query_string;
37
+ static VALUE global_http_version;
38
+ static VALUE global_request_path;
39
+
40
+ /** Defines common length and error messages for input length validation. */
41
+ #define DEF_MAX_LENGTH(N,length) const size_t MAX_##N##_LENGTH = length; const char *MAX_##N##_LENGTH_ERR = "HTTP element " # N " is longer than the " # length " allowed length (was %d)"
42
+
43
+ /** Validates the max length of given input and throws an HttpParserError exception if over. */
44
+ #define VALIDATE_MAX_LENGTH(len, N) if(len > MAX_##N##_LENGTH) { rb_raise(eHttpParserError, MAX_##N##_LENGTH_ERR, len); }
45
+
46
+ /** Defines global strings in the init method. */
47
+ #define DEF_GLOBAL(N, val) global_##N = rb_str_new2(val); rb_global_variable(&global_##N)
48
+
49
+
50
+ /* Defines the maximum allowed lengths for various input elements.*/
51
+ DEF_MAX_LENGTH(FIELD_NAME, 256);
52
+ DEF_MAX_LENGTH(FIELD_VALUE, 80 * 1024);
53
+ DEF_MAX_LENGTH(REQUEST_URI, 1024 * 12);
54
+ DEF_MAX_LENGTH(FRAGMENT, 1024); /* Don't know if this length is specified somewhere or not */
55
+ DEF_MAX_LENGTH(REQUEST_PATH, 2048);
56
+ DEF_MAX_LENGTH(QUERY_STRING, (1024 * 10));
57
+ DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32)));
58
+
59
+ struct common_field {
60
+ const size_t len;
61
+ const char *name;
62
+ int raw;
63
+ VALUE value;
64
+ };
65
+
66
+ /*
67
+ * A list of common HTTP headers we expect to receive.
68
+ * This allows us to avoid repeatedly creating identical string
69
+ * objects to be used with rb_hash_aset().
70
+ */
71
+ static struct common_field common_http_fields[] = {
72
+ # define f(N) { (sizeof(N) - 1), N, 0, Qnil }
73
+ # define fr(N) { (sizeof(N) - 1), N, 1, Qnil }
74
+ f("ACCEPT"),
75
+ f("ACCEPT_CHARSET"),
76
+ f("ACCEPT_ENCODING"),
77
+ f("ACCEPT_LANGUAGE"),
78
+ f("ALLOW"),
79
+ f("AUTHORIZATION"),
80
+ f("CACHE_CONTROL"),
81
+ f("CONNECTION"),
82
+ f("CONTENT_ENCODING"),
83
+ fr("CONTENT_LENGTH"),
84
+ fr("CONTENT_TYPE"),
85
+ f("COOKIE"),
86
+ f("DATE"),
87
+ f("EXPECT"),
88
+ f("FROM"),
89
+ f("HOST"),
90
+ f("IF_MATCH"),
91
+ f("IF_MODIFIED_SINCE"),
92
+ f("IF_NONE_MATCH"),
93
+ f("IF_RANGE"),
94
+ f("IF_UNMODIFIED_SINCE"),
95
+ f("KEEP_ALIVE"), /* Firefox sends this */
96
+ f("MAX_FORWARDS"),
97
+ f("PRAGMA"),
98
+ f("PROXY_AUTHORIZATION"),
99
+ f("RANGE"),
100
+ f("REFERER"),
101
+ f("TE"),
102
+ f("TRAILER"),
103
+ f("TRANSFER_ENCODING"),
104
+ f("UPGRADE"),
105
+ f("USER_AGENT"),
106
+ f("VIA"),
107
+ f("X_FORWARDED_FOR"), /* common for proxies */
108
+ f("X_REAL_IP"), /* common for proxies */
109
+ f("WARNING")
110
+ # undef f
111
+ };
112
+
113
+ /*
114
+ * qsort(3) and bsearch(3) improve average performance slightly, but may
115
+ * not be worth it for lack of portability to certain platforms...
116
+ */
117
+ #if defined(HAVE_QSORT_BSEARCH)
118
+ /* sort by length, then by name if there's a tie */
119
+ static int common_field_cmp(const void *a, const void *b)
120
+ {
121
+ struct common_field *cfa = (struct common_field *)a;
122
+ struct common_field *cfb = (struct common_field *)b;
123
+ signed long diff = cfa->len - cfb->len;
124
+ return diff ? diff : memcmp(cfa->name, cfb->name, cfa->len);
125
+ }
126
+ #endif /* HAVE_QSORT_BSEARCH */
127
+
128
+ static void init_common_fields(void)
129
+ {
130
+ unsigned i;
131
+ struct common_field *cf = common_http_fields;
132
+ char tmp[256]; /* MAX_FIELD_NAME_LENGTH */
133
+ memcpy(tmp, HTTP_PREFIX, HTTP_PREFIX_LEN);
134
+
135
+ for(i = 0; i < ARRAY_SIZE(common_http_fields); cf++, i++) {
136
+ if(cf->raw) {
137
+ cf->value = rb_str_new(cf->name, cf->len);
138
+ } else {
139
+ memcpy(tmp + HTTP_PREFIX_LEN, cf->name, cf->len + 1);
140
+ cf->value = rb_str_new(tmp, HTTP_PREFIX_LEN + cf->len);
141
+ }
142
+ rb_global_variable(&cf->value);
143
+ }
144
+
145
+ #if defined(HAVE_QSORT_BSEARCH)
146
+ qsort(common_http_fields,
147
+ ARRAY_SIZE(common_http_fields),
148
+ sizeof(struct common_field),
149
+ common_field_cmp);
150
+ #endif /* HAVE_QSORT_BSEARCH */
151
+ }
152
+
153
+ static VALUE find_common_field_value(const char *field, size_t flen)
154
+ {
155
+ #if defined(HAVE_QSORT_BSEARCH)
156
+ struct common_field key;
157
+ struct common_field *found;
158
+ key.name = field;
159
+ key.len = (signed long)flen;
160
+ found = (struct common_field *)bsearch(&key, common_http_fields,
161
+ ARRAY_SIZE(common_http_fields),
162
+ sizeof(struct common_field),
163
+ common_field_cmp);
164
+ return found ? found->value : Qnil;
165
+ #else /* !HAVE_QSORT_BSEARCH */
166
+ unsigned i;
167
+ struct common_field *cf = common_http_fields;
168
+ for(i = 0; i < ARRAY_SIZE(common_http_fields); i++, cf++) {
169
+ if (cf->len == flen && !memcmp(cf->name, field, flen))
170
+ return cf->value;
171
+ }
172
+ return Qnil;
173
+ #endif /* !HAVE_QSORT_BSEARCH */
174
+ }
175
+
176
+ void http_field(puma_parser* hp, const char *field, size_t flen,
177
+ const char *value, size_t vlen)
178
+ {
179
+ VALUE v = Qnil;
180
+ VALUE f = Qnil;
181
+
182
+ VALIDATE_MAX_LENGTH(flen, FIELD_NAME);
183
+ VALIDATE_MAX_LENGTH(vlen, FIELD_VALUE);
184
+
185
+ v = rb_str_new(value, vlen);
186
+
187
+ f = find_common_field_value(field, flen);
188
+
189
+ if (f == Qnil) {
190
+ /*
191
+ * We got a strange header that we don't have a memoized value for.
192
+ * Fallback to creating a new string to use as a hash key.
193
+ */
194
+
195
+ size_t new_size = HTTP_PREFIX_LEN + flen;
196
+ assert(new_size < BUFFER_LEN);
197
+
198
+ memcpy(hp->buf, HTTP_PREFIX, HTTP_PREFIX_LEN);
199
+ memcpy(hp->buf + HTTP_PREFIX_LEN, field, flen);
200
+
201
+ f = rb_str_new(hp->buf, new_size);
202
+ }
203
+
204
+ rb_hash_aset(hp->request, f, v);
205
+ }
206
+
207
+ void request_method(puma_parser* hp, const char *at, size_t length)
208
+ {
209
+ VALUE val = Qnil;
210
+
211
+ val = rb_str_new(at, length);
212
+ rb_hash_aset(hp->request, global_request_method, val);
213
+ }
214
+
215
+ void request_uri(puma_parser* hp, const char *at, size_t length)
216
+ {
217
+ VALUE val = Qnil;
218
+
219
+ VALIDATE_MAX_LENGTH(length, REQUEST_URI);
220
+
221
+ val = rb_str_new(at, length);
222
+ rb_hash_aset(hp->request, global_request_uri, val);
223
+ }
224
+
225
+ void fragment(puma_parser* hp, const char *at, size_t length)
226
+ {
227
+ VALUE val = Qnil;
228
+
229
+ VALIDATE_MAX_LENGTH(length, FRAGMENT);
230
+
231
+ val = rb_str_new(at, length);
232
+ rb_hash_aset(hp->request, global_fragment, val);
233
+ }
234
+
235
+ void request_path(puma_parser* hp, const char *at, size_t length)
236
+ {
237
+ VALUE val = Qnil;
238
+
239
+ VALIDATE_MAX_LENGTH(length, REQUEST_PATH);
240
+
241
+ val = rb_str_new(at, length);
242
+ rb_hash_aset(hp->request, global_request_path, val);
243
+ }
244
+
245
+ void query_string(puma_parser* hp, const char *at, size_t length)
246
+ {
247
+ VALUE val = Qnil;
248
+
249
+ VALIDATE_MAX_LENGTH(length, QUERY_STRING);
250
+
251
+ val = rb_str_new(at, length);
252
+ rb_hash_aset(hp->request, global_query_string, val);
253
+ }
254
+
255
+ void http_version(puma_parser* hp, const char *at, size_t length)
256
+ {
257
+ VALUE val = rb_str_new(at, length);
258
+ rb_hash_aset(hp->request, global_http_version, val);
259
+ }
260
+
261
+ /** Finalizes the request header to have a bunch of stuff that's
262
+ needed. */
263
+
264
+ void header_done(puma_parser* hp, const char *at, size_t length)
265
+ {
266
+ hp->body = rb_str_new(at, length);
267
+ }
268
+
269
+
270
+ void HttpParser_free(void *data) {
271
+ TRACE();
272
+
273
+ if(data) {
274
+ xfree(data);
275
+ }
276
+ }
277
+
278
+ void HttpParser_mark(puma_parser* hp) {
279
+ if(hp->request) rb_gc_mark(hp->request);
280
+ if(hp->body) rb_gc_mark(hp->body);
281
+ }
282
+
283
+ VALUE HttpParser_alloc(VALUE klass)
284
+ {
285
+ puma_parser *hp = ALLOC_N(puma_parser, 1);
286
+ TRACE();
287
+ hp->http_field = http_field;
288
+ hp->request_method = request_method;
289
+ hp->request_uri = request_uri;
290
+ hp->fragment = fragment;
291
+ hp->request_path = request_path;
292
+ hp->query_string = query_string;
293
+ hp->http_version = http_version;
294
+ hp->header_done = header_done;
295
+ hp->request = Qnil;
296
+
297
+ puma_parser_init(hp);
298
+
299
+ return Data_Wrap_Struct(klass, HttpParser_mark, HttpParser_free, hp);
300
+ }
301
+
302
+ /**
303
+ * call-seq:
304
+ * parser.new -> parser
305
+ *
306
+ * Creates a new parser.
307
+ */
308
+ VALUE HttpParser_init(VALUE self)
309
+ {
310
+ puma_parser *http = NULL;
311
+ DATA_GET(self, puma_parser, http);
312
+ puma_parser_init(http);
313
+
314
+ return self;
315
+ }
316
+
317
+
318
+ /**
319
+ * call-seq:
320
+ * parser.reset -> nil
321
+ *
322
+ * Resets the parser to it's initial state so that you can reuse it
323
+ * rather than making new ones.
324
+ */
325
+ VALUE HttpParser_reset(VALUE self)
326
+ {
327
+ puma_parser *http = NULL;
328
+ DATA_GET(self, puma_parser, http);
329
+ puma_parser_init(http);
330
+
331
+ return Qnil;
332
+ }
333
+
334
+
335
+ /**
336
+ * call-seq:
337
+ * parser.finish -> true/false
338
+ *
339
+ * Finishes a parser early which could put in a "good" or bad state.
340
+ * You should call reset after finish it or bad things will happen.
341
+ */
342
+ VALUE HttpParser_finish(VALUE self)
343
+ {
344
+ puma_parser *http = NULL;
345
+ DATA_GET(self, puma_parser, http);
346
+ puma_parser_finish(http);
347
+
348
+ return puma_parser_is_finished(http) ? Qtrue : Qfalse;
349
+ }
350
+
351
+
352
+ /**
353
+ * call-seq:
354
+ * parser.execute(req_hash, data, start) -> Integer
355
+ *
356
+ * Takes a Hash and a String of data, parses the String of data filling in the Hash
357
+ * returning an Integer to indicate how much of the data has been read. No matter
358
+ * what the return value, you should call HttpParser#finished? and HttpParser#error?
359
+ * to figure out if it's done parsing or there was an error.
360
+ *
361
+ * This function now throws an exception when there is a parsing error. This makes
362
+ * the logic for working with the parser much easier. You can still test for an
363
+ * error, but now you need to wrap the parser with an exception handling block.
364
+ *
365
+ * The third argument allows for parsing a partial request and then continuing
366
+ * the parsing from that position. It needs all of the original data as well
367
+ * so you have to append to the data buffer as you read.
368
+ */
369
+ VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
370
+ {
371
+ puma_parser *http = NULL;
372
+ int from = 0;
373
+ char *dptr = NULL;
374
+ long dlen = 0;
375
+
376
+ DATA_GET(self, puma_parser, http);
377
+
378
+ from = FIX2INT(start);
379
+ dptr = rb_extract_chars(data, &dlen);
380
+
381
+ if(from >= dlen) {
382
+ rb_free_chars(dptr);
383
+ rb_raise(eHttpParserError, "%s", "Requested start is after data buffer end.");
384
+ } else {
385
+ http->request = req_hash;
386
+ puma_parser_execute(http, dptr, dlen, from);
387
+
388
+ rb_free_chars(dptr);
389
+ VALIDATE_MAX_LENGTH(puma_parser_nread(http), HEADER);
390
+
391
+ if(puma_parser_has_error(http)) {
392
+ rb_raise(eHttpParserError, "%s", "Invalid HTTP format, parsing fails.");
393
+ } else {
394
+ return INT2FIX(puma_parser_nread(http));
395
+ }
396
+ }
397
+ }
398
+
399
+
400
+
401
+ /**
402
+ * call-seq:
403
+ * parser.error? -> true/false
404
+ *
405
+ * Tells you whether the parser is in an error state.
406
+ */
407
+ VALUE HttpParser_has_error(VALUE self)
408
+ {
409
+ puma_parser *http = NULL;
410
+ DATA_GET(self, puma_parser, http);
411
+
412
+ return puma_parser_has_error(http) ? Qtrue : Qfalse;
413
+ }
414
+
415
+
416
+ /**
417
+ * call-seq:
418
+ * parser.finished? -> true/false
419
+ *
420
+ * Tells you whether the parser is finished or not and in a good state.
421
+ */
422
+ VALUE HttpParser_is_finished(VALUE self)
423
+ {
424
+ puma_parser *http = NULL;
425
+ DATA_GET(self, puma_parser, http);
426
+
427
+ return puma_parser_is_finished(http) ? Qtrue : Qfalse;
428
+ }
429
+
430
+
431
+ /**
432
+ * call-seq:
433
+ * parser.nread -> Integer
434
+ *
435
+ * Returns the amount of data processed so far during this processing cycle. It is
436
+ * set to 0 on initialize or reset calls and is incremented each time execute is called.
437
+ */
438
+ VALUE HttpParser_nread(VALUE self)
439
+ {
440
+ puma_parser *http = NULL;
441
+ DATA_GET(self, puma_parser, http);
442
+
443
+ return INT2FIX(http->nread);
444
+ }
445
+
446
+ /**
447
+ * call-seq:
448
+ * parser.body -> nil or String
449
+ *
450
+ * If the request included a body, returns it.
451
+ */
452
+ VALUE HttpParser_body(VALUE self) {
453
+ puma_parser *http = NULL;
454
+ DATA_GET(self, puma_parser, http);
455
+
456
+ return http->body;
457
+ }
458
+
459
+ void Init_io_buffer(VALUE puma);
460
+ void Init_mini_ssl(VALUE mod);
461
+
462
+ void Init_puma_http11()
463
+ {
464
+
465
+ VALUE mPuma = rb_define_module("Puma");
466
+ VALUE cHttpParser = rb_define_class_under(mPuma, "HttpParser", rb_cObject);
467
+
468
+ DEF_GLOBAL(request_method, "REQUEST_METHOD");
469
+ DEF_GLOBAL(request_uri, "REQUEST_URI");
470
+ DEF_GLOBAL(fragment, "FRAGMENT");
471
+ DEF_GLOBAL(query_string, "QUERY_STRING");
472
+ DEF_GLOBAL(http_version, "HTTP_VERSION");
473
+ DEF_GLOBAL(request_path, "REQUEST_PATH");
474
+
475
+ eHttpParserError = rb_define_class_under(mPuma, "HttpParserError", rb_eIOError);
476
+ rb_global_variable(&eHttpParserError);
477
+
478
+ rb_define_alloc_func(cHttpParser, HttpParser_alloc);
479
+ rb_define_method(cHttpParser, "initialize", HttpParser_init, 0);
480
+ rb_define_method(cHttpParser, "reset", HttpParser_reset, 0);
481
+ rb_define_method(cHttpParser, "finish", HttpParser_finish, 0);
482
+ rb_define_method(cHttpParser, "execute", HttpParser_execute, 3);
483
+ rb_define_method(cHttpParser, "error?", HttpParser_has_error, 0);
484
+ rb_define_method(cHttpParser, "finished?", HttpParser_is_finished, 0);
485
+ rb_define_method(cHttpParser, "nread", HttpParser_nread, 0);
486
+ rb_define_method(cHttpParser, "body", HttpParser_body, 0);
487
+ init_common_fields();
488
+
489
+ Init_io_buffer(mPuma);
490
+ Init_mini_ssl(mPuma);
491
+ }
@@ -0,0 +1,23 @@
1
+ require 'openssl'
2
+
3
+ module OpenSSL
4
+ module SSL
5
+ class SSLServer
6
+ unless public_method_defined? :accept_nonblock
7
+ def accept_nonblock
8
+ sock = @svr.accept_nonblock
9
+
10
+ begin
11
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
12
+ ssl.sync_close = true
13
+ ssl.accept if @start_immediately
14
+ ssl
15
+ rescue SSLError => ex
16
+ sock.close
17
+ raise ex
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,59 @@
1
+ module Puma
2
+ module App
3
+ class Status
4
+ def initialize(cli)
5
+ @cli = cli
6
+ @auth_token = nil
7
+ end
8
+ OK_STATUS = '{ "status": "ok" }'.freeze
9
+
10
+ attr_accessor :auth_token
11
+
12
+ def authenticate(env)
13
+ return true unless @auth_token
14
+ env['QUERY_STRING'].to_s.split(/&;/).include?("token=#{@auth_token}")
15
+ end
16
+
17
+ def rack_response(status, body, content_type='application/json')
18
+ headers = {
19
+ 'Content-Type' => content_type,
20
+ 'Content-Length' => body.bytesize.to_s
21
+ }
22
+
23
+ [status, headers, [body]]
24
+ end
25
+
26
+ def call(env)
27
+ unless authenticate(env)
28
+ return rack_response(403, 'Invalid auth token', 'text/plain')
29
+ end
30
+
31
+ case env['PATH_INFO']
32
+ when /\/stop$/
33
+ @cli.stop
34
+ return rack_response(200, OK_STATUS)
35
+
36
+ when /\/halt$/
37
+ @cli.halt
38
+ return rack_response(200, OK_STATUS)
39
+
40
+ when /\/restart$/
41
+ @cli.restart
42
+ return rack_response(200, OK_STATUS)
43
+
44
+ when /\/phased-restart$/
45
+ if !@cli.phased_restart
46
+ return rack_response(404, '{ "error": "phased restart not available" }')
47
+ else
48
+ return rack_response(200, OK_STATUS)
49
+ end
50
+
51
+ when /\/stats$/
52
+ return rack_response(200, @cli.stats)
53
+ else
54
+ rack_response 404, "Unsupported action", 'text/plain'
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end