nyara 0.0.1.pre

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 (67) hide show
  1. checksums.yaml +7 -0
  2. data/example/design.rb +62 -0
  3. data/example/fib.rb +15 -0
  4. data/example/hello.rb +5 -0
  5. data/example/stream.rb +10 -0
  6. data/ext/accept.c +133 -0
  7. data/ext/event.c +89 -0
  8. data/ext/extconf.rb +34 -0
  9. data/ext/hashes.c +130 -0
  10. data/ext/http-parser/AUTHORS +41 -0
  11. data/ext/http-parser/CONTRIBUTIONS +4 -0
  12. data/ext/http-parser/LICENSE-MIT +23 -0
  13. data/ext/http-parser/contrib/parsertrace.c +156 -0
  14. data/ext/http-parser/contrib/url_parser.c +44 -0
  15. data/ext/http-parser/http_parser.c +2175 -0
  16. data/ext/http-parser/http_parser.h +304 -0
  17. data/ext/http-parser/test.c +3425 -0
  18. data/ext/http_parser.c +1 -0
  19. data/ext/inc/epoll.h +60 -0
  20. data/ext/inc/kqueue.h +77 -0
  21. data/ext/inc/status_codes.inc +64 -0
  22. data/ext/inc/str_intern.h +66 -0
  23. data/ext/inc/version.inc +1 -0
  24. data/ext/mime.c +107 -0
  25. data/ext/multipart-parser-c/README.md +18 -0
  26. data/ext/multipart-parser-c/multipart_parser.c +309 -0
  27. data/ext/multipart-parser-c/multipart_parser.h +48 -0
  28. data/ext/multipart_parser.c +1 -0
  29. data/ext/nyara.c +56 -0
  30. data/ext/nyara.h +59 -0
  31. data/ext/request.c +474 -0
  32. data/ext/route.cc +325 -0
  33. data/ext/url_encoded.c +304 -0
  34. data/hello.rb +5 -0
  35. data/lib/nyara/config.rb +64 -0
  36. data/lib/nyara/config_hash.rb +51 -0
  37. data/lib/nyara/controller.rb +336 -0
  38. data/lib/nyara/cookie.rb +31 -0
  39. data/lib/nyara/cpu_counter.rb +65 -0
  40. data/lib/nyara/header_hash.rb +18 -0
  41. data/lib/nyara/mime_types.rb +612 -0
  42. data/lib/nyara/nyara.rb +82 -0
  43. data/lib/nyara/param_hash.rb +5 -0
  44. data/lib/nyara/request.rb +144 -0
  45. data/lib/nyara/route.rb +138 -0
  46. data/lib/nyara/route_entry.rb +43 -0
  47. data/lib/nyara/session.rb +104 -0
  48. data/lib/nyara/view.rb +317 -0
  49. data/lib/nyara.rb +25 -0
  50. data/nyara.gemspec +20 -0
  51. data/rakefile +91 -0
  52. data/readme.md +35 -0
  53. data/spec/ext_mime_match_spec.rb +27 -0
  54. data/spec/ext_parse_accept_value_spec.rb +29 -0
  55. data/spec/ext_parse_spec.rb +138 -0
  56. data/spec/ext_route_spec.rb +70 -0
  57. data/spec/hashes_spec.rb +71 -0
  58. data/spec/path_helper_spec.rb +77 -0
  59. data/spec/request_delegate_spec.rb +67 -0
  60. data/spec/request_spec.rb +56 -0
  61. data/spec/route_entry_spec.rb +12 -0
  62. data/spec/route_spec.rb +84 -0
  63. data/spec/session_spec.rb +66 -0
  64. data/spec/spec_helper.rb +52 -0
  65. data/spec/view_spec.rb +87 -0
  66. data/tools/bench-cookie.rb +22 -0
  67. metadata +111 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cb0049e820e49ff09f09423ecce778a56834fd82
4
+ data.tar.gz: 30a2651c518f2f7c3db0581396b52ef1655c4ce8
5
+ SHA512:
6
+ metadata.gz: b43a204aa71c4a3b1f2a94b21ee87be98d0e78348e93d9ba7439df27cb383cced9d1135e3ac1ce47e6bd7479d8542456360ce1c297399eaa77cfcce41871ea79
7
+ data.tar.gz: 955570020bccc660c5d7ae82ecad85c821988f92ebc80b4beffaa84575a1b487ccecf07be51d6041c7a88af62565e6a61260bec11009dacaf0c88814decedca7
data/example/design.rb ADDED
@@ -0,0 +1,62 @@
1
+ meta '#hello', accept: %w[js html] | default is text/html, default / * not implemented yet
2
+ get '/' do
3
+ send_data ... --> will make encoding chunked
4
+
5
+ # set resp status
6
+ status 302 | :not_found
7
+
8
+ # content type is separated out from render
9
+ content_type :js
10
+
11
+ # terminal action : render view, or file for download
12
+ render ..., layout: [a, b, c]
13
+
14
+ render file # choose renderer by ext
15
+ render :slim => template_content
16
+
17
+ ... Fiber.yield
18
+
19
+ s = stream ... # same arg as render
20
+ ...
21
+ r.resume
22
+ ...
23
+ r.resume
24
+
25
+ render :slim, 'content'
26
+
27
+ # terminal action
28
+ redirect_to path_for '...'
29
+ redirect_to '/'
30
+ redirect_to :back # referrer
31
+
32
+ # terminate process
33
+ halt status
34
+
35
+ # loop response
36
+ loop do
37
+ sleep 4
38
+ send_data ...
39
+ end
40
+
41
+ # can use accept when meta is configured, raise error if not configured
42
+ case accept
43
+ when 'html'
44
+ ...
45
+ when 'js'
46
+ end
47
+ end
48
+
49
+ # default is no scheme, the links start with // to fit all schemes
50
+ configure url_for, default_scheme nil / 'https'
51
+
52
+ url_for '#b', scheme: 'http', format: 'js', host: 'a.b.c:3000' # string keys are put in query
53
+
54
+ path_for 'cont#action', 12, 3, :format => 'js', # string keys are put in query, (what about hash tags?)
55
+
56
+ partial '...'
57
+
58
+ # for middleware, we use life cycle callbacks
59
+ # on :header_complete
60
+ # on :init
61
+
62
+ # before
data/example/fib.rb ADDED
@@ -0,0 +1,15 @@
1
+ require "nyara"
2
+
3
+ configure do
4
+ port 3000
5
+ end
6
+
7
+ def fib i
8
+ a, b = 0, 1
9
+ i.times { a, b = b, a + b }
10
+ a
11
+ end
12
+
13
+ get '/fib/%d' do |i|
14
+ send_string "fib(#{i}) = #{fib i}\n"
15
+ end
data/example/hello.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "nyara"
2
+
3
+ get '/' do
4
+ send_string 'hello world'
5
+ end
data/example/stream.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "nyara"
2
+ require "slim"
3
+
4
+ get '/' do
5
+ view = stream 'index'
6
+ 4.times do
7
+ sleep 1
8
+ view.resume
9
+ end
10
+ end
data/ext/accept.c ADDED
@@ -0,0 +1,133 @@
1
+ /* efficient Accpet-* value parser in C */
2
+
3
+ #include "nyara.h"
4
+ #include <ctype.h>
5
+ #include "inc/str_intern.h"
6
+
7
+ // standard:
8
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
9
+ // about +q+:
10
+ // http://www.gethifi.com/blog/browser-rest-http-accept-headers
11
+ // +level+ is a waste of time:
12
+ // http://stackoverflow.com/questions/13890996/http-accept-level
13
+
14
+ // sorted data structure
15
+ typedef struct {
16
+ double* qs;
17
+ long len;
18
+ long cap;
19
+ } QArray;
20
+
21
+ static QArray qarray_new() {
22
+ QArray qa = {ALLOC_N(double, 10), 0, 10};
23
+ return qa;
24
+ }
25
+
26
+ // return inserted pos
27
+ static long qarray_insert(QArray* qa, double v) {
28
+ if (qa->len == qa->cap) {
29
+ qa->cap *= 2;
30
+ REALLOC_N(qa->qs, double, qa->cap);
31
+ }
32
+ long i = 0;
33
+ for (; i < qa->len; i++) {
34
+ if (qa->qs[i] < v) {
35
+ memmove(qa->qs + i + 1, qa->qs + i, sizeof(double) * (qa->len - i));
36
+ break;
37
+ }
38
+ }
39
+ qa->qs[i] = v;
40
+ qa->len++;
41
+ return i;
42
+ }
43
+
44
+ static void qarray_delete(QArray* qa) {
45
+ xfree(qa->qs);
46
+ }
47
+
48
+ static VALUE trim_space(VALUE str) {
49
+ long olen = RSTRING_LEN(str);
50
+ str = rb_str_new(RSTRING_PTR(str), olen);
51
+ char* s = RSTRING_PTR(str);
52
+ long len = 0;
53
+ for (long i = 0; i < olen; i++) {
54
+ if (!isspace(s[i])) {
55
+ s[len++] = s[i];
56
+ }
57
+ }
58
+ STR_SET_LEN(str, len);
59
+ return str;
60
+ }
61
+
62
+ // stopped by ',' or EOS, return seg_len
63
+ static long find_seg(const char* s, long len) {
64
+ long i = 0;
65
+ for (; i < len; i++) {
66
+ if (s[i] == ',') {
67
+ break;
68
+ }
69
+ }
70
+ return i;
71
+ }
72
+
73
+ // return first pointer to ';q='
74
+ static const char* find_q(const char* s, long len) {
75
+ for (long i = 0; i < (len - 2); i++) {
76
+ if (s[i] == ';' && s[i+1] == 'q' && s[i+2] == '=') {
77
+ return s + i;
78
+ }
79
+ }
80
+ return NULL;
81
+ }
82
+
83
+ // parse a segment, and +out[value] = q+
84
+ static void parse_seg(const char* s, long len, VALUE out, QArray* qa) {
85
+ double qval = 1;
86
+ const char* q = find_q(s, len);
87
+ if (q) {
88
+ if (q == s) {
89
+ return;
90
+ }
91
+ char* str_end = (char*)q + 3;
92
+ qval = strtod(q + 3, &str_end);
93
+ if (str_end == q + 3 || isnan(qval) || qval > 3) {
94
+ qval = 1;
95
+ } else if (qval <= 0) {
96
+ return;
97
+ }
98
+ len = q - s;
99
+ }
100
+ long pos = qarray_insert(qa, qval);
101
+ rb_ary_push(out, Qnil); // just to increase cap
102
+ VALUE* out_ptr = RARRAY_PTR(out);
103
+ long out_len = RARRAY_LEN(out); // note this len is +1
104
+ memmove(out_ptr + pos + 1, out_ptr + pos, sizeof(VALUE) * (out_len - pos - 1));
105
+ rb_ary_store(out, pos, rb_str_new(s, len));
106
+ }
107
+
108
+ VALUE ext_parse_accept_value(VALUE _, VALUE str) {
109
+ if (str == Qnil) {
110
+ return rb_ary_new();
111
+ }
112
+
113
+ str = trim_space(str);
114
+ const char* s = RSTRING_PTR(str);
115
+ long len = RSTRING_LEN(str);
116
+ volatile VALUE out = rb_ary_new();
117
+ QArray qa = qarray_new();
118
+ while (len > 0) {
119
+ long seg_len = find_seg(s, len);
120
+ if (seg_len == 0) {
121
+ break;
122
+ }
123
+ parse_seg(s, seg_len, out, &qa);
124
+ s += seg_len + 1;
125
+ len -= seg_len + 1;
126
+ }
127
+ qarray_delete(&qa);
128
+ return out;
129
+ }
130
+
131
+ void Init_accept(VALUE ext) {
132
+ rb_define_singleton_method(ext, "parse_accept_value", ext_parse_accept_value, 1);
133
+ }
data/ext/event.c ADDED
@@ -0,0 +1,89 @@
1
+ #include "nyara.h"
2
+ #include <sys/fcntl.h>
3
+ #include <sys/socket.h>
4
+ #include <errno.h>
5
+ #include <stdint.h>
6
+ #include <unistd.h>
7
+
8
+ #define ETYPE_ACCEPT 0
9
+ #define ETYPE_REQUEST 1
10
+ #define ETYPE_CONNECT 2
11
+ #define MAX_E 1024
12
+ static void loop_body(int fd, int etype);
13
+ static int qfd;
14
+
15
+ #ifdef HAVE_KQUEUE
16
+ #include "inc/kqueue.h"
17
+ #elif HAVE_EPOLL
18
+ #include "inc/epoll.h"
19
+ #endif
20
+
21
+ static void set_nonblock(int fd) {
22
+ int flags;
23
+
24
+ if ((flags = fcntl(fd, F_GETFL)) == -1) {
25
+ rb_raise(rb_eRuntimeError, "fcntl(F_GETFL): %s", strerror(errno));
26
+ }
27
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
28
+ rb_raise(rb_eRuntimeError, "fcntl(F_SETFL,O_NONBLOCK): %s", strerror(errno));
29
+ }
30
+ }
31
+
32
+ static VALUE ext_add(VALUE _, VALUE vfd) {
33
+ int fd = FIX2INT(vfd);
34
+ ADD_E(fd, ETYPE_CONNECT);
35
+ return Qnil;
36
+ }
37
+
38
+ // platform independent, invoked by LOOP_E()
39
+ static void loop_body(int fd, int etype) {
40
+ switch (etype) {
41
+ case ETYPE_ACCEPT: {
42
+ int cfd = accept(fd, NULL, NULL);
43
+ if (cfd > 0) {
44
+ set_nonblock(cfd);
45
+ ADD_E(cfd, ETYPE_REQUEST);
46
+ }
47
+ break;
48
+ }
49
+ case ETYPE_REQUEST: {
50
+ nyara_handle_request(fd);
51
+ break;
52
+ }
53
+ case ETYPE_CONNECT: {
54
+ // todo
55
+ // NOTE
56
+ // fd and connection are 1:1, there can more more than 1 fds on a same file / address
57
+ // so it's streight forward to using fd as query index
58
+ }
59
+ }
60
+ }
61
+
62
+ static VALUE ext_init_queue(VALUE _) {
63
+ INIT_E();
64
+ return Qnil;
65
+ }
66
+
67
+ static VALUE ext_run_queue(VALUE _, VALUE v_fd) {
68
+ int fd = FIX2INT(v_fd);
69
+ set_nonblock(fd);
70
+ ADD_E(fd, ETYPE_ACCEPT);
71
+
72
+ LOOP_E();
73
+ return Qnil;
74
+ }
75
+
76
+ static VALUE ext_set_nonblock(VALUE _, VALUE v_fd) {
77
+ int fd = FIX2INT(v_fd);
78
+ set_nonblock(fd);
79
+ return Qnil;
80
+ }
81
+
82
+ void Init_event(VALUE ext) {
83
+ // rb_define_singleton_method(c, "add", add_q, 2);
84
+ rb_define_singleton_method(ext, "init_queue", ext_init_queue, 0);
85
+ rb_define_singleton_method(ext, "run_queue", ext_run_queue, 1);
86
+
87
+ // for test
88
+ rb_define_singleton_method(ext, "set_nonblock", ext_set_nonblock, 1);
89
+ }
data/ext/extconf.rb ADDED
@@ -0,0 +1,34 @@
1
+ require "mkmf"
2
+
3
+ def tweak_include
4
+ dir = File.dirname __FILE__
5
+ multipart_dir = File.join dir, "multipart-parser-c"
6
+ http_parser_dir = File.join dir, "http-parser"
7
+ flags = " -I#{multipart_dir.shellescape} -I#{http_parser_dir.shellescape}"
8
+ $CFLAGS << flags
9
+ $CPPFLAGS << flags
10
+ end
11
+
12
+ def tweak_cflags
13
+ mf_conf = RbConfig::MAKEFILE_CONFIG
14
+ if mf_conf['CC'] =~ /clang/
15
+ # enable c++11. this can not be installed on $CPPFLAGS, wtf??
16
+ mf_conf['CXXFLAGS'] << ' -stdlib=libc++ -std=c++11'
17
+ $CFLAGS << ' $(xflags)'
18
+ else
19
+ mf_conf['CXXFLAGS'] << ' -std=c++11'
20
+ $CFLAGS << ' -std=c99 -Wno-declaration-after-statement $(xflags)'
21
+ end
22
+
23
+ $CPPFLAGS << ' $(xflags)'
24
+ puts "To enable debug: make xflags='-DDEBUG -O0'"
25
+ end
26
+
27
+ have_kqueue = (have_header("sys/event.h") and have_header("sys/queue.h"))
28
+ have_epoll = have_func('epoll_create', 'sys/epoll.h')
29
+ abort('no kqueue nor epoll') if !have_kqueue and !have_epoll
30
+ $defs << "-DNDEBUG -D#{have_epoll ? 'HAVE_EPOLL' : 'HAVE_KQUEUE'}"
31
+
32
+ tweak_include
33
+ tweak_cflags
34
+ create_makefile 'nyara'
data/ext/hashes.c ADDED
@@ -0,0 +1,130 @@
1
+ // provide handy hash variants
2
+ #include "nyara.h"
3
+ #include <ruby/st.h>
4
+
5
+ VALUE nyara_param_hash_class;
6
+ VALUE nyara_header_hash_class;
7
+ VALUE nyara_config_hash_class;
8
+
9
+ // stolen from hash.c
10
+ int nyara_rb_hash_has_key(VALUE hash, VALUE key) {
11
+ if (!RHASH(hash)->ntbl)
12
+ return 0;
13
+ if (st_lookup(RHASH(hash)->ntbl, key, 0))
14
+ return 1;
15
+ return 0;
16
+ }
17
+
18
+ // NOTE no need to add lots of methods like HashWithIndifferentAccess
19
+ // just return simple hash like rack
20
+
21
+ static VALUE param_hash_aref(VALUE self, VALUE key) {
22
+ if (TYPE(key) == T_SYMBOL) {
23
+ key = rb_sym_to_s(key);
24
+ }
25
+ return rb_hash_aref(self, key);
26
+ }
27
+
28
+ static VALUE param_hash_key_p(VALUE self, VALUE key) {
29
+ if (TYPE(key) == T_SYMBOL) {
30
+ key = rb_sym_to_s(key);
31
+ }
32
+ return nyara_rb_hash_has_key(self, key) ? Qtrue : Qfalse;
33
+ }
34
+
35
+ static VALUE param_hash_aset(VALUE self, VALUE key, VALUE value) {
36
+ if (TYPE(key) == T_SYMBOL) {
37
+ key = rb_sym_to_s(key);
38
+ }
39
+ return rb_hash_aset(self, key, value);
40
+ }
41
+
42
+ void nyara_headerlize(VALUE str) {
43
+ char* s = (char*)RSTRING_PTR(str);
44
+ long len = RSTRING_LEN(str);
45
+ int border = 1;
46
+ for (long i = 0; i < len; i++) {
47
+ if (s[i] == '-') {
48
+ border = 1;
49
+ continue;
50
+ }
51
+ if (border) {
52
+ // note this is most reliable way,
53
+ // with <ctype.h> we have to deal with locale...
54
+ if (s[i] >= 'a' && s[i] <= 'z') {
55
+ s[i] = 'A' + (s[i] - 'a');
56
+ }
57
+ border = 0;
58
+ } else {
59
+ if (s[i] >= 'A' && s[i] <= 'Z') {
60
+ s[i] = 'a' + (s[i] - 'A');
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ static VALUE header_hash_tidy_key(VALUE key) {
67
+ if (TYPE(key) == T_SYMBOL) {
68
+ key = rb_sym_to_s(key);
69
+ }
70
+ Check_Type(key, T_STRING);
71
+ key = rb_str_new(RSTRING_PTR(key), RSTRING_LEN(key));
72
+ nyara_headerlize(key);
73
+ return key;
74
+ }
75
+
76
+ static VALUE header_hash_aref(VALUE self, VALUE key) {
77
+ return rb_hash_aref(self, header_hash_tidy_key(key));
78
+ }
79
+
80
+ static VALUE header_hash_key_p(VALUE self, VALUE key) {
81
+ return nyara_rb_hash_has_key(self, header_hash_tidy_key(key)) ? Qtrue : Qfalse;
82
+ }
83
+
84
+ ID id_to_s;
85
+ static VALUE header_hash_aset(VALUE self, VALUE key, VALUE value) {
86
+ key = header_hash_tidy_key(key);
87
+ if (TYPE(value) != T_STRING) {
88
+ value = rb_funcall(value, id_to_s, 0);
89
+ }
90
+
91
+ return rb_hash_aset(self, key, value);
92
+ }
93
+
94
+ int header_hash_merge_func(VALUE k, VALUE v, VALUE self_st) {
95
+ st_table* t = (st_table*)self_st;
96
+ if (!st_is_member(t, k)) {
97
+ st_insert(t, (st_data_t)k, (st_data_t)v);
98
+ }
99
+ return ST_CONTINUE;
100
+ }
101
+
102
+ static VALUE header_hash_reverse_merge_bang(VALUE self, VALUE other) {
103
+ if (!rb_obj_is_kind_of(other, nyara_header_hash_class)) {
104
+ rb_raise(rb_eArgError, "need a Nyara::HeaderHash");
105
+ }
106
+ st_table* t = rb_hash_tbl(self);
107
+ rb_hash_foreach(other, header_hash_merge_func, (VALUE)t);
108
+ return self;
109
+ }
110
+
111
+ void Init_hashes(VALUE nyara) {
112
+ id_to_s = rb_intern("to_s");
113
+
114
+ nyara_param_hash_class = rb_define_class_under(nyara, "ParamHash", rb_cHash);
115
+ nyara_header_hash_class = rb_define_class_under(nyara, "HeaderHash", nyara_param_hash_class);
116
+ nyara_config_hash_class = rb_define_class_under(nyara, "ConfigHash", nyara_param_hash_class);
117
+
118
+ rb_define_method(nyara_param_hash_class, "[]", param_hash_aref, 1);
119
+ rb_define_method(nyara_param_hash_class, "key?", param_hash_key_p, 1);
120
+ rb_define_method(nyara_param_hash_class, "[]=", param_hash_aset, 2);
121
+
122
+ rb_define_method(nyara_header_hash_class, "[]", header_hash_aref, 1);
123
+ rb_define_method(nyara_header_hash_class, "key?", header_hash_key_p, 1);
124
+ rb_define_method(nyara_header_hash_class, "[]=", header_hash_aset, 2);
125
+ rb_define_method(nyara_header_hash_class, "reverse_merge!", header_hash_reverse_merge_bang, 1);
126
+
127
+ // for internal use
128
+ rb_define_method(nyara_header_hash_class, "_aset", rb_hash_aset, 2);
129
+ rb_define_method(nyara_header_hash_class, "_aref", rb_hash_aref, 1);
130
+ }
@@ -0,0 +1,41 @@
1
+ # Authors ordered by first contribution.
2
+ Ryan Dahl <ry@tinyclouds.org>
3
+ Jeremy Hinegardner <jeremy@hinegardner.org>
4
+ Sergey Shepelev <temotor@gmail.com>
5
+ Joe Damato <ice799@gmail.com>
6
+ tomika <tomika_nospam@freemail.hu>
7
+ Phoenix Sol <phoenix@burninglabs.com>
8
+ Cliff Frey <cliff@meraki.com>
9
+ Ewen Cheslack-Postava <ewencp@cs.stanford.edu>
10
+ Santiago Gala <sgala@apache.org>
11
+ Tim Becker <tim.becker@syngenio.de>
12
+ Jeff Terrace <jterrace@gmail.com>
13
+ Ben Noordhuis <info@bnoordhuis.nl>
14
+ Nathan Rajlich <nathan@tootallnate.net>
15
+ Mark Nottingham <mnot@mnot.net>
16
+ Aman Gupta <aman@tmm1.net>
17
+ Tim Becker <tim.becker@kuriositaet.de>
18
+ Sean Cunningham <sean.cunningham@mandiant.com>
19
+ Peter Griess <pg@std.in>
20
+ Salman Haq <salman.haq@asti-usa.com>
21
+ Cliff Frey <clifffrey@gmail.com>
22
+ Jon Kolb <jon@b0g.us>
23
+ Fouad Mardini <f.mardini@gmail.com>
24
+ Paul Querna <pquerna@apache.org>
25
+ Felix Geisendörfer <felix@debuggable.com>
26
+ koichik <koichik@improvement.jp>
27
+ Andre Caron <andre.l.caron@gmail.com>
28
+ Ivo Raisr <ivosh@ivosh.net>
29
+ James McLaughlin <jamie@lacewing-project.org>
30
+ David Gwynne <loki@animata.net>
31
+ Thomas LE ROUX <thomas@november-eleven.fr>
32
+ Randy Rizun <rrizun@ortivawireless.com>
33
+ Andre Louis Caron <andre.louis.caron@usherbrooke.ca>
34
+ Simon Zimmermann <simonz05@gmail.com>
35
+ Erik Dubbelboer <erik@dubbelboer.com>
36
+ Martell Malone <martellmalone@gmail.com>
37
+ Bertrand Paquet <bpaquet@octo.com>
38
+ BogDan Vatra <bogdan@kde.org>
39
+ Peter Faiman <peter@thepicard.org>
40
+ Corey Richardson <corey@octayn.net>
41
+ Tóth Tamás <tomika_nospam@freemail.hu>
@@ -0,0 +1,4 @@
1
+ Contributors must agree to the Contributor License Agreement before patches
2
+ can be accepted.
3
+
4
+ http://spreadsheets2.google.com/viewform?hl=en&formkey=dDJXOGUwbzlYaWM4cHN1MERwQS1CSnc6MQ
@@ -0,0 +1,23 @@
1
+ http_parser.c is based on src/http/ngx_http_parse.c from NGINX copyright
2
+ Igor Sysoev.
3
+
4
+ Additional changes are licensed under the same terms as NGINX and
5
+ copyright Joyent, Inc. and other Node contributors. All rights reserved.
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to
9
+ deal in the Software without restriction, including without limitation the
10
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11
+ sell copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23
+ IN THE SOFTWARE.