cool.io 1.2.4 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/ext/libev/ev.h CHANGED
@@ -205,7 +205,7 @@ struct ev_loop;
205
205
  /*****************************************************************************/
206
206
 
207
207
  #define EV_VERSION_MAJOR 4
208
- #define EV_VERSION_MINOR 15
208
+ #define EV_VERSION_MINOR 19
209
209
 
210
210
  /* eventmask, revents, events... */
211
211
  enum {
@@ -658,8 +658,10 @@ EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_T
658
658
  /* advanced stuff for threading etc. support, see docs */
659
659
  EV_API_DECL void ev_set_userdata (EV_P_ void *data) EV_THROW;
660
660
  EV_API_DECL void *ev_userdata (EV_P) EV_THROW;
661
- EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P)) EV_THROW;
662
- EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P) EV_THROW) EV_THROW;
661
+ typedef void (*ev_loop_callback)(EV_P);
662
+ EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW;
663
+ /* C++ doesn't allow the use of the ev_loop_callback typedef here, so we need to spell it out*/
664
+ EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW;
663
665
 
664
666
  EV_API_DECL unsigned int ev_pending_count (EV_P) EV_THROW; /* number of pending events, if any */
665
667
  EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */
@@ -730,7 +732,7 @@ EV_API_DECL void ev_resume (EV_P) EV_THROW;
730
732
  #endif
731
733
 
732
734
  /* stopping (enabling, adding) a watcher does nothing if it is already running */
733
- /* stopping (disabling, deleting) a watcher does nothing unless its already running */
735
+ /* stopping (disabling, deleting) a watcher does nothing unless it's already running */
734
736
  #if EV_PROTOTYPES
735
737
 
736
738
  /* feeds an event into a watcher as if the event actually occurred */
data/ext/libev/ev_epoll.c CHANGED
@@ -228,7 +228,10 @@ epoll_poll (EV_P_ ev_tstamp timeout)
228
228
  if (anfds [fd].emask & EV_EMASK_EPERM && events)
229
229
  fd_event (EV_A_ fd, events);
230
230
  else
231
- epoll_eperms [i] = epoll_eperms [--epoll_epermcnt];
231
+ {
232
+ epoll_eperms [i] = epoll_eperms [--epoll_epermcnt];
233
+ anfds [fd].emask = 0;
234
+ }
232
235
  }
233
236
  }
234
237
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libev kqueue backend
3
3
  *
4
- * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libev@schmorp.de>
4
+ * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de>
5
5
  * All rights reserved.
6
6
  *
7
7
  * Redistribution and use in source and binary forms, with or without modifica-
data/ext/libev/ev_vars.h CHANGED
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * loop member variable declarations
3
3
  *
4
- * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libev@schmorp.de>
4
+ * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de>
5
5
  * All rights reserved.
6
6
  *
7
7
  * Redistribution and use in source and binary forms, with or without modifica-
@@ -194,9 +194,10 @@ VARx(unsigned int, loop_count) /* total number of loop iterations/blocks */
194
194
  VARx(unsigned int, loop_depth) /* #ev_run enters - #ev_run leaves */
195
195
 
196
196
  VARx(void *, userdata)
197
+ /* C++ doesn't support the ev_loop_callback typedef here. stinks. */
197
198
  VAR (release_cb, void (*release_cb)(EV_P) EV_THROW)
198
199
  VAR (acquire_cb, void (*acquire_cb)(EV_P) EV_THROW)
199
- VAR (invoke_cb , void (*invoke_cb) (EV_P))
200
+ VAR (invoke_cb , ev_loop_callback invoke_cb)
200
201
  #endif
201
202
 
202
203
  #undef VARx
data/ext/libev/ev_win32.c CHANGED
@@ -143,7 +143,7 @@ fail:
143
143
 
144
144
  #undef pipe
145
145
  #define pipe(filedes) ev_pipe (filedes)
146
-
146
+
147
147
  #define EV_HAVE_EV_TIME 1
148
148
  ev_tstamp
149
149
  ev_time (void)
@@ -0,0 +1,115 @@
1
+ diff --git a/ext/libev/ev_select.c b/ext/libev/ev_select.c
2
+ index f38d6ca..3a32642 100644
3
+ --- a/ext/libev/ev_select.c
4
+ +++ b/ext/libev/ev_select.c
5
+ @@ -67,6 +67,53 @@
6
+
7
+ #include <string.h>
8
+
9
+ +#ifdef _WIN32
10
+ +/*
11
+ +########## COOLIO PATCHERY HO! ##########
12
+ +
13
+ +Ruby undefs FD_* utilities for own implementation.
14
+ +It converts fd argument into socket handle internally on Windows,
15
+ +so libev should not use Ruby's FD_* utilities.
16
+ +
17
+ +Following FD_* utilities come from MinGW.
18
+ +RubyInstaller is built by MinGW so this should work.
19
+ +*/
20
+ +int PASCAL __WSAFDIsSet(SOCKET,fd_set*);
21
+ +#define EV_WIN_FD_CLR(fd,set) do { u_int __i;\
22
+ +for (__i = 0; __i < ((fd_set *)(set))->fd_count ; __i++) {\
23
+ + if (((fd_set *)(set))->fd_array[__i] == (fd)) {\
24
+ + while (__i < ((fd_set *)(set))->fd_count-1) {\
25
+ + ((fd_set*)(set))->fd_array[__i] = ((fd_set*)(set))->fd_array[__i+1];\
26
+ + __i++;\
27
+ + }\
28
+ + ((fd_set*)(set))->fd_count--;\
29
+ + break;\
30
+ + }\
31
+ +}\
32
+ +} while (0)
33
+ +#define EV_WIN_FD_SET(fd, set) do { u_int __i;\
34
+ +for (__i = 0; __i < ((fd_set *)(set))->fd_count ; __i++) {\
35
+ + if (((fd_set *)(set))->fd_array[__i] == (fd)) {\
36
+ + break;\
37
+ + }\
38
+ +}\
39
+ +if (__i == ((fd_set *)(set))->fd_count) {\
40
+ + if (((fd_set *)(set))->fd_count < FD_SETSIZE) {\
41
+ + ((fd_set *)(set))->fd_array[__i] = (fd);\
42
+ + ((fd_set *)(set))->fd_count++;\
43
+ + }\
44
+ +}\
45
+ +} while(0)
46
+ +#define EV_WIN_FD_ZERO(set) (((fd_set *)(set))->fd_count=0)
47
+ +#define EV_WIN_FD_ISSET(fd, set) __WSAFDIsSet((SOCKET)(fd), (fd_set *)(set))
48
+ +/* ######################################## */
49
+ +#else
50
+ +#define EV_WIN_FD_CLR FD_CLR
51
+ +#define EV_WIN_FD_SET FD_SET
52
+ +#define EV_WIN_FD_ZERO FD_ZERO
53
+ +#define EV_WIN_FD_ISSET FD_ISSET
54
+ +#endif
55
+ +
56
+ static void
57
+ select_modify (EV_P_ int fd, int oev, int nev)
58
+ {
59
+ @@ -91,17 +138,17 @@ select_modify (EV_P_ int fd, int oev, int nev)
60
+ if ((oev ^ nev) & EV_READ)
61
+ #endif
62
+ if (nev & EV_READ)
63
+ - FD_SET (handle, (fd_set *)vec_ri);
64
+ + EV_WIN_FD_SET (handle, (fd_set *)vec_ri);
65
+ else
66
+ - FD_CLR (handle, (fd_set *)vec_ri);
67
+ + EV_WIN_FD_CLR (handle, (fd_set *)vec_ri);
68
+
69
+ #if EV_SELECT_IS_WINSOCKET
70
+ if ((oev ^ nev) & EV_WRITE)
71
+ #endif
72
+ if (nev & EV_WRITE)
73
+ - FD_SET (handle, (fd_set *)vec_wi);
74
+ + EV_WIN_FD_SET (handle, (fd_set *)vec_wi);
75
+ else
76
+ - FD_CLR (handle, (fd_set *)vec_wi);
77
+ + EV_WIN_FD_CLR (handle, (fd_set *)vec_wi);
78
+
79
+ #else
80
+
81
+ @@ -136,6 +183,8 @@ select_modify (EV_P_ int fd, int oev, int nev)
82
+ }
83
+ }
84
+
85
+ +#undef socket
86
+ +
87
+ static void
88
+ select_poll (EV_P_ ev_tstamp timeout)
89
+ {
90
+ @@ -230,10 +279,10 @@ select_poll (EV_P_ ev_tstamp timeout)
91
+ int handle = fd;
92
+ #endif
93
+
94
+ - if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
95
+ - if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
96
+ + if (EV_WIN_FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
97
+ + if (EV_WIN_FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
98
+ #ifdef _WIN32
99
+ - if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE;
100
+ + if (EV_WIN_FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE;
101
+ #endif
102
+
103
+ if (expect_true (events))
104
+ @@ -279,9 +328,9 @@ select_init (EV_P_ int flags)
105
+ backend_poll = select_poll;
106
+
107
+ #if EV_SELECT_USE_FD_SET
108
+ - vec_ri = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri);
109
+ + vec_ri = ev_malloc (sizeof (fd_set)); EV_WIN_FD_ZERO ((fd_set *)vec_ri);
110
+ vec_ro = ev_malloc (sizeof (fd_set));
111
+ - vec_wi = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi);
112
+ + vec_wi = ev_malloc (sizeof (fd_set)); EV_WIN_FD_ZERO ((fd_set *)vec_wi);
113
+ vec_wo = ev_malloc (sizeof (fd_set));
114
+ #ifdef _WIN32
115
+ vec_eo = ev_malloc (sizeof (fd_set));
data/lib/cool.io.rb CHANGED
@@ -19,8 +19,6 @@ require "cool.io/listener"
19
19
  require "cool.io/dns_resolver"
20
20
  require "cool.io/socket"
21
21
  require "cool.io/server"
22
- require "cool.io/http_client"
23
- require "cool.io/dsl"
24
22
 
25
23
  module Coolio
26
24
  def self.inspect
data/lib/cool.io/io.rb CHANGED
@@ -98,11 +98,6 @@ module Coolio
98
98
  data.size
99
99
  end
100
100
 
101
- # Number of bytes are currently in the output buffer
102
- def output_buffer_size
103
- @_write_buffer.size
104
- end
105
-
106
101
  # Close the IO stream
107
102
  def close
108
103
  detach if attached?
data/lib/cool.io/meta.rb CHANGED
@@ -39,7 +39,7 @@ module Coolio
39
39
  end
40
40
 
41
41
  if defined? @#{method}_callback and @#{method}_callback
42
- instance_exec(*args, &@#{method}_callback)
42
+ @#{method}_callback.call(*args)
43
43
  end
44
44
  end
45
45
  EOD
@@ -1,5 +1,5 @@
1
1
  module Coolio
2
- VERSION = "1.2.4"
2
+ VERSION = "1.3.0"
3
3
 
4
4
  def self.version
5
5
  VERSION
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cool.io
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Arcieri
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-12 00:00:00.000000000 Z
12
+ date: 2015-01-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler
@@ -61,7 +61,6 @@ email:
61
61
  executables: []
62
62
  extensions:
63
63
  - ext/cool.io/extconf.rb
64
- - ext/http11_client/extconf.rb
65
64
  - ext/iobuffer/extconf.rb
66
65
  extra_rdoc_files: []
67
66
  files:
@@ -74,12 +73,12 @@ files:
74
73
  - README.md
75
74
  - Rakefile
76
75
  - cool.io.gemspec
76
+ - examples/callbacked_echo_server.rb
77
77
  - examples/dslified_echo_client.rb
78
78
  - examples/dslified_echo_server.rb
79
79
  - examples/echo_client.rb
80
80
  - examples/echo_server.rb
81
81
  - examples/google.rb
82
- - examples/httpclient.rb
83
82
  - ext/cool.io/.gitignore
84
83
  - ext/cool.io/cool.io.h
85
84
  - ext/cool.io/cool.io_ext.c
@@ -93,14 +92,6 @@ files:
93
92
  - ext/cool.io/utils.c
94
93
  - ext/cool.io/watcher.c
95
94
  - ext/cool.io/watcher.h
96
- - ext/http11_client/.gitignore
97
- - ext/http11_client/LICENSE
98
- - ext/http11_client/ext_help.h
99
- - ext/http11_client/extconf.rb
100
- - ext/http11_client/http11_client.c
101
- - ext/http11_client/http11_parser.c
102
- - ext/http11_client/http11_parser.h
103
- - ext/http11_client/http11_parser.rl
104
95
  - ext/iobuffer/extconf.rb
105
96
  - ext/iobuffer/iobuffer.c
106
97
  - ext/libev/Changes
@@ -119,14 +110,13 @@ files:
119
110
  - ext/libev/ev_wrap.h
120
111
  - ext/libev/ruby_gil.patch
121
112
  - ext/libev/test_libev_win32.c
113
+ - ext/libev/win_select.patch
122
114
  - lib/.gitignore
123
115
  - lib/cool.io.rb
124
116
  - lib/cool.io/async_watcher.rb
125
117
  - lib/cool.io/custom_require.rb
126
118
  - lib/cool.io/dns_resolver.rb
127
119
  - lib/cool.io/dsl.rb
128
- - lib/cool.io/eventmachine.rb
129
- - lib/cool.io/http_client.rb
130
120
  - lib/cool.io/io.rb
131
121
  - lib/cool.io/iowatcher.rb
132
122
  - lib/cool.io/listener.rb
@@ -165,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
155
  version: '0'
166
156
  requirements: []
167
157
  rubyforge_project:
168
- rubygems_version: 2.2.2
158
+ rubygems_version: 2.4.5
169
159
  signing_key:
170
160
  specification_version: 4
171
161
  summary: A cool framework for doing high performance I/O in Ruby
@@ -1,38 +0,0 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
-
3
- require 'rubygems'
4
- require 'cool.io'
5
-
6
- class MyHttpClient < Coolio::HttpClient
7
- def on_connect
8
- super
9
- STDERR.puts "Connected to #{remote_host}:#{remote_port}"
10
- end
11
-
12
- def on_connect_failed
13
- super
14
- STDERR.puts "Connection failed"
15
- end
16
-
17
- def on_response_header(header)
18
- STDERR.puts "Response: #{header.http_version} #{header.status} #{header.http_reason}"
19
- end
20
-
21
- def on_body_data(data)
22
- STDOUT.write data
23
- STDOUT.flush
24
- end
25
-
26
- def on_request_complete
27
- STDERR.puts "Request complete!"
28
- end
29
-
30
- def on_error(reason)
31
- STDERR.puts "Error: #{reason}"
32
- end
33
- end
34
-
35
- l = Coolio::Loop.default
36
- c = MyHttpClient.connect("www.google.com", 80).attach(l)
37
- c.request('GET', '/search', :query => { :q => 'foobar' })
38
- l.run
@@ -1,5 +0,0 @@
1
- Makefile
2
- mkmf.log
3
- *.o
4
- *.so
5
- *.bundle
@@ -1,31 +0,0 @@
1
- Copyright (c) 2010, Zed A. Shaw and Mongrel2 Project Contributors.
2
- All rights reserved.
3
-
4
- Redistribution and use in source and binary forms, with or without
5
- modification, are permitted provided that the following conditions are
6
- met:
7
-
8
- * Redistributions of source code must retain the above copyright
9
- notice, this list of conditions and the following disclaimer.
10
-
11
- * Redistributions in binary form must reproduce the above copyright
12
- notice, this list of conditions and the following disclaimer in the
13
- documentation and/or other materials provided with the distribution.
14
-
15
- * Neither the name of the Mongrel2 Project, Zed A. Shaw, nor the names
16
- of its contributors may be used to endorse or promote products
17
- derived from this software without specific prior written
18
- permission.
19
-
20
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21
- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
-
@@ -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,300 +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 mCoolio;
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
- void client_http_field(void *data, const char *field, size_t flen, const char *value, size_t vlen)
25
- {
26
- char *ch, *end;
27
- VALUE req = (VALUE)data;
28
- VALUE v = Qnil;
29
- VALUE f = Qnil;
30
-
31
- v = rb_str_new(value, vlen);
32
- f = rb_str_new(field, flen);
33
-
34
- /* Yes Children, rb_str_upcase_bang isn't even available as an intern.h function.
35
- * how incredibly handy to not have that. Nope, I have to do it by hand.*/
36
- for(ch = RSTRING_PTR(f), end = ch + RSTRING_LEN(f); ch < end; ch++) {
37
- if(*ch == '-') {
38
- *ch = '_';
39
- } else {
40
- *ch = toupper(*ch);
41
- }
42
- }
43
-
44
- rb_hash_aset(req, f, v);
45
- }
46
-
47
- void client_reason_phrase(void *data, const char *at, size_t length)
48
- {
49
- VALUE req = (VALUE)data;
50
- VALUE v = Qnil;
51
-
52
- v = rb_str_new(at, length);
53
-
54
- rb_ivar_set(req, id_reason, v);
55
- }
56
-
57
- void client_status_code(void *data, const char *at, size_t length)
58
- {
59
- VALUE req = (VALUE)data;
60
- VALUE v = Qnil;
61
-
62
- v = rb_str_new(at, length);
63
-
64
- rb_ivar_set(req, id_status, v);
65
- }
66
-
67
- void client_http_version(void *data, const char *at, size_t length)
68
- {
69
- VALUE req = (VALUE)data;
70
- VALUE v = Qnil;
71
-
72
- v = rb_str_new(at, length);
73
-
74
- rb_ivar_set(req, id_version, v);
75
- }
76
-
77
- /** Finalizes the request header to have a bunch of stuff that's
78
- needed. */
79
- void client_header_done(void *data, const char *at, size_t length)
80
- {
81
- VALUE req = (VALUE)data;
82
- VALUE v = Qnil;
83
-
84
- v = rb_str_new(at, length);
85
- rb_ivar_set(req, id_body, v);
86
- }
87
-
88
- void client_chunk_size(void *data, const char *at, size_t length)
89
- {
90
- VALUE req = (VALUE)data;
91
- VALUE v = Qnil;
92
-
93
- if(length <= 0) {
94
- rb_raise(eHttpClientParserError, "Chunked Encoding gave <= 0 chunk size.");
95
- }
96
-
97
- v = rb_str_new(at, length);
98
-
99
- rb_ivar_set(req, id_chunk_size, v);
100
- }
101
-
102
- void client_last_chunk(void *data, const char *at, size_t length) {
103
- VALUE req = (VALUE)data;
104
- rb_ivar_set(req, id_last_chunk,Qtrue);
105
- }
106
-
107
-
108
- void HttpClientParser_free(void *data) {
109
- TRACE();
110
-
111
- if(data) {
112
- free(data);
113
- }
114
- }
115
-
116
-
117
- VALUE HttpClientParser_alloc(VALUE klass)
118
- {
119
- VALUE obj;
120
- httpclient_parser *hp = ALLOC_N(httpclient_parser, 1);
121
- TRACE();
122
- hp->http_field = client_http_field;
123
- hp->status_code = client_status_code;
124
- hp->reason_phrase = client_reason_phrase;
125
- hp->http_version = client_http_version;
126
- hp->header_done = client_header_done;
127
- hp->chunk_size = client_chunk_size;
128
- hp->last_chunk = client_last_chunk;
129
- httpclient_parser_init(hp);
130
-
131
- obj = Data_Wrap_Struct(klass, NULL, HttpClientParser_free, hp);
132
-
133
- return obj;
134
- }
135
-
136
-
137
- /**
138
- * call-seq:
139
- * parser.new -> parser
140
- *
141
- * Creates a new parser.
142
- */
143
- VALUE HttpClientParser_init(VALUE self)
144
- {
145
- httpclient_parser *http = NULL;
146
- DATA_GET(self, httpclient_parser, http);
147
- httpclient_parser_init(http);
148
-
149
- return self;
150
- }
151
-
152
-
153
- /**
154
- * call-seq:
155
- * parser.reset -> nil
156
- *
157
- * Resets the parser to it's initial state so that you can reuse it
158
- * rather than making new ones.
159
- */
160
- VALUE HttpClientParser_reset(VALUE self)
161
- {
162
- httpclient_parser *http = NULL;
163
- DATA_GET(self, httpclient_parser, http);
164
- httpclient_parser_init(http);
165
-
166
- return Qnil;
167
- }
168
-
169
-
170
- /**
171
- * call-seq:
172
- * parser.finish -> true/false
173
- *
174
- * Finishes a parser early which could put in a "good" or bad state.
175
- * You should call reset after finish it or bad things will happen.
176
- */
177
- VALUE HttpClientParser_finish(VALUE self)
178
- {
179
- httpclient_parser *http = NULL;
180
- DATA_GET(self, httpclient_parser, http);
181
- httpclient_parser_finish(http);
182
-
183
- return httpclient_parser_is_finished(http) ? Qtrue : Qfalse;
184
- }
185
-
186
-
187
- /**
188
- * call-seq:
189
- * parser.execute(req_hash, data, start) -> Integer
190
- *
191
- * Takes a Hash and a String of data, parses the String of data filling in the Hash
192
- * returning an Integer to indicate how much of the data has been read. No matter
193
- * what the return value, you should call HttpClientParser#finished? and HttpClientParser#error?
194
- * to figure out if it's done parsing or there was an error.
195
- *
196
- * This function now throws an exception when there is a parsing error. This makes
197
- * the logic for working with the parser much easier. You can still test for an
198
- * error, but now you need to wrap the parser with an exception handling block.
199
- *
200
- * The third argument allows for parsing a partial request and then continuing
201
- * the parsing from that position. It needs all of the original data as well
202
- * so you have to append to the data buffer as you read.
203
- */
204
- VALUE HttpClientParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
205
- {
206
- httpclient_parser *http = NULL;
207
- int from = 0;
208
- char *dptr = NULL;
209
- long dlen = 0;
210
-
211
- REQUIRE_TYPE(req_hash, T_HASH);
212
- REQUIRE_TYPE(data, T_STRING);
213
- REQUIRE_TYPE(start, T_FIXNUM);
214
-
215
- DATA_GET(self, httpclient_parser, http);
216
-
217
- from = FIX2INT(start);
218
- dptr = RSTRING_PTR(data);
219
- dlen = RSTRING_LEN(data);
220
-
221
- if(from >= dlen) {
222
- rb_raise(eHttpClientParserError, "Requested start is after data buffer end.");
223
- } else {
224
- http->data = (void *)req_hash;
225
- httpclient_parser_execute(http, dptr, dlen, from);
226
-
227
- if(httpclient_parser_has_error(http)) {
228
- rb_raise(eHttpClientParserError, "Invalid HTTP format, parsing fails.");
229
- } else {
230
- return INT2FIX(httpclient_parser_nread(http));
231
- }
232
- }
233
- }
234
-
235
-
236
-
237
- /**
238
- * call-seq:
239
- * parser.error? -> true/false
240
- *
241
- * Tells you whether the parser is in an error state.
242
- */
243
- VALUE HttpClientParser_has_error(VALUE self)
244
- {
245
- httpclient_parser *http = NULL;
246
- DATA_GET(self, httpclient_parser, http);
247
-
248
- return httpclient_parser_has_error(http) ? Qtrue : Qfalse;
249
- }
250
-
251
-
252
- /**
253
- * call-seq:
254
- * parser.finished? -> true/false
255
- *
256
- * Tells you whether the parser is finished or not and in a good state.
257
- */
258
- VALUE HttpClientParser_is_finished(VALUE self)
259
- {
260
- httpclient_parser *http = NULL;
261
- DATA_GET(self, httpclient_parser, http);
262
-
263
- return httpclient_parser_is_finished(http) ? Qtrue : Qfalse;
264
- }
265
-
266
-
267
- /**
268
- * call-seq:
269
- * parser.nread -> Integer
270
- *
271
- * Returns the amount of data processed so far during this processing cycle. It is
272
- * set to 0 on initialize or reset calls and is incremented each time execute is called.
273
- */
274
- VALUE HttpClientParser_nread(VALUE self)
275
- {
276
- httpclient_parser *http = NULL;
277
- DATA_GET(self, httpclient_parser, http);
278
-
279
- return INT2FIX(http->nread);
280
- }
281
-
282
-
283
-
284
- void Init_http11_client()
285
- {
286
-
287
- mCoolio = rb_define_module("Coolio");
288
-
289
- eHttpClientParserError = rb_define_class_under(mCoolio, "HttpClientParserError", rb_eIOError);
290
-
291
- cHttpClientParser = rb_define_class_under(mCoolio, "HttpClientParser", rb_cObject);
292
- rb_define_alloc_func(cHttpClientParser, HttpClientParser_alloc);
293
- rb_define_method(cHttpClientParser, "initialize", HttpClientParser_init,0);
294
- rb_define_method(cHttpClientParser, "reset", HttpClientParser_reset,0);
295
- rb_define_method(cHttpClientParser, "finish", HttpClientParser_finish,0);
296
- rb_define_method(cHttpClientParser, "execute", HttpClientParser_execute,3);
297
- rb_define_method(cHttpClientParser, "error?", HttpClientParser_has_error,0);
298
- rb_define_method(cHttpClientParser, "finished?", HttpClientParser_is_finished,0);
299
- rb_define_method(cHttpClientParser, "nread", HttpClientParser_nread,0);
300
- }