em-http-request 0.3.0 → 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of em-http-request might be problematic. Click here for more details.

Files changed (44) hide show
  1. data/.gitignore +1 -0
  2. data/Changelog.md +10 -0
  3. data/README.md +43 -160
  4. data/Rakefile +2 -73
  5. data/em-http-request.gemspec +7 -7
  6. data/examples/fetch.rb +30 -30
  7. data/examples/fibered-http.rb +38 -38
  8. data/examples/oauth-tweet.rb +49 -49
  9. data/lib/em-http.rb +4 -6
  10. data/lib/em-http/client.rb +101 -522
  11. data/lib/em-http/http_connection.rb +125 -0
  12. data/lib/em-http/http_encoding.rb +19 -12
  13. data/lib/em-http/http_header.rb +2 -17
  14. data/lib/em-http/http_options.rb +37 -19
  15. data/lib/em-http/request.rb +33 -66
  16. data/lib/em-http/version.rb +2 -2
  17. data/spec/client_spec.rb +575 -0
  18. data/spec/dns_spec.rb +41 -0
  19. data/spec/encoding_spec.rb +6 -6
  20. data/spec/external_spec.rb +99 -0
  21. data/spec/fixtures/google.ca +13 -17
  22. data/spec/helper.rb +17 -8
  23. data/spec/http_proxy_spec.rb +53 -0
  24. data/spec/middleware_spec.rb +114 -0
  25. data/spec/multi_spec.rb +11 -38
  26. data/spec/pipelining_spec.rb +38 -0
  27. data/spec/redirect_spec.rb +114 -0
  28. data/spec/socksify_proxy_spec.rb +24 -0
  29. data/spec/ssl_spec.rb +20 -0
  30. data/spec/stallion.rb +7 -63
  31. metadata +59 -39
  32. data/examples/websocket-handler.rb +0 -28
  33. data/examples/websocket-server.rb +0 -8
  34. data/ext/buffer/em_buffer.c +0 -639
  35. data/ext/buffer/extconf.rb +0 -53
  36. data/ext/http11_client/ext_help.h +0 -14
  37. data/ext/http11_client/extconf.rb +0 -6
  38. data/ext/http11_client/http11_client.c +0 -328
  39. data/ext/http11_client/http11_parser.c +0 -418
  40. data/ext/http11_client/http11_parser.h +0 -48
  41. data/ext/http11_client/http11_parser.rl +0 -170
  42. data/lib/em-http/mock.rb +0 -137
  43. data/spec/mock_spec.rb +0 -166
  44. data/spec/request_spec.rb +0 -1003
@@ -1,53 +0,0 @@
1
- require 'mkmf'
2
-
3
- libs = []
4
-
5
- $defs << "-DRUBY_VERSION_CODE=#{RUBY_VERSION.gsub(/\D/, '')}"
6
-
7
- if have_func('rb_thread_blocking_region')
8
- $defs << '-DHAVE_RB_THREAD_BLOCKING_REGION'
9
- end
10
-
11
- if have_func('rb_str_set_len')
12
- $defs << '-DHAVE_RB_STR_SET_LEN'
13
- end
14
-
15
- if have_header('sys/select.h')
16
- $defs << '-DEV_USE_SELECT'
17
- end
18
-
19
- if have_header('poll.h')
20
- $defs << '-DEV_USE_POLL'
21
- end
22
-
23
- if have_header('sys/epoll.h')
24
- $defs << '-DEV_USE_EPOLL'
25
- end
26
-
27
- if have_header('sys/event.h') and have_header('sys/queue.h')
28
- $defs << '-DEV_USE_KQUEUE'
29
- end
30
-
31
- if have_header('port.h')
32
- $defs << '-DEV_USE_PORT'
33
- end
34
-
35
- if have_header('openssl/ssl.h')
36
- $defs << '-DHAVE_OPENSSL_SSL_H'
37
- libs << '-lssl -lcrypto'
38
- end
39
-
40
- # ncpu detection specifics
41
- case RUBY_PLATFORM
42
- when /linux/
43
- $defs << '-DHAVE_LINUX_PROCFS'
44
- else
45
- if have_func('sysctlbyname', ['sys/param.h', 'sys/sysctl.h'])
46
- $defs << '-DHAVE_SYSCTLBYNAME'
47
- end
48
- end
49
-
50
- $LIBS << ' ' << libs.join(' ')
51
-
52
- dir_config('em_buffer')
53
- create_makefile('em_buffer')
@@ -1,14 +0,0 @@
1
- #ifndef ext_help_h
2
- #define ext_help_h
3
-
4
- #define RAISE_NOT_NULL(T) if(T == NULL) rb_raise(rb_eArgError, "NULL found for " # T " when shouldn't be.");
5
- #define DATA_GET(from,type,name) Data_Get_Struct(from,type,name); RAISE_NOT_NULL(name);
6
- #define REQUIRE_TYPE(V, T) if(TYPE(V) != T) rb_raise(rb_eTypeError, "Wrong argument type for " # V " required " # T);
7
-
8
- #ifdef DEBUG
9
- #define TRACE() fprintf(stderr, "> %s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__)
10
- #else
11
- #define TRACE()
12
- #endif
13
-
14
- #endif
@@ -1,6 +0,0 @@
1
- require 'mkmf'
2
-
3
- dir_config("http11_client")
4
- have_library("c", "main")
5
-
6
- create_makefile("http11_client")
@@ -1,328 +0,0 @@
1
- /**
2
- * Copyright (c) 2005 Zed A. Shaw
3
- * You can redistribute it and/or modify it under the same terms as Ruby.
4
- */
5
-
6
- #include "ruby.h"
7
- #include "ext_help.h"
8
- #include <assert.h>
9
- #include <string.h>
10
- #include "http11_parser.h"
11
- #include <ctype.h>
12
-
13
- static VALUE mEm;
14
- static VALUE cHttpClientParser;
15
- static VALUE eHttpClientParserError;
16
-
17
- #define id_reason rb_intern("@http_reason")
18
- #define id_status rb_intern("@http_status")
19
- #define id_version rb_intern("@http_version")
20
- #define id_body rb_intern("@http_body")
21
- #define id_chunk_size rb_intern("@http_chunk_size")
22
- #define id_last_chunk rb_intern("@last_chunk")
23
-
24
- #ifndef RHASH_TBL
25
- /* rb_hash_lookup() is only in Ruby 1.8.7 */
26
- static VALUE rb_hash_lookup(VALUE hash, VALUE key)
27
- {
28
- VALUE val;
29
-
30
- if (!st_lookup(RHASH(hash)->tbl, key, &val)) {
31
- return Qnil; /* without Hash#default */
32
- }
33
-
34
- return val;
35
- }
36
- #endif
37
-
38
- void client_http_field(void *data, const char *field, size_t flen, const char *value, size_t vlen)
39
- {
40
- char *ch, *end;
41
- VALUE req = (VALUE)data;
42
- VALUE v = Qnil;
43
- VALUE f = Qnil;
44
- VALUE el = Qnil;
45
-
46
- v = rb_str_new(value, vlen);
47
- f = rb_str_new(field, flen);
48
-
49
- /* Yes Children, rb_str_upcase_bang isn't even available as an intern.h function.
50
- * how incredibly handy to not have that. Nope, I have to do it by hand.*/
51
- for(ch = RSTRING_PTR(f), end = ch + RSTRING_LEN(f); ch < end; ch++) {
52
- if(*ch == '-') {
53
- *ch = '_';
54
- } else {
55
- *ch = toupper(*ch);
56
- }
57
- }
58
-
59
- el = rb_hash_lookup(req, f);
60
- switch(TYPE(el)) {
61
- case T_ARRAY:
62
- rb_ary_push(el, v);
63
- break;
64
- case T_STRING:
65
- rb_hash_aset(req, f, rb_ary_new3(2, el, v));
66
- break;
67
- default:
68
- rb_hash_aset(req, f, v);
69
- break;
70
- }
71
- }
72
-
73
- void client_reason_phrase(void *data, const char *at, size_t length)
74
- {
75
- VALUE req = (VALUE)data;
76
- VALUE v = Qnil;
77
-
78
- v = rb_str_new(at, length);
79
-
80
- rb_ivar_set(req, id_reason, v);
81
- }
82
-
83
- void client_status_code(void *data, const char *at, size_t length)
84
- {
85
- VALUE req = (VALUE)data;
86
- VALUE v = Qnil;
87
-
88
- v = rb_str_new(at, length);
89
-
90
- rb_ivar_set(req, id_status, v);
91
- }
92
-
93
- void client_http_version(void *data, const char *at, size_t length)
94
- {
95
- VALUE req = (VALUE)data;
96
- VALUE v = Qnil;
97
-
98
- v = rb_str_new(at, length);
99
-
100
- rb_ivar_set(req, id_version, v);
101
- }
102
-
103
- /** Finalizes the request header to have a bunch of stuff that's
104
- needed. */
105
- void client_header_done(void *data, const char *at, size_t length)
106
- {
107
- VALUE req = (VALUE)data;
108
- VALUE v = Qnil;
109
-
110
- v = rb_str_new(at, length);
111
- rb_ivar_set(req, id_body, v);
112
- }
113
-
114
- void client_chunk_size(void *data, const char *at, size_t length)
115
- {
116
- VALUE req = (VALUE)data;
117
- VALUE v = Qnil;
118
-
119
- if(length <= 0) {
120
- rb_raise(eHttpClientParserError, "Chunked Encoding gave <= 0 chunk size.");
121
- }
122
-
123
- v = rb_str_new(at, length);
124
-
125
- rb_ivar_set(req, id_chunk_size, v);
126
- }
127
-
128
- void client_last_chunk(void *data, const char *at, size_t length) {
129
- VALUE req = (VALUE)data;
130
- rb_ivar_set(req, id_last_chunk,Qtrue);
131
- }
132
-
133
-
134
- void HttpClientParser_free(void *data) {
135
- TRACE();
136
-
137
- if(data) {
138
- free(data);
139
- }
140
- }
141
-
142
-
143
- VALUE HttpClientParser_alloc(VALUE klass)
144
- {
145
- VALUE obj;
146
- httpclient_parser *hp = ALLOC_N(httpclient_parser, 1);
147
- TRACE();
148
- hp->http_field = client_http_field;
149
- hp->status_code = client_status_code;
150
- hp->reason_phrase = client_reason_phrase;
151
- hp->http_version = client_http_version;
152
- hp->header_done = client_header_done;
153
- hp->chunk_size = client_chunk_size;
154
- hp->last_chunk = client_last_chunk;
155
- httpclient_parser_init(hp);
156
-
157
- obj = Data_Wrap_Struct(klass, NULL, HttpClientParser_free, hp);
158
-
159
- return obj;
160
- }
161
-
162
-
163
- /**
164
- * call-seq:
165
- * parser.new -> parser
166
- *
167
- * Creates a new parser.
168
- */
169
- VALUE HttpClientParser_init(VALUE self)
170
- {
171
- httpclient_parser *http = NULL;
172
- DATA_GET(self, httpclient_parser, http);
173
- httpclient_parser_init(http);
174
-
175
- return self;
176
- }
177
-
178
-
179
- /**
180
- * call-seq:
181
- * parser.reset -> nil
182
- *
183
- * Resets the parser to it's initial state so that you can reuse it
184
- * rather than making new ones.
185
- */
186
- VALUE HttpClientParser_reset(VALUE self)
187
- {
188
- httpclient_parser *http = NULL;
189
- DATA_GET(self, httpclient_parser, http);
190
- httpclient_parser_init(http);
191
-
192
- return Qnil;
193
- }
194
-
195
-
196
- /**
197
- * call-seq:
198
- * parser.finish -> true/false
199
- *
200
- * Finishes a parser early which could put in a "good" or bad state.
201
- * You should call reset after finish it or bad things will happen.
202
- */
203
- VALUE HttpClientParser_finish(VALUE self)
204
- {
205
- httpclient_parser *http = NULL;
206
- DATA_GET(self, httpclient_parser, http);
207
- httpclient_parser_finish(http);
208
-
209
- return httpclient_parser_is_finished(http) ? Qtrue : Qfalse;
210
- }
211
-
212
-
213
- /**
214
- * call-seq:
215
- * parser.execute(req_hash, data, start) -> Integer
216
- *
217
- * Takes a Hash and a String of data, parses the String of data filling in the Hash
218
- * returning an Integer to indicate how much of the data has been read. No matter
219
- * what the return value, you should call HttpClientParser#finished? and HttpClientParser#error?
220
- * to figure out if it's done parsing or there was an error.
221
- *
222
- * This function now throws an exception when there is a parsing error. This makes
223
- * the logic for working with the parser much easier. You can still test for an
224
- * error, but now you need to wrap the parser with an exception handling block.
225
- *
226
- * The third argument allows for parsing a partial request and then continuing
227
- * the parsing from that position. It needs all of the original data as well
228
- * so you have to append to the data buffer as you read.
229
- */
230
- VALUE HttpClientParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
231
- {
232
- httpclient_parser *http = NULL;
233
- int from = 0;
234
- char *dptr = NULL;
235
- long dlen = 0;
236
-
237
- REQUIRE_TYPE(req_hash, T_HASH);
238
- REQUIRE_TYPE(data, T_STRING);
239
- REQUIRE_TYPE(start, T_FIXNUM);
240
-
241
- DATA_GET(self, httpclient_parser, http);
242
-
243
- from = FIX2INT(start);
244
- dptr = RSTRING_PTR(data);
245
- dlen = RSTRING_LEN(data);
246
-
247
- if(from >= dlen) {
248
- rb_raise(eHttpClientParserError, "Requested start is after data buffer end.");
249
- } else {
250
- http->data = (void *)req_hash;
251
- httpclient_parser_execute(http, dptr, dlen, from);
252
-
253
- if(httpclient_parser_has_error(http)) {
254
- rb_raise(eHttpClientParserError, "Invalid HTTP format, parsing fails.");
255
- } else {
256
- return INT2FIX(httpclient_parser_nread(http));
257
- }
258
- }
259
- }
260
-
261
-
262
-
263
- /**
264
- * call-seq:
265
- * parser.error? -> true/false
266
- *
267
- * Tells you whether the parser is in an error state.
268
- */
269
- VALUE HttpClientParser_has_error(VALUE self)
270
- {
271
- httpclient_parser *http = NULL;
272
- DATA_GET(self, httpclient_parser, http);
273
-
274
- return httpclient_parser_has_error(http) ? Qtrue : Qfalse;
275
- }
276
-
277
-
278
- /**
279
- * call-seq:
280
- * parser.finished? -> true/false
281
- *
282
- * Tells you whether the parser is finished or not and in a good state.
283
- */
284
- VALUE HttpClientParser_is_finished(VALUE self)
285
- {
286
- httpclient_parser *http = NULL;
287
- DATA_GET(self, httpclient_parser, http);
288
-
289
- return httpclient_parser_is_finished(http) ? Qtrue : Qfalse;
290
- }
291
-
292
-
293
- /**
294
- * call-seq:
295
- * parser.nread -> Integer
296
- *
297
- * Returns the amount of data processed so far during this processing cycle. It is
298
- * set to 0 on initialize or reset calls and is incremented each time execute is called.
299
- */
300
- VALUE HttpClientParser_nread(VALUE self)
301
- {
302
- httpclient_parser *http = NULL;
303
- DATA_GET(self, httpclient_parser, http);
304
-
305
- return INT2FIX(http->nread);
306
- }
307
-
308
-
309
-
310
- void Init_http11_client()
311
- {
312
-
313
- mEm = rb_define_module("EventMachine");
314
-
315
- eHttpClientParserError = rb_define_class_under(mEm, "HttpClientParserError", rb_eIOError);
316
-
317
- cHttpClientParser = rb_define_class_under(mEm, "HttpClientParser", rb_cObject);
318
- rb_define_alloc_func(cHttpClientParser, HttpClientParser_alloc);
319
- rb_define_method(cHttpClientParser, "initialize", HttpClientParser_init,0);
320
- rb_define_method(cHttpClientParser, "reset", HttpClientParser_reset,0);
321
- rb_define_method(cHttpClientParser, "finish", HttpClientParser_finish,0);
322
- rb_define_method(cHttpClientParser, "execute", HttpClientParser_execute,3);
323
- rb_define_method(cHttpClientParser, "error?", HttpClientParser_has_error,0);
324
- rb_define_method(cHttpClientParser, "finished?", HttpClientParser_is_finished,0);
325
- rb_define_method(cHttpClientParser, "nread", HttpClientParser_nread,0);
326
- }
327
-
328
-
@@ -1,418 +0,0 @@
1
-
2
- #line 1 "http11_parser.rl"
3
- /**
4
- * Copyright (c) 2005 Zed A. Shaw
5
- * You can redistribute it and/or modify it under the same terms as Ruby.
6
- */
7
-
8
- #include "http11_parser.h"
9
- #include <stdio.h>
10
- #include <assert.h>
11
- #include <stdlib.h>
12
- #include <ctype.h>
13
- #include <string.h>
14
-
15
- #define LEN(AT, FPC) (FPC - buffer - parser->AT)
16
- #define MARK(M,FPC) (parser->M = (FPC) - buffer)
17
- #define PTR_TO(F) (buffer + parser->F)
18
- #define L(M) fprintf(stderr, "" # M "\n");
19
-
20
-
21
- /** machine **/
22
-
23
- #line 95 "http11_parser.rl"
24
-
25
-
26
- /** Data **/
27
-
28
- #line 29 "http11_parser.c"
29
- static const char _httpclient_parser_actions[] = {
30
- 0, 1, 0, 1, 1, 1, 2, 1,
31
- 3, 1, 4, 1, 5, 1, 7, 1,
32
- 8, 1, 10, 2, 0, 5, 2, 2,
33
- 3, 2, 3, 4, 2, 4, 10, 2,
34
- 6, 0, 2, 8, 10, 2, 9, 10,
35
- 2, 10, 9, 3, 2, 3, 4, 3,
36
- 4, 9, 10, 3, 4, 10, 9, 3,
37
- 6, 0, 5, 3, 8, 10, 9, 4,
38
- 2, 3, 4, 10, 5, 2, 3, 4,
39
- 9, 10, 5, 2, 3, 4, 10, 9
40
-
41
- };
42
-
43
- static const short _httpclient_parser_key_offsets[] = {
44
- 0, 0, 11, 12, 24, 29, 30, 31,
45
- 43, 58, 80, 95, 116, 131, 153, 168,
46
- 189, 204, 223, 238, 256, 257, 258, 259,
47
- 260, 262, 265, 267, 270, 272, 274, 276,
48
- 279, 281, 298, 314, 317, 319, 320, 322
49
- };
50
-
51
- static const char _httpclient_parser_trans_keys[] = {
52
- 10, 13, 48, 59, 72, 49, 57, 65,
53
- 70, 97, 102, 10, 10, 13, 32, 59,
54
- 9, 12, 48, 57, 65, 70, 97, 102,
55
- 10, 13, 32, 9, 12, 10, 10, 10,
56
- 13, 32, 59, 9, 12, 48, 57, 65,
57
- 70, 97, 102, 33, 124, 126, 35, 39,
58
- 42, 43, 45, 46, 48, 57, 65, 90,
59
- 94, 122, 10, 13, 32, 33, 59, 61,
60
- 124, 126, 9, 12, 35, 39, 42, 43,
61
- 45, 46, 48, 57, 65, 90, 94, 122,
62
- 33, 124, 126, 35, 39, 42, 43, 45,
63
- 46, 48, 57, 65, 90, 94, 122, 10,
64
- 13, 32, 33, 59, 124, 126, 9, 12,
65
- 35, 39, 42, 43, 45, 46, 48, 57,
66
- 65, 90, 94, 122, 33, 124, 126, 35,
67
- 39, 42, 43, 45, 46, 48, 57, 65,
68
- 90, 94, 122, 10, 13, 32, 33, 59,
69
- 61, 124, 126, 9, 12, 35, 39, 42,
70
- 43, 45, 46, 48, 57, 65, 90, 94,
71
- 122, 33, 124, 126, 35, 39, 42, 43,
72
- 45, 46, 48, 57, 65, 90, 94, 122,
73
- 10, 13, 32, 33, 59, 124, 126, 9,
74
- 12, 35, 39, 42, 43, 45, 46, 48,
75
- 57, 65, 90, 94, 122, 33, 124, 126,
76
- 35, 39, 42, 43, 45, 46, 48, 57,
77
- 65, 90, 94, 122, 10, 13, 33, 59,
78
- 61, 124, 126, 35, 39, 42, 43, 45,
79
- 46, 48, 57, 65, 90, 94, 122, 33,
80
- 124, 126, 35, 39, 42, 43, 45, 46,
81
- 48, 57, 65, 90, 94, 122, 10, 13,
82
- 33, 59, 124, 126, 35, 39, 42, 43,
83
- 45, 46, 48, 57, 65, 90, 94, 122,
84
- 84, 84, 80, 47, 48, 57, 46, 48,
85
- 57, 48, 57, 32, 48, 57, 48, 57,
86
- 48, 57, 48, 57, 10, 13, 32, 10,
87
- 13, 10, 13, 33, 124, 126, 35, 39,
88
- 42, 43, 45, 46, 48, 57, 65, 90,
89
- 94, 122, 33, 58, 124, 126, 35, 39,
90
- 42, 43, 45, 46, 48, 57, 65, 90,
91
- 94, 122, 10, 13, 32, 10, 13, 10,
92
- 10, 13, 0
93
- };
94
-
95
- static const char _httpclient_parser_single_lengths[] = {
96
- 0, 5, 1, 4, 3, 1, 1, 4,
97
- 3, 8, 3, 7, 3, 8, 3, 7,
98
- 3, 7, 3, 6, 1, 1, 1, 1,
99
- 0, 1, 0, 1, 0, 0, 0, 3,
100
- 2, 5, 4, 3, 2, 1, 2, 0
101
- };
102
-
103
- static const char _httpclient_parser_range_lengths[] = {
104
- 0, 3, 0, 4, 1, 0, 0, 4,
105
- 6, 7, 6, 7, 6, 7, 6, 7,
106
- 6, 6, 6, 6, 0, 0, 0, 0,
107
- 1, 1, 1, 1, 1, 1, 1, 0,
108
- 0, 6, 6, 0, 0, 0, 0, 0
109
- };
110
-
111
- static const short _httpclient_parser_index_offsets[] = {
112
- 0, 0, 9, 11, 20, 25, 27, 29,
113
- 38, 48, 64, 74, 89, 99, 115, 125,
114
- 140, 150, 164, 174, 187, 189, 191, 193,
115
- 195, 197, 200, 202, 205, 207, 209, 211,
116
- 215, 218, 230, 241, 245, 248, 250, 253
117
- };
118
-
119
- static const char _httpclient_parser_indicies[] = {
120
- 0, 2, 3, 5, 6, 4, 4, 4,
121
- 1, 0, 1, 8, 9, 7, 11, 7,
122
- 10, 10, 10, 1, 13, 14, 12, 12,
123
- 1, 13, 1, 15, 1, 16, 17, 7,
124
- 18, 7, 10, 10, 10, 1, 19, 19,
125
- 19, 19, 19, 19, 19, 19, 19, 1,
126
- 21, 22, 20, 23, 24, 25, 23, 23,
127
- 20, 23, 23, 23, 23, 23, 23, 1,
128
- 26, 26, 26, 26, 26, 26, 26, 26,
129
- 26, 1, 28, 29, 27, 30, 31, 30,
130
- 30, 27, 30, 30, 30, 30, 30, 30,
131
- 1, 32, 32, 32, 32, 32, 32, 32,
132
- 32, 32, 1, 33, 34, 20, 35, 36,
133
- 37, 35, 35, 20, 35, 35, 35, 35,
134
- 35, 35, 1, 38, 38, 38, 38, 38,
135
- 38, 38, 38, 38, 1, 39, 40, 27,
136
- 41, 42, 41, 41, 27, 41, 41, 41,
137
- 41, 41, 41, 1, 43, 43, 43, 43,
138
- 43, 43, 43, 43, 43, 1, 44, 45,
139
- 46, 47, 48, 46, 46, 46, 46, 46,
140
- 46, 46, 46, 1, 49, 49, 49, 49,
141
- 49, 49, 49, 49, 49, 1, 50, 51,
142
- 52, 53, 52, 52, 52, 52, 52, 52,
143
- 52, 52, 1, 54, 1, 55, 1, 56,
144
- 1, 57, 1, 58, 1, 59, 58, 1,
145
- 60, 1, 61, 60, 1, 62, 1, 63,
146
- 1, 64, 1, 66, 67, 68, 65, 70,
147
- 71, 69, 13, 14, 72, 72, 72, 72,
148
- 72, 72, 72, 72, 72, 1, 73, 74,
149
- 73, 73, 73, 73, 73, 73, 73, 73,
150
- 1, 76, 77, 78, 75, 80, 81, 79,
151
- 82, 1, 84, 85, 83, 1, 0
152
- };
153
-
154
- static const char _httpclient_parser_trans_targs[] = {
155
- 39, 0, 2, 3, 7, 16, 20, 4,
156
- 39, 6, 7, 12, 4, 39, 5, 39,
157
- 39, 5, 8, 9, 4, 39, 5, 9,
158
- 8, 10, 11, 4, 39, 5, 11, 8,
159
- 13, 39, 6, 13, 12, 14, 15, 39,
160
- 6, 15, 12, 17, 39, 2, 17, 16,
161
- 18, 19, 39, 2, 19, 16, 21, 22,
162
- 23, 24, 25, 26, 27, 28, 29, 30,
163
- 31, 32, 33, 37, 38, 32, 33, 37,
164
- 34, 34, 35, 36, 33, 37, 35, 36,
165
- 33, 37, 33, 32, 33, 37
166
- };
167
-
168
- static const char _httpclient_parser_trans_actions[] = {
169
- 37, 0, 0, 1, 1, 0, 1, 15,
170
- 59, 15, 0, 15, 0, 17, 0, 40,
171
- 34, 15, 15, 3, 43, 63, 43, 0,
172
- 43, 22, 7, 9, 28, 9, 0, 9,
173
- 3, 74, 43, 0, 43, 22, 7, 51,
174
- 9, 0, 9, 3, 68, 43, 0, 43,
175
- 22, 7, 47, 9, 0, 9, 0, 0,
176
- 0, 0, 0, 0, 0, 13, 1, 0,
177
- 0, 31, 55, 55, 31, 0, 11, 11,
178
- 3, 0, 5, 7, 25, 25, 7, 0,
179
- 9, 9, 0, 1, 19, 19
180
- };
181
-
182
- static const int httpclient_parser_start = 1;
183
- static const int httpclient_parser_first_final = 39;
184
- static const int httpclient_parser_error = 0;
185
-
186
- static const int httpclient_parser_en_main = 1;
187
-
188
-
189
- #line 99 "http11_parser.rl"
190
-
191
- int httpclient_parser_init(httpclient_parser *parser) {
192
- int cs = 0;
193
-
194
- #line 195 "http11_parser.c"
195
- {
196
- cs = httpclient_parser_start;
197
- }
198
-
199
- #line 103 "http11_parser.rl"
200
- parser->cs = cs;
201
- parser->body_start = 0;
202
- parser->content_len = 0;
203
- parser->mark = 0;
204
- parser->nread = 0;
205
- parser->field_len = 0;
206
- parser->field_start = 0;
207
-
208
- return(1);
209
- }
210
-
211
-
212
- /** exec **/
213
- size_t httpclient_parser_execute(httpclient_parser *parser, const char *buffer, size_t len, size_t off) {
214
- const char *p, *pe;
215
- int cs = parser->cs;
216
-
217
- assert(off <= len && "offset past end of buffer");
218
-
219
- p = buffer+off;
220
- pe = buffer+len;
221
-
222
- assert(*pe == '\0' && "pointer does not end on NUL");
223
- assert(pe - p == len - off && "pointers aren't same distance");
224
-
225
-
226
-
227
- #line 228 "http11_parser.c"
228
- {
229
- int _klen;
230
- unsigned int _trans;
231
- const char *_acts;
232
- unsigned int _nacts;
233
- const char *_keys;
234
-
235
- if ( p == pe )
236
- goto _test_eof;
237
- if ( cs == 0 )
238
- goto _out;
239
- _resume:
240
- _keys = _httpclient_parser_trans_keys + _httpclient_parser_key_offsets[cs];
241
- _trans = _httpclient_parser_index_offsets[cs];
242
-
243
- _klen = _httpclient_parser_single_lengths[cs];
244
- if ( _klen > 0 ) {
245
- const char *_lower = _keys;
246
- const char *_mid;
247
- const char *_upper = _keys + _klen - 1;
248
- while (1) {
249
- if ( _upper < _lower )
250
- break;
251
-
252
- _mid = _lower + ((_upper-_lower) >> 1);
253
- if ( (*p) < *_mid )
254
- _upper = _mid - 1;
255
- else if ( (*p) > *_mid )
256
- _lower = _mid + 1;
257
- else {
258
- _trans += (_mid - _keys);
259
- goto _match;
260
- }
261
- }
262
- _keys += _klen;
263
- _trans += _klen;
264
- }
265
-
266
- _klen = _httpclient_parser_range_lengths[cs];
267
- if ( _klen > 0 ) {
268
- const char *_lower = _keys;
269
- const char *_mid;
270
- const char *_upper = _keys + (_klen<<1) - 2;
271
- while (1) {
272
- if ( _upper < _lower )
273
- break;
274
-
275
- _mid = _lower + (((_upper-_lower) >> 1) & ~1);
276
- if ( (*p) < _mid[0] )
277
- _upper = _mid - 2;
278
- else if ( (*p) > _mid[1] )
279
- _lower = _mid + 2;
280
- else {
281
- _trans += ((_mid - _keys)>>1);
282
- goto _match;
283
- }
284
- }
285
- _trans += _klen;
286
- }
287
-
288
- _match:
289
- _trans = _httpclient_parser_indicies[_trans];
290
- cs = _httpclient_parser_trans_targs[_trans];
291
-
292
- if ( _httpclient_parser_trans_actions[_trans] == 0 )
293
- goto _again;
294
-
295
- _acts = _httpclient_parser_actions + _httpclient_parser_trans_actions[_trans];
296
- _nacts = (unsigned int) *_acts++;
297
- while ( _nacts-- > 0 )
298
- {
299
- switch ( *_acts++ )
300
- {
301
- case 0:
302
- #line 23 "http11_parser.rl"
303
- {MARK(mark, p); }
304
- break;
305
- case 1:
306
- #line 25 "http11_parser.rl"
307
- { MARK(field_start, p); }
308
- break;
309
- case 2:
310
- #line 27 "http11_parser.rl"
311
- {
312
- parser->field_len = LEN(field_start, p);
313
- }
314
- break;
315
- case 3:
316
- #line 31 "http11_parser.rl"
317
- { MARK(mark, p); }
318
- break;
319
- case 4:
320
- #line 33 "http11_parser.rl"
321
- {
322
- parser->http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p));
323
- }
324
- break;
325
- case 5:
326
- #line 37 "http11_parser.rl"
327
- {
328
- parser->reason_phrase(parser->data, PTR_TO(mark), LEN(mark, p));
329
- }
330
- break;
331
- case 6:
332
- #line 41 "http11_parser.rl"
333
- {
334
- parser->status_code(parser->data, PTR_TO(mark), LEN(mark, p));
335
- }
336
- break;
337
- case 7:
338
- #line 45 "http11_parser.rl"
339
- {
340
- parser->http_version(parser->data, PTR_TO(mark), LEN(mark, p));
341
- }
342
- break;
343
- case 8:
344
- #line 49 "http11_parser.rl"
345
- {
346
- parser->chunk_size(parser->data, PTR_TO(mark), LEN(mark, p));
347
- }
348
- break;
349
- case 9:
350
- #line 53 "http11_parser.rl"
351
- {
352
- parser->last_chunk(parser->data, NULL, 0);
353
- }
354
- break;
355
- case 10:
356
- #line 57 "http11_parser.rl"
357
- {
358
- parser->body_start = p - buffer + 1;
359
- if(parser->header_done != NULL)
360
- parser->header_done(parser->data, p + 1, pe - p - 1);
361
- {p++; goto _out; }
362
- }
363
- break;
364
- #line 365 "http11_parser.c"
365
- }
366
- }
367
-
368
- _again:
369
- if ( cs == 0 )
370
- goto _out;
371
- if ( ++p != pe )
372
- goto _resume;
373
- _test_eof: {}
374
- _out: {}
375
- }
376
-
377
- #line 130 "http11_parser.rl"
378
-
379
- parser->cs = cs;
380
- parser->nread += p - (buffer + off);
381
-
382
- assert(p <= pe && "buffer overflow after parsing execute");
383
- assert(parser->nread <= len && "nread longer than length");
384
- assert(parser->body_start <= len && "body starts after buffer end");
385
- assert(parser->mark < len && "mark is after buffer end");
386
- assert(parser->field_len <= len && "field has length longer than whole buffer");
387
- assert(parser->field_start < len && "field starts after buffer end");
388
-
389
- if(parser->body_start) {
390
- /* final \r\n combo encountered so stop right here */
391
- parser->nread = parser->body_start;
392
- }
393
-
394
- return(parser->nread);
395
- }
396
-
397
- int httpclient_parser_finish(httpclient_parser *parser)
398
- {
399
- int cs = parser->cs;
400
-
401
- parser->cs = cs;
402
-
403
- if (httpclient_parser_has_error(parser) ) {
404
- return -1;
405
- } else if (httpclient_parser_is_finished(parser) ) {
406
- return 1;
407
- } else {
408
- return 0;
409
- }
410
- }
411
-
412
- int httpclient_parser_has_error(httpclient_parser *parser) {
413
- return parser->cs == httpclient_parser_error;
414
- }
415
-
416
- int httpclient_parser_is_finished(httpclient_parser *parser) {
417
- return parser->cs == httpclient_parser_first_final;
418
- }