http_parser.rb 0.5.1-x86-mswin32-60 → 0.5.2-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/Gemfile.lock +16 -16
  2. data/LICENSE-MIT +20 -0
  3. data/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java +68 -11
  4. data/ext/ruby_http_parser/ruby_http_parser.c +74 -6
  5. data/ext/ruby_http_parser/vendor/http-parser-java/LICENSE-MIT +26 -1
  6. data/ext/ruby_http_parser/vendor/http-parser-java/README.md +23 -143
  7. data/ext/ruby_http_parser/vendor/http-parser-java/TODO +3 -0
  8. data/ext/ruby_http_parser/vendor/http-parser-java/build.xml +74 -0
  9. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.c +115 -61
  10. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.h +19 -3
  11. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPCallback.java +8 -0
  12. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPDataCallback.java +34 -0
  13. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPErrorCallback.java +12 -0
  14. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPException.java +4 -2
  15. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java +64 -52
  16. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParser.java +5 -0
  17. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserSettings.java +323 -0
  18. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/{lolevel/Util.java → Util.java} +27 -28
  19. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java +259 -85
  20. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java +1 -0
  21. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Message.java +324 -0
  22. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Requests.java +69 -0
  23. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Responses.java +51 -0
  24. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Test.java +15 -0
  25. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestHeaderOverflowError.java +47 -0
  26. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestLoaderNG.java +183 -447
  27. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestNoOverflowLongBody.java +61 -0
  28. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/UnitTest.java +2 -1
  29. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Upgrade.java +26 -0
  30. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Util.java +165 -0
  31. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/WrongContentLength.java +58 -0
  32. data/ext/ruby_http_parser/vendor/http-parser-java/test.c +232 -29
  33. data/ext/ruby_http_parser/vendor/http-parser-java/test_permutations +1 -1
  34. data/ext/ruby_http_parser/vendor/http-parser-java/test_unit +1 -1
  35. data/ext/ruby_http_parser/vendor/http-parser-java/test_utf8 +1 -0
  36. data/ext/ruby_http_parser/vendor/http-parser-java/tests.dumped +154 -7
  37. data/ext/ruby_http_parser/vendor/http-parser-java/tests.utf8 +17 -0
  38. data/ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT +1 -1
  39. data/ext/ruby_http_parser/vendor/http-parser/http_parser.c +52 -10
  40. data/ext/ruby_http_parser/vendor/http-parser/http_parser.h +3 -1
  41. data/ext/ruby_http_parser/vendor/http-parser/test.c +89 -3
  42. data/http_parser.rb.gemspec +8 -2
  43. data/lib/http_parser.rb +17 -0
  44. data/spec/parser_spec.rb +97 -6
  45. data/tasks/compile.rake +3 -1
  46. metadata +83 -20
  47. data/ext/ruby_http_parser/vendor/http-parser-java/CONTRIBUTIONS +0 -4
@@ -1,3 +1,6 @@
1
+ some tests from test.c left to port
2
+ documentation
3
+
1
4
  hi level callback interface
2
5
  eventloop
3
6
  state() as a function (?)
@@ -0,0 +1,74 @@
1
+ <?xml version="1.0"?>
2
+
3
+ <project name="http-parser" default="compile" basedir=".">
4
+
5
+ <echo message="pulling in property files"/>
6
+ <property file="build.properties"/>
7
+ <property name="classes.dir" value="classes"/>
8
+ <property name="assemble.dir" value="assemble"/>
9
+ <property name="lib.dir" value="lib"/>
10
+
11
+
12
+
13
+ <target name="prepare">
14
+ <mkdir dir="${classes.dir}" />
15
+ <mkdir dir="${assemble.dir}" />
16
+ <mkdir dir="${lib.dir}" />
17
+ </target>
18
+
19
+ <target name="clean">
20
+ <delete dir="${classes.dir}"/>
21
+ <delete dir="lib"/>
22
+ <delete dir="doc"/>
23
+ <delete dir="${assemble.dir}"/>
24
+ </target>
25
+
26
+ <target name="compile" depends="prepare">
27
+ <javac srcdir="src" destdir="${classes.dir}" debug='true'>
28
+ <classpath>
29
+ <pathelement path="${classpath}"/>
30
+ <pathelement location="ext/http-parser.jar"/>
31
+ <pathelement location="ext/primitives.jar"/>
32
+ </classpath>
33
+ </javac>
34
+ </target>
35
+
36
+ <target name="jar" depends="compile">
37
+ <copy todir="${assemble.dir}">
38
+ <fileset dir="classes"/>
39
+ </copy>
40
+ <jar basedir="${assemble.dir}" destfile="lib/${ant.project.name}.jar"/>
41
+ </target>
42
+
43
+ <target name="run" depends="jar">
44
+ <echo message="don't know how to run"/>
45
+ </target>
46
+
47
+ <target name="doc" depends="prepare">
48
+ <javadoc sourcepath="src/impl" destdir="doc">
49
+ </javadoc>
50
+ </target>
51
+
52
+ <target name="test_permutations" depends="compile">
53
+ <java classname="http_parser.lolevel.TestLoaderNG">
54
+ <arg value="tests.dumped"/>
55
+ <classpath>
56
+ <pathelement location="classes/"/>
57
+ <pathelement location="ext/primitives.jar/"/>
58
+ </classpath>
59
+ </java>
60
+ </target>
61
+
62
+ <target name="test_unit" depends="compile">
63
+ <java classname="http_parser.lolevel.Test">
64
+ <arg value="tests.dumped"/>
65
+ <classpath>
66
+ <pathelement location="classes/"/>
67
+ <pathelement location="ext/primitives.jar/"/>
68
+ </classpath>
69
+ </java>
70
+ </target>
71
+
72
+ <target name="test" depends="test_permutations, test_unit"/>
73
+
74
+ </project>
@@ -1,4 +1,4 @@
1
- /* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
1
+ /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
2
  *
3
3
  * Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  * of this software and associated documentation files (the "Software"), to
@@ -19,16 +19,6 @@
19
19
  * IN THE SOFTWARE.
20
20
  */
21
21
  #include <http_parser.h>
22
- #ifdef _WIN32
23
- typedef __int8 int8_t;
24
- typedef unsigned __int8 uint8_t;
25
- typedef __int16 int16_t;
26
- typedef unsigned __int16 uint16_t;
27
- typedef __int16 int32_t;
28
- typedef unsigned __int32 uint32_t;
29
- #else
30
- #include <stdint.h>
31
- #endif
32
22
  #include <assert.h>
33
23
  #include <stddef.h>
34
24
 
@@ -103,12 +93,21 @@ static const char *method_strings[] =
103
93
  , "MKACTIVITY"
104
94
  , "CHECKOUT"
105
95
  , "MERGE"
96
+ , "M-SEARCH"
97
+ , "NOTIFY"
98
+ , "SUBSCRIBE"
99
+ , "UNSUBSCRIBE"
106
100
  };
107
101
 
108
102
 
109
- /* ' ', '_', '-' and all alpha-numeric ascii characters are accepted by acceptable_header.
110
- The 'A'-'Z' are lower-cased. */
111
- static const char acceptable_header[256] = {
103
+ /* Tokens as defined by rfc 2616. Also lowercases them.
104
+ * token = 1*<any CHAR except CTLs or separators>
105
+ * separators = "(" | ")" | "<" | ">" | "@"
106
+ * | "," | ";" | ":" | "\" | <">
107
+ * | "/" | "[" | "]" | "?" | "="
108
+ * | "{" | "}" | SP | HT
109
+ */
110
+ static const char tokens[256] = {
112
111
  /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */
113
112
  0, 0, 0, 0, 0, 0, 0, 0,
114
113
  /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */
@@ -118,9 +117,9 @@ static const char acceptable_header[256] = {
118
117
  /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
119
118
  0, 0, 0, 0, 0, 0, 0, 0,
120
119
  /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
121
- ' ', 0, 0, 0, 0, 0, 0, 0,
120
+ ' ', '!', '"', '#', '$', '%', '&', '\'',
122
121
  /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
123
- 0, 0, 0, 0, 0, '-', 0, 0,
122
+ 0, 0, '*', '+', 0, '-', '.', '/',
124
123
  /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
125
124
  '0', '1', '2', '3', '4', '5', '6', '7',
126
125
  /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */
@@ -132,15 +131,15 @@ static const char acceptable_header[256] = {
132
131
  /* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */
133
132
  'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
134
133
  /* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */
135
- 'x', 'y', 'z', 0, 0, 0, 0, '_',
134
+ 'x', 'y', 'z', 0, 0, 0, '^', '_',
136
135
  /* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */
137
- 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
136
+ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
138
137
  /* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */
139
138
  'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
140
139
  /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
141
140
  'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
142
141
  /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
143
- 'x', 'y', 'z', 0, 0, 0, 0, 0 };
142
+ 'x', 'y', 'z', 0, '|', '}', '~', 0 };
144
143
 
145
144
 
146
145
  static const int8_t unhex[256] =
@@ -187,7 +186,28 @@ static const uint8_t normal_url_char[256] = {
187
186
  /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
188
187
  1, 1, 1, 1, 1, 1, 1, 1,
189
188
  /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
190
- 1, 1, 1, 1, 1, 1, 1, 0 };
189
+ 1, 1, 1, 1, 1, 1, 1, 0,
190
+
191
+ /* Remainder of non-ASCII range are accepted as-is to support implicitly UTF-8
192
+ encoded paths. This is out of spec, but clients generate this and most other
193
+ HTTP servers support it. We should, too. */
194
+
195
+ 1, 1, 1, 1, 1, 1, 1, 1,
196
+ 1, 1, 1, 1, 1, 1, 1, 1,
197
+ 1, 1, 1, 1, 1, 1, 1, 1,
198
+ 1, 1, 1, 1, 1, 1, 1, 1,
199
+ 1, 1, 1, 1, 1, 1, 1, 1,
200
+ 1, 1, 1, 1, 1, 1, 1, 1,
201
+ 1, 1, 1, 1, 1, 1, 1, 1,
202
+ 1, 1, 1, 1, 1, 1, 1, 1,
203
+ 1, 1, 1, 1, 1, 1, 1, 1,
204
+ 1, 1, 1, 1, 1, 1, 1, 1,
205
+ 1, 1, 1, 1, 1, 1, 1, 1,
206
+ 1, 1, 1, 1, 1, 1, 1, 1,
207
+ 1, 1, 1, 1, 1, 1, 1, 1,
208
+ 1, 1, 1, 1, 1, 1, 1, 1,
209
+ 1, 1, 1, 1, 1, 1, 1, 1,
210
+ 1, 1, 1, 1, 1, 1, 1, 1 };
191
211
 
192
212
 
193
213
  enum state
@@ -241,15 +261,17 @@ enum state
241
261
 
242
262
  , s_header_almost_done
243
263
 
264
+ , s_chunk_size_start
265
+ , s_chunk_size
266
+ , s_chunk_parameters
267
+ , s_chunk_size_almost_done
268
+
244
269
  , s_headers_almost_done
245
270
  /* Important: 's_headers_almost_done' must be the last 'header' state. All
246
271
  * states beyond this must be 'body' states. It is used for overflow
247
272
  * checking. See the PARSING_HEADER() macro.
248
273
  */
249
- , s_chunk_size_start
250
- , s_chunk_size
251
- , s_chunk_size_almost_done
252
- , s_chunk_parameters
274
+
253
275
  , s_chunk_data
254
276
  , s_chunk_data_almost_done
255
277
  , s_chunk_data_done
@@ -259,7 +281,7 @@ enum state
259
281
  };
260
282
 
261
283
 
262
- #define PARSING_HEADER(state) (state <= s_headers_almost_done && 0 == (parser->flags & F_TRAILING))
284
+ #define PARSING_HEADER(state) (state <= s_headers_almost_done)
263
285
 
264
286
 
265
287
  enum header_states
@@ -302,6 +324,7 @@ enum flags
302
324
  #define CR '\r'
303
325
  #define LF '\n'
304
326
  #define LOWER(c) (unsigned char)(c | 0x20)
327
+ #define TOKEN(c) tokens[(unsigned char)c]
305
328
 
306
329
 
307
330
  #define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res)
@@ -331,10 +354,20 @@ size_t http_parser_execute (http_parser *parser,
331
354
  uint64_t nread = parser->nread;
332
355
 
333
356
  if (len == 0) {
334
- if (state == s_body_identity_eof) {
335
- CALLBACK2(message_complete);
357
+ switch (state) {
358
+ case s_body_identity_eof:
359
+ CALLBACK2(message_complete);
360
+ return 0;
361
+
362
+ case s_dead:
363
+ case s_start_req_or_res:
364
+ case s_start_res:
365
+ case s_start_req:
366
+ return 0;
367
+
368
+ default:
369
+ return 1; // error
336
370
  }
337
- return 0;
338
371
  }
339
372
 
340
373
  /* technically we could combine all of these (except for url_mark) into one
@@ -579,12 +612,14 @@ size_t http_parser_execute (http_parser *parser,
579
612
  case 'G': parser->method = HTTP_GET; break;
580
613
  case 'H': parser->method = HTTP_HEAD; break;
581
614
  case 'L': parser->method = HTTP_LOCK; break;
582
- case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE */ break;
615
+ case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break;
616
+ case 'N': parser->method = HTTP_NOTIFY; break;
583
617
  case 'O': parser->method = HTTP_OPTIONS; break;
584
618
  case 'P': parser->method = HTTP_POST; /* or PROPFIND or PROPPATCH or PUT */ break;
585
619
  case 'R': parser->method = HTTP_REPORT; break;
620
+ case 'S': parser->method = HTTP_SUBSCRIBE; break;
586
621
  case 'T': parser->method = HTTP_TRACE; break;
587
- case 'U': parser->method = HTTP_UNLOCK; break;
622
+ case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break;
588
623
  default: goto error;
589
624
  }
590
625
  state = s_req_method;
@@ -612,6 +647,8 @@ size_t http_parser_execute (http_parser *parser,
612
647
  parser->method = HTTP_MOVE;
613
648
  } else if (index == 1 && ch == 'E') {
614
649
  parser->method = HTTP_MERGE;
650
+ } else if (index == 1 && ch == '-') {
651
+ parser->method = HTTP_MSEARCH;
615
652
  } else if (index == 2 && ch == 'A') {
616
653
  parser->method = HTTP_MKACTIVITY;
617
654
  }
@@ -619,6 +656,8 @@ size_t http_parser_execute (http_parser *parser,
619
656
  parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */
620
657
  } else if (index == 1 && parser->method == HTTP_POST && ch == 'U') {
621
658
  parser->method = HTTP_PUT;
659
+ } else if (index == 2 && parser->method == HTTP_UNLOCK && ch == 'S') {
660
+ parser->method = HTTP_UNSUBSCRIBE;
622
661
  } else if (index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') {
623
662
  parser->method = HTTP_PROPPATCH;
624
663
  } else {
@@ -632,7 +671,7 @@ size_t http_parser_execute (http_parser *parser,
632
671
  {
633
672
  if (ch == ' ') break;
634
673
 
635
- if (ch == '/') {
674
+ if (ch == '/' || ch == '*') {
636
675
  MARK(url);
637
676
  MARK(path);
638
677
  state = s_req_path;
@@ -662,6 +701,9 @@ size_t http_parser_execute (http_parser *parser,
662
701
  } else if (ch == '.') {
663
702
  state = s_req_host;
664
703
  break;
704
+ } else if ('0' <= ch && ch <= '9') {
705
+ state = s_req_host;
706
+ break;
665
707
  }
666
708
 
667
709
  goto error;
@@ -698,6 +740,9 @@ size_t http_parser_execute (http_parser *parser,
698
740
  CALLBACK(url);
699
741
  state = s_req_http_start;
700
742
  break;
743
+ case '?':
744
+ state = s_req_query_string_start;
745
+ break;
701
746
  default:
702
747
  goto error;
703
748
  }
@@ -720,6 +765,9 @@ size_t http_parser_execute (http_parser *parser,
720
765
  CALLBACK(url);
721
766
  state = s_req_http_start;
722
767
  break;
768
+ case '?':
769
+ state = s_req_query_string_start;
770
+ break;
723
771
  default:
724
772
  goto error;
725
773
  }
@@ -739,12 +787,14 @@ size_t http_parser_execute (http_parser *parser,
739
787
  case CR:
740
788
  CALLBACK(url);
741
789
  CALLBACK(path);
790
+ parser->http_major = 0;
742
791
  parser->http_minor = 9;
743
792
  state = s_req_line_almost_done;
744
793
  break;
745
794
  case LF:
746
795
  CALLBACK(url);
747
796
  CALLBACK(path);
797
+ parser->http_major = 0;
748
798
  parser->http_minor = 9;
749
799
  state = s_header_field_start;
750
800
  break;
@@ -779,11 +829,13 @@ size_t http_parser_execute (http_parser *parser,
779
829
  break;
780
830
  case CR:
781
831
  CALLBACK(url);
832
+ parser->http_major = 0;
782
833
  parser->http_minor = 9;
783
834
  state = s_req_line_almost_done;
784
835
  break;
785
836
  case LF:
786
837
  CALLBACK(url);
838
+ parser->http_major = 0;
787
839
  parser->http_minor = 9;
788
840
  state = s_header_field_start;
789
841
  break;
@@ -812,12 +864,14 @@ size_t http_parser_execute (http_parser *parser,
812
864
  case CR:
813
865
  CALLBACK(url);
814
866
  CALLBACK(query_string);
867
+ parser->http_major = 0;
815
868
  parser->http_minor = 9;
816
869
  state = s_req_line_almost_done;
817
870
  break;
818
871
  case LF:
819
872
  CALLBACK(url);
820
873
  CALLBACK(query_string);
874
+ parser->http_major = 0;
821
875
  parser->http_minor = 9;
822
876
  state = s_header_field_start;
823
877
  break;
@@ -846,11 +900,13 @@ size_t http_parser_execute (http_parser *parser,
846
900
  break;
847
901
  case CR:
848
902
  CALLBACK(url);
903
+ parser->http_major = 0;
849
904
  parser->http_minor = 9;
850
905
  state = s_req_line_almost_done;
851
906
  break;
852
907
  case LF:
853
908
  CALLBACK(url);
909
+ parser->http_major = 0;
854
910
  parser->http_minor = 9;
855
911
  state = s_header_field_start;
856
912
  break;
@@ -879,12 +935,14 @@ size_t http_parser_execute (http_parser *parser,
879
935
  case CR:
880
936
  CALLBACK(url);
881
937
  CALLBACK(fragment);
938
+ parser->http_major = 0;
882
939
  parser->http_minor = 9;
883
940
  state = s_req_line_almost_done;
884
941
  break;
885
942
  case LF:
886
943
  CALLBACK(url);
887
944
  CALLBACK(fragment);
945
+ parser->http_major = 0;
888
946
  parser->http_minor = 9;
889
947
  state = s_header_field_start;
890
948
  break;
@@ -1006,9 +1064,9 @@ size_t http_parser_execute (http_parser *parser,
1006
1064
  goto headers_almost_done;
1007
1065
  }
1008
1066
 
1009
- c = LOWER(ch);
1067
+ c = TOKEN(ch);
1010
1068
 
1011
- if (c < 'a' || 'z' < c) goto error;
1069
+ if (!c) goto error;
1012
1070
 
1013
1071
  MARK(header_field);
1014
1072
 
@@ -1041,7 +1099,7 @@ size_t http_parser_execute (http_parser *parser,
1041
1099
 
1042
1100
  case s_header_field:
1043
1101
  {
1044
- c = acceptable_header[(unsigned char)ch];
1102
+ c = TOKEN(ch);
1045
1103
 
1046
1104
  if (c) {
1047
1105
  switch (header_state) {
@@ -1177,23 +1235,18 @@ size_t http_parser_execute (http_parser *parser,
1177
1235
  state = s_header_value;
1178
1236
  index = 0;
1179
1237
 
1180
- c = acceptable_header[(unsigned char)ch];
1181
-
1182
- if (!c) {
1183
- if (ch == CR) {
1184
- CALLBACK(header_value);
1185
- header_state = h_general;
1186
- state = s_header_almost_done;
1187
- break;
1188
- }
1189
-
1190
- if (ch == LF) {
1191
- CALLBACK(header_value);
1192
- state = s_header_field_start;
1193
- break;
1194
- }
1238
+ c = LOWER(ch);
1195
1239
 
1240
+ if (ch == CR) {
1241
+ CALLBACK(header_value);
1196
1242
  header_state = h_general;
1243
+ state = s_header_almost_done;
1244
+ break;
1245
+ }
1246
+
1247
+ if (ch == LF) {
1248
+ CALLBACK(header_value);
1249
+ state = s_header_field_start;
1197
1250
  break;
1198
1251
  }
1199
1252
 
@@ -1238,22 +1291,19 @@ size_t http_parser_execute (http_parser *parser,
1238
1291
 
1239
1292
  case s_header_value:
1240
1293
  {
1241
- c = acceptable_header[(unsigned char)ch];
1242
-
1243
- if (!c) {
1244
- if (ch == CR) {
1245
- CALLBACK(header_value);
1246
- state = s_header_almost_done;
1247
- break;
1248
- }
1294
+ c = LOWER(ch);
1249
1295
 
1250
- if (ch == LF) {
1251
- CALLBACK(header_value);
1252
- goto header_almost_done;
1253
- }
1296
+ if (ch == CR) {
1297
+ CALLBACK(header_value);
1298
+ state = s_header_almost_done;
1254
1299
  break;
1255
1300
  }
1256
1301
 
1302
+ if (ch == LF) {
1303
+ CALLBACK(header_value);
1304
+ goto header_almost_done;
1305
+ }
1306
+
1257
1307
  switch (header_state) {
1258
1308
  case h_general:
1259
1309
  break;
@@ -1373,6 +1423,7 @@ size_t http_parser_execute (http_parser *parser,
1373
1423
  break;
1374
1424
 
1375
1425
  default:
1426
+ parser->state = state;
1376
1427
  return p - data; /* Error */
1377
1428
  }
1378
1429
  }
@@ -1436,6 +1487,7 @@ size_t http_parser_execute (http_parser *parser,
1436
1487
 
1437
1488
  case s_chunk_size_start:
1438
1489
  {
1490
+ assert(nread == 1);
1439
1491
  assert(parser->flags & F_CHUNKED);
1440
1492
 
1441
1493
  c = unhex[(unsigned char)ch];
@@ -1485,6 +1537,8 @@ size_t http_parser_execute (http_parser *parser,
1485
1537
  assert(parser->flags & F_CHUNKED);
1486
1538
  STRICT_CHECK(ch != LF);
1487
1539
 
1540
+ nread = 0;
1541
+
1488
1542
  if (parser->content_length == 0) {
1489
1543
  parser->flags |= F_TRAILING;
1490
1544
  state = s_header_field_start;