Skip to content

Commit

Permalink
Merge pull request #7 from mcunha/fix-http-1.0
Browse files Browse the repository at this point in the history
Fix http 1.0
  • Loading branch information
bvanderveen committed Apr 1, 2012
2 parents 5747f5e + e79f9fb commit 41e85f7
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 20 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -7,3 +7,4 @@ packages
*.pidb
TestResult.xml
.DS_Store
test-results/
34 changes: 21 additions & 13 deletions src/HttpMachine/HttpParser.cs
Expand Up @@ -50,7 +50,7 @@ public bool ShouldKeepAlive
// int mark;


#line 335 "rl/HttpParser.cs.rl"
#line 343 "rl/HttpParser.cs.rl"



Expand Down Expand Up @@ -546,7 +546,7 @@ public bool ShouldKeepAlive
const int http_parser_en_dead = 130;


#line 338 "rl/HttpParser.cs.rl"
#line 346 "rl/HttpParser.cs.rl"

public HttpParser(IHttpParserDelegate del)
{
Expand All @@ -558,7 +558,7 @@ public HttpParser(IHttpParserDelegate del)
cs = http_parser_start;
}

#line 344 "rl/HttpParser.cs.rl"
#line 352 "rl/HttpParser.cs.rl"
}

public int Execute(ArraySegment<byte> buf)
Expand Down Expand Up @@ -592,7 +592,7 @@ public int Execute(ArraySegment<byte> buf)
while ( _nacts-- > 0 ) {
switch ( _http_parser_actions[_acts++] ) {
case 31:
#line 329 "rl/HttpParser.cs.rl"
#line 337 "rl/HttpParser.cs.rl"
{
throw new Exception("Parser is dead; there shouldn't be more data. Client is bogus? fpc =" + p);
}
Expand Down Expand Up @@ -873,7 +873,9 @@ public int Execute(ArraySegment<byte> buf)
// if content length is given and non-zero, we should read that many bytes
// if content length is not given
// if should keep alive, assume next request is coming and read it
// else read body until EOF
// else
// if chunked transfer read body until EOF
// else read next request

if (contentLength == 0)
{
Expand All @@ -898,16 +900,22 @@ public int Execute(ArraySegment<byte> buf)
}
else
{
//Console.WriteLine("Not keeping alive, will read until eof. Will hold, but currently fpc = " + fpc);
if (gotTransferEncodingChunked) {
//Console.WriteLine("Not keeping alive, will read until eof. Will hold, but currently fpc = " + fpc);
//fhold;
{cs = 133; if (true) goto _again;}
}

del.OnMessageEnd(this);
//fhold;
{cs = 133; if (true) goto _again;}
{cs = 1; if (true) goto _again;}
}
}
}
}
break;
case 29:
#line 272 "rl/HttpParser.cs.rl"
#line 280 "rl/HttpParser.cs.rl"
{
var toRead = Math.Min(pe - p, contentLength);
//Console.WriteLine("body_identity: reading " + toRead + " bytes from body.");
Expand Down Expand Up @@ -942,7 +950,7 @@ public int Execute(ArraySegment<byte> buf)
}
break;
case 30:
#line 305 "rl/HttpParser.cs.rl"
#line 313 "rl/HttpParser.cs.rl"
{
var toRead = pe - p;
//Console.WriteLine("body_identity_eof: reading " + toRead + " bytes from body.");
Expand All @@ -967,7 +975,7 @@ public int Execute(ArraySegment<byte> buf)
}
}
break;
#line 971 "HttpParser.cs"
#line 979 "HttpParser.cs"
default: break;
}
}
Expand All @@ -991,7 +999,7 @@ public int Execute(ArraySegment<byte> buf)
}
break;
case 30:
#line 305 "rl/HttpParser.cs.rl"
#line 313 "rl/HttpParser.cs.rl"
{
var toRead = pe - p;
//Console.WriteLine("body_identity_eof: reading " + toRead + " bytes from body.");
Expand All @@ -1016,7 +1024,7 @@ public int Execute(ArraySegment<byte> buf)
}
}
break;
#line 1020 "HttpParser.cs"
#line 1028 "HttpParser.cs"
default: break;
}
}
Expand All @@ -1025,7 +1033,7 @@ public int Execute(ArraySegment<byte> buf)
_out: {}
}

#line 359 "rl/HttpParser.cs.rl"
#line 367 "rl/HttpParser.cs.rl"

var result = p - buf.Offset;

Expand Down
14 changes: 11 additions & 3 deletions src/HttpMachine/rl/HttpParser.cs.rl
Expand Up @@ -236,7 +236,9 @@ namespace HttpMachine
// if content length is given and non-zero, we should read that many bytes
// if content length is not given
// if should keep alive, assume next request is coming and read it
// else read body until EOF
// else
// if chunked transfer read body until EOF
// else read next request

if (contentLength == 0)
{
Expand All @@ -261,9 +263,15 @@ namespace HttpMachine
}
else
{
//Console.WriteLine("Not keeping alive, will read until eof. Will hold, but currently fpc = " + fpc);
if (gotTransferEncodingChunked) {
//Console.WriteLine("Not keeping alive, will read until eof. Will hold, but currently fpc = " + fpc);
//fhold;
fgoto body_identity_eof;
}

del.OnMessageEnd(this);
//fhold;
fgoto body_identity_eof;
fgoto main;
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions tests/HttpMachine.Tests/HttpMachineTests.cs
Expand Up @@ -286,6 +286,12 @@ public void PostEof()
}

[Test]
public void PostNoContentLength()
{
PipelineAndScan("1.0 post no content length");
}

[Test]
public void Get()
{
PipelineAndScan("1.0 get");
Expand Down Expand Up @@ -464,9 +470,6 @@ static void ThreeChunkScan(IEnumerable<TestRequest> requests)
//Console.WriteLine("Parsing buffer 3.");
Assert.AreEqual(buffer3Length, parser.Execute(new ArraySegment<byte>(buffer3, 0, buffer3Length)), "Error parsing buffer 3.");

//Console.WriteLine("Parsing EOF");
Assert.AreEqual(parser.Execute(default(ArraySegment<byte>)), 0, "Error parsing EOF chunk.");

AssertRequest(requests.ToArray(), handler.Requests.ToArray(), parser);
}
}
Expand Down
19 changes: 18 additions & 1 deletion tests/HttpMachine.Tests/TestRequest.cs
Expand Up @@ -325,7 +325,7 @@ class TestRequest
},
new TestRequest() {
Name = "1.0 post",
Raw = Encoding.ASCII.GetBytes("POST /foo HTTP/1.0\r\nFoo: Bar\r\n\r\nhelloworldhello"),
Raw = Encoding.ASCII.GetBytes("POST /foo HTTP/1.0\r\nContent-Length: 15\r\nFoo: Bar\r\n\r\nhelloworldhello"),
Method = "POST",
RequestUri = "/foo",
RequestPath = "/foo",
Expand All @@ -334,12 +334,29 @@ class TestRequest
VersionMajor = 1,
VersionMinor = 0,
Headers = new Dictionary<string,string>(StringComparer.InvariantCultureIgnoreCase) {
{ "Content-Length", "15" },
{ "Foo", "Bar" }
},
Body = Encoding.UTF8.GetBytes("helloworldhello"),
ShouldKeepAlive = false
},
new TestRequest() {
Name = "1.0 post no content length",
Raw = Encoding.ASCII.GetBytes("POST /foo HTTP/1.0\r\nFoo: Bar\r\n\r\nhelloworldhello"),
Method = "POST",
RequestUri = "/foo",
RequestPath = "/foo",
QueryString = null,
Fragment = null,
VersionMajor = 1,
VersionMinor = 0,
Headers = new Dictionary<string,string>(StringComparer.InvariantCultureIgnoreCase) {
{ "Foo", "Bar" }
},
Body = null,
ShouldKeepAlive = false
},
new TestRequest() {
Name = "1.0 post keep-alive with content length",
Raw = Encoding.ASCII.GetBytes("POST /foo HTTP/1.0\r\nContent-Length: 15\r\nFoo: Bar\r\nConnection: keep-alive\r\n\r\nhelloworldhello"),
Method = "POST",
Expand Down

0 comments on commit 41e85f7

Please sign in to comment.