Changeset 993

Show
Ignore:
Timestamp:
03/06/08 02:41:33 (6 months ago)
Author:
normalperson
Message:

ext/http11: remove strchr() and scary comment regarding it

Replace it with memchr(3) instead, which works on a buffer
with a predetermined length, so we don't have to worry about
strange versions of Ruby which don't null-terminate strings.

memchr() is used several times in the MRI source code itself
(without compatibility definitions), so it should be portable to
all platforms MRI runs on.

Additionally, we now tolerate null bytes in the Host header and
can still parse ports in them correctly if anybody sends
them :)

If it matters, it is also theoretically faster as it doesn't
need to check for a '\0' terminator.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ext/http11/http11.c

    r992 r993  
    293293  rb_hash_aset(req, global_gateway_interface, global_gateway_interface_value); 
    294294  if((temp = rb_hash_aref(req, global_http_host)) != Qnil) { 
    295     /* ruby better close strings off with a '\0' dammit */ 
    296     colon = strchr(RSTRING_PTR(temp), ':'); 
     295    colon = memchr(RSTRING_PTR(temp), ':', RSTRING_LEN(temp)); 
    297296    if(colon != NULL) { 
    298297      rb_hash_aset(req, global_server_name, rb_str_substr(temp, 0, colon - RSTRING_PTR(temp))); 
  • trunk/test/test_http11.rb

    r992 r993  
    131131  end 
    132132 
     133  def test_host_port_parsing 
     134    parser = HttpParser.new 
     135    req = {} 
     136    should_be_good = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" 
     137    nread = parser.execute(req, should_be_good, 0) 
     138    assert_equal should_be_good.length, nread 
     139    assert parser.finished? 
     140    assert !parser.error? 
     141    assert_equal "example.com", req["HTTP_HOST"] 
     142    assert_equal "example.com", req["SERVER_NAME"] 
     143    assert_equal "80", req["SERVER_PORT"] 
     144 
     145    parser = HttpParser.new 
     146    req = {} 
     147    should_be_good = "GET / HTTP/1.1\r\nHost: example.com:123\r\n\r\n" 
     148    nread = parser.execute(req, should_be_good, 0) 
     149    assert_equal should_be_good.length, nread 
     150    assert parser.finished? 
     151    assert !parser.error? 
     152    assert_equal "example.com:123", req["HTTP_HOST"] 
     153    assert_equal "example.com", req["SERVER_NAME"] 
     154    assert_equal "123", req["SERVER_PORT"] 
     155 
     156    # null character in domain name is never actually valid, but if it 
     157    # becomes valid in Web 3.0, we'll be ready for it. 
     158    parser = HttpParser.new 
     159    req = {} 
     160    should_be_good = "GET / HTTP/1.1\r\nHost: example.com\0:123\r\n\r\n" 
     161    nread = parser.execute(req, should_be_good, 0) 
     162    assert_equal should_be_good.length, nread 
     163    assert parser.finished? 
     164    assert !parser.error? 
     165    assert_equal "example.com\0:123", req["HTTP_HOST"] 
     166    assert_equal "example.com\0", req["SERVER_NAME"] 
     167    assert_equal "123", req["SERVER_PORT"] 
     168  end 
     169 
    133170  def test_fragment_in_uri 
    134171    parser = HttpParser.new