rhebok 0.0.3 → 0.0.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e57b88c70418eccd0131a3798c093e5f121783df
4
- data.tar.gz: d483fa40f2b94af141e1a7674bb9ee01d3c0b326
3
+ metadata.gz: 9f2f6e28f41bf7d49e71ade28a3c1ff5628d219f
4
+ data.tar.gz: b593fa179c4f0e53271f883d82e68ee6fe6e40d7
5
5
  SHA512:
6
- metadata.gz: 56a9bedb5bdfa63745fc1bcd46ef349173a144c911cfbb2b08570d81051ebe6bdad4c2f39a1ad98892428b6093ebb27b9d0b7e6e83c22856b6939ff3a77d30ee
7
- data.tar.gz: 80dbef163aa4804173847972c5c2dbdb5097775a24e3127cebee33efdd460326e0a6d84d1e574d6170214dbafea110c3cb5280e1945ecb8dc4e6d187ea90ea61
6
+ metadata.gz: e1c9b47ec3cf7e8b9e1566e0d62f04a0d80bea52d4b5b8a357e0b29253c339199825ff1fa7e4fc8daa1501a47b441034363d4a8e09504bc91d00124e4d21eb8b
7
+ data.tar.gz: 288903b31717eb0887605c0dc36e4743d45e3be4f876b20a8c3985cc88141f29913b16f8607576b7a52e89e43e95a597b2d267b832cb9e07ebf8341218ce0b00
data/Changes CHANGED
@@ -1,3 +1,7 @@
1
+ 0.0.4 2014-12-19-T01:50:11Z
2
+
3
+ - support multiple line header
4
+
1
5
  0.0.3 2014-12-18T17:22:53Z
2
6
 
3
7
  - fixed segfault. iovec shortage
@@ -122,6 +122,12 @@ static VALUE remote_addr_key;
122
122
  static VALUE remote_port_key;
123
123
  static VALUE path_info_key;
124
124
 
125
+ static VALUE vacant_string_val;
126
+ static VALUE zero_string_val;
127
+
128
+ static VALUE http10_val;
129
+ static VALUE http11_val;
130
+
125
131
  struct common_header {
126
132
  const char * name;
127
133
  size_t name_len;
@@ -167,6 +173,17 @@ void set_common_header(const char * key, int key_len, const int raw)
167
173
  common_headers_num++;
168
174
  }
169
175
 
176
+ static
177
+ long find_lf(const char* v, ssize_t offset, ssize_t len)
178
+ {
179
+ ssize_t i;
180
+ for ( i=offset; i != len; ++i) {
181
+ if (v[i] == 10) {
182
+ return i;
183
+ }
184
+ }
185
+ return len;
186
+ }
170
187
 
171
188
  static
172
189
  size_t find_ch(const char* s, size_t len, char ch)
@@ -207,7 +224,7 @@ int store_path_info(VALUE env, const char* src, size_t src_len) {
207
224
  size_t dlen = 0, i = 0;
208
225
  char *d;
209
226
  char s2, s3;
210
- d = (char*)malloc(src_len * 3 + 1);
227
+ d = ALLOC_N(char, src_len * 3 + 1);
211
228
  for (i = 0; i < src_len; i++ ) {
212
229
  if ( src[i] == '%' ) {
213
230
  if ( !isxdigit(src[i+1]) || !isxdigit(src[i+2]) ) {
@@ -231,7 +248,7 @@ int store_path_info(VALUE env, const char* src, size_t src_len) {
231
248
  }
232
249
  d[dlen]='0';
233
250
  rb_hash_aset(env, path_info_key, rb_str_new(d, dlen));
234
- free(d);
251
+ xfree(d);
235
252
  return dlen;
236
253
  }
237
254
 
@@ -418,10 +435,8 @@ int _parse_http_request(char *buf, ssize_t buf_len, VALUE env) {
418
435
 
419
436
  rb_hash_aset(env, request_method_key, rb_str_new(method,method_len));
420
437
  rb_hash_aset(env, request_uri_key, rb_str_new(path, path_len));
421
- rb_hash_aset(env, script_name_key, rb_str_new2(""));
422
- strcpy(tmp, "HTTP/1.");
423
- tmp[7] = 48 + ((minor_version > 1 || minor_version < 0 ) ? 0 : minor_version);
424
- rb_hash_aset(env, server_protocol_key, rb_str_new(tmp, sizeof("HTTP/1.0") - 1));
438
+ rb_hash_aset(env, script_name_key, vacant_string_val);
439
+ rb_hash_aset(env, server_protocol_key, (minor_version > 1 || minor_version < 0 ) ? http10_val : http11_val);
425
440
 
426
441
  /* PATH_INFO QUERY_STRING */
427
442
  path_len = find_ch(path, path_len, '#'); /* strip off all text after # after storing request_uri */
@@ -515,8 +530,8 @@ VALUE rhe_accept(VALUE self, VALUE fileno, VALUE timeoutv, VALUE tcp, VALUE env)
515
530
  rb_hash_aset(env, remote_port_key, rb_String(rb_int_new(ntohs(cliaddr.sin_port))));
516
531
  }
517
532
  else {
518
- rb_hash_aset(env, remote_addr_key, rb_str_new("",0));
519
- rb_hash_aset(env, remote_port_key, rb_String(rb_int_new(0)));
533
+ rb_hash_aset(env, remote_addr_key, vacant_string_val);
534
+ rb_hash_aset(env, remote_port_key, zero_string_val);
520
535
  }
521
536
 
522
537
  buf_len = rv;
@@ -556,15 +571,23 @@ VALUE rhe_accept(VALUE self, VALUE fileno, VALUE timeoutv, VALUE tcp, VALUE env)
556
571
  }
557
572
 
558
573
  static
559
- VALUE rhe_read_timeout(VALUE self, VALUE fileno, VALUE rbuf, VALUE len, VALUE offset, VALUE timeout) {
574
+ VALUE rhe_read_timeout(VALUE self, VALUE filenov, VALUE rbuf, VALUE lenv, VALUE offsetv, VALUE timeoutv) {
560
575
  char * d;
561
576
  ssize_t rv;
562
- d = malloc(len);
563
- rv = _read_timeout(NUM2INT(fileno), NUM2DBL(timeout), &d[NUM2LONG(offset)], NUM2LONG(len));
577
+ int fileno;
578
+ double timeout;
579
+ ssize_t offset;
580
+ ssize_t len;
581
+ fileno = NUM2INT(filenov);
582
+ timeout = NUM2DBL(timeoutv);
583
+ offset = NUM2LONG(offsetv);
584
+ len = NUM2LONG(lenv);
585
+ d = ALLOC_N(char, len);
586
+ rv = _read_timeout(fileno, timeout, &d[offset], len);
564
587
  if ( rv > 0 ) {
565
588
  rb_str_cat(rbuf, d, rv);
566
589
  }
567
- free(d);
590
+ xfree(d);
568
591
  return rb_int_new(rv);
569
592
  }
570
593
 
@@ -638,6 +661,10 @@ VALUE rhe_write_response(VALUE self, VALUE filenov, VALUE timeoutv, VALUE status
638
661
  VALUE key_obj;
639
662
  VALUE val_obj;
640
663
  char * key;
664
+ char * val;
665
+ ssize_t val_len;
666
+ ssize_t val_offset;
667
+ long val_lf;
641
668
  const char * message;
642
669
 
643
670
 
@@ -650,7 +677,7 @@ VALUE rhe_write_response(VALUE self, VALUE filenov, VALUE timeoutv, VALUE status
650
677
  rb_hash_foreach(headers, my_hash_keys, arr);
651
678
  hlen = RARRAY_LEN(arr);
652
679
  blen = RARRAY_LEN(body);
653
- iovcnt = 10 + (hlen * 4) + blen;
680
+ iovcnt = 128 + (hlen * 4) + blen;
654
681
 
655
682
  {
656
683
  struct iovec v[iovcnt]; // Needs C99 compiler
@@ -694,20 +721,50 @@ VALUE rhe_write_response(VALUE self, VALUE filenov, VALUE timeoutv, VALUE status
694
721
  if ( strncasecmp(key,"Date",len) == 0 ) {
695
722
  date_pushed = 1;
696
723
  }
697
- v[iovcnt].iov_base = key;
698
- v[iovcnt].iov_len = len;
699
- iovcnt++;
700
- v[iovcnt].iov_base = ": ";
701
- v[iovcnt].iov_len = sizeof(": ") - 1;
702
- iovcnt++;
703
724
  /* value */
704
725
  val_obj = rb_hash_aref(headers, key_obj);
705
- v[iovcnt].iov_base = RSTRING_PTR(val_obj);
706
- v[iovcnt].iov_len = RSTRING_LEN(val_obj);
707
- iovcnt++;
708
- v[iovcnt].iov_base = "\r\n";
709
- v[iovcnt].iov_len = sizeof("\r\n") - 1;
710
- iovcnt++;
726
+ val = RSTRING_PTR(val_obj);
727
+ val_len = RSTRING_LEN(val_obj);
728
+ val_offset = 0;
729
+ val_lf = find_lf(val, val_offset, val_len);
730
+ if ( val_lf < val_len ) {
731
+ /* contain "\n" */
732
+ while ( val_offset < val_len ) {
733
+ // printf("'%s' val_len:%zd, val_offset:%zd, val_lf:%zd\n", &val[val_offset], val_len, val_offset, val_lf);
734
+ if ( val_offset != val_lf ) {
735
+ v[iovcnt].iov_base = key;
736
+ v[iovcnt].iov_len = len;
737
+ iovcnt++;
738
+ v[iovcnt].iov_base = ": ";
739
+ v[iovcnt].iov_len = sizeof(": ") - 1;
740
+ iovcnt++;
741
+ v[iovcnt].iov_base = &val[val_offset];
742
+ v[iovcnt].iov_len = val_lf - val_offset;
743
+ iovcnt++;
744
+ v[iovcnt].iov_base = "\r\n";
745
+ v[iovcnt].iov_len = sizeof("\r\n") - 1;
746
+ iovcnt++;
747
+ }
748
+ val_offset = val_lf + 1;
749
+ val_lf = find_lf(val, val_offset, val_len);
750
+ }
751
+ }
752
+ else {
753
+ v[iovcnt].iov_base = key;
754
+ v[iovcnt].iov_len = len;
755
+ iovcnt++;
756
+ v[iovcnt].iov_base = ": ";
757
+ v[iovcnt].iov_len = sizeof(": ") - 1;
758
+ iovcnt++;
759
+ v[iovcnt].iov_base = val;
760
+ v[iovcnt].iov_len = val_len;
761
+ iovcnt++;
762
+ v[iovcnt].iov_base = "\r\n";
763
+ v[iovcnt].iov_len = sizeof("\r\n") - 1;
764
+ iovcnt++;
765
+ }
766
+
767
+
711
768
  }
712
769
 
713
770
  if ( date_pushed == 0 ) {
@@ -771,12 +828,21 @@ void Init_rhebok()
771
828
  rb_gc_register_address(&server_protocol_key);
772
829
  query_string_key = rb_obj_freeze(rb_str_new2("QUERY_STRING"));
773
830
  rb_gc_register_address(&query_string_key);
774
-
775
831
  remote_addr_key = rb_obj_freeze(rb_str_new2("REMOTE_ADDR"));
776
832
  rb_gc_register_address(&remote_addr_key);
777
833
  remote_port_key = rb_obj_freeze(rb_str_new2("REMOTE_PORT"));
778
834
  rb_gc_register_address(&remote_port_key);
779
835
 
836
+ vacant_string_val = rb_obj_freeze(rb_str_new("",0));
837
+ rb_gc_register_address(&vacant_string_val);
838
+ zero_string_val = rb_obj_freeze(rb_str_new("0",1));
839
+ rb_gc_register_address(&zero_string_val);
840
+
841
+ http10_val = rb_obj_freeze(rb_str_new2("HTTP/1.0"));
842
+ rb_gc_register_address(&http10_val);
843
+ http11_val = rb_obj_freeze(rb_str_new2("HTTP/1.1"));
844
+ rb_gc_register_address(&http11_val);
845
+
780
846
  set_common_header("ACCEPT",sizeof("ACCEPT") - 1, 0);
781
847
  set_common_header("ACCEPT-ENCODING",sizeof("ACCEPT-ENCODING") - 1, 0);
782
848
  set_common_header("ACCEPT-LANGUAGE",sizeof("ACCEPT-LANGUAGE") - 1, 0);
@@ -1,3 +1,3 @@
1
1
  class Rhebok
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Rhebok::VERSION
9
9
  spec.authors = ["Masahiro Nagano"]
10
10
  spec.email = ["kazeburo@gmail.com"]
11
- spec.summary = %q{High Perfomance Preforked Rack Handler}
12
- spec.description = %q{High Perfomance and Optimized Preforked Rack Handler}
11
+ spec.summary = %q{High Performance Preforked Rack Handler}
12
+ spec.description = %q{High Performance and Optimized Preforked Rack Handler}
13
13
  spec.homepage = "https://github.com/kazeburo/rhebok"
14
14
  spec.license = "Artistic"
15
15
  spec.extensions = %w[ext/rhebok/extconf.rb]
@@ -40,6 +40,16 @@ describe Rhebok do
40
40
  response["rack.run_once"].should.equal false
41
41
  end
42
42
 
43
+ should "multiple header" do
44
+ GET("/")
45
+ header["Content-Type"].should.equal "text/yaml"
46
+ header["X-Foo"].should.equal "Foo, Bar"
47
+ header["X-Bar"].should.equal "Foo, Bar"
48
+ header["X-Baz"].should.equal "Baz"
49
+ header["X-Fuga"].should.equal "Fuga"
50
+ end
51
+
52
+
43
53
  should "have CGI headers on GET" do
44
54
  GET("/")
45
55
  response["REQUEST_METHOD"].should.equal "GET"
@@ -13,11 +13,11 @@ class TestRequest
13
13
  minienv.delete_if { |k,v| NOSERIALIZE.any? { |c| v.kind_of?(c) } }
14
14
  body = minienv.to_yaml
15
15
  size = body.respond_to?(:bytesize) ? body.bytesize : body.size
16
- [status, {"Content-Type" => "text/yaml", "Content-Length" => size.to_s}, [body]]
16
+ [status, {"Content-Type" => "text/yaml", "Content-Length" => size.to_s, "X-Foo" => "Foo\nBar", "X-Bar"=>"Foo\n\nBar", "X-Baz"=>"\nBaz", "X-Fuga"=>"Fuga\n"}, [body]]
17
17
  end
18
18
 
19
19
  module Helpers
20
- attr_reader :status, :response
20
+ attr_reader :status, :response, :header
21
21
 
22
22
  ROOT = File.expand_path(File.dirname(__FILE__) + "/..")
23
23
  ENV["RUBYOPT"] = "-I#{ROOT}/lib -rubygems"
@@ -39,6 +39,7 @@ class TestRequest
39
39
  get.basic_auth user, passwd if user && passwd
40
40
  http.request(get) { |response|
41
41
  @status = response.code.to_i
42
+ @header = response
42
43
  begin
43
44
  @response = YAML.load(response.body)
44
45
  rescue TypeError, ArgumentError
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rhebok
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro Nagano
@@ -80,7 +80,7 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.0.4
83
- description: High Perfomance and Optimized Preforked Rack Handler
83
+ description: High Performance and Optimized Preforked Rack Handler
84
84
  email:
85
85
  - kazeburo@gmail.com
86
86
  executables: []
@@ -137,7 +137,7 @@ rubyforge_project:
137
137
  rubygems_version: 2.2.2
138
138
  signing_key:
139
139
  specification_version: 4
140
- summary: High Perfomance Preforked Rack Handler
140
+ summary: High Performance Preforked Rack Handler
141
141
  test_files:
142
142
  - test/spec_02_basic.rb
143
143
  - test/spec_02_server.rb