em-http-request 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

data/README.rdoc CHANGED
@@ -1,14 +1,15 @@
1
1
  = EM-HTTP-Client
2
2
 
3
- EventMachine based HTTP Request interface. Supports streaming response processing, uses Ragel HTTP parser.
3
+ EventMachine based HTTP Request interface. Supports streaming response processing, uses Ragel HTTP parser.
4
4
  - Simple interface for single & parallel requests via deferred callbacks
5
5
  - Automatic gzip & deflate decoding
6
6
  - Basic-Auth & OAuth support
7
7
  - Custom timeouts
8
8
  - Proxy support (with SSL Tunneling)
9
+ - Auto-follow 3xx redirects with max depth
9
10
  - Bi-directional communication with web-socket services
10
11
 
11
- Screencast / Demo of using EM-HTTP-Request:
12
+ Screencast / Demo of using EM-HTTP-Request:
12
13
  - http://everburning.com/news/eventmachine-screencast-em-http-request/
13
14
 
14
15
  == Getting started
@@ -26,12 +27,12 @@ Screencast / Demo of using EM-HTTP-Request:
26
27
 
27
28
  EventMachine.run {
28
29
  http = EventMachine::HttpRequest.new('http://127.0.0.1/').get :query => {'keyname' => 'value'}, :timeout => 10
29
-
30
+
30
31
  http.callback {
31
32
  p http.response_header.status
32
33
  p http.response_header
33
34
  p http.response
34
-
35
+
35
36
  EventMachine.stop
36
37
  }
37
38
  }
@@ -41,15 +42,15 @@ Fire and wait for multiple requess to complete via the MultiRequest interface.
41
42
 
42
43
  EventMachine.run {
43
44
  multi = EventMachine::MultiRequest.new
44
-
45
+
45
46
  # add multiple requests to the multi-handler
46
47
  multi.add(EventMachine::HttpRequest.new('http://www.google.com/').get)
47
48
  multi.add(EventMachine::HttpRequest.new('http://www.yahoo.com/').get)
48
-
49
+
49
50
  multi.callback {
50
51
  p multi.responses[:succeeded]
51
52
  p multi.responses[:failed]
52
-
53
+
53
54
  EventMachine.stop
54
55
  }
55
56
  }
@@ -59,7 +60,7 @@ Full basic author support. For OAuth, check examples/oauth-tweet.rb file.
59
60
 
60
61
  EventMachine.run {
61
62
  http = EventMachine::HttpRequest.new('http://www.website.com/').get :head => {'authorization' => ['user', 'pass']}
62
-
63
+
63
64
  http.errback { failed }
64
65
  http.callback {
65
66
  p http.response_header
@@ -72,7 +73,7 @@ Full basic author support. For OAuth, check examples/oauth-tweet.rb file.
72
73
  EventMachine.run {
73
74
  http1 = EventMachine::HttpRequest.new('http://www.website.com/').post :body => {"key1" => 1, "key2" => [2,3]}
74
75
  http2 = EventMachine::HttpRequest.new('http://www.website.com/').post :body => "some data"
75
-
76
+
76
77
  # ...
77
78
  }
78
79
 
@@ -83,8 +84,14 @@ to the client, it is passed to the stream callback for you to operate on.
83
84
  EventMachine.run {
84
85
  http = EventMachine::HttpRequest.new('http://www.website.com/').get
85
86
  http.stream { |chunk| print chunk }
87
+ }
86
88
 
87
- # ...
89
+ == Streaming file from disk
90
+ Allows you to efficiently stream a (large) file from disk via EventMachine's FileStream interface.
91
+
92
+ EventMachine.run {
93
+ http = EventMachine::HttpRequest.new('http://www.website.com/').post :file => 'largefile.txt'
94
+ http.callback { |chunk| puts "Upload finished!" }
88
95
  }
89
96
 
90
97
  == Proxy example
@@ -97,6 +104,15 @@ Full transparent proxy support with support for SSL tunneling.
97
104
  :authorization => ['username', 'password'] # authorization is optional
98
105
  }
99
106
 
107
+ == Auto-follow 3xx redirects
108
+ Specify the max depth of redirects to follow, default is 0.
109
+
110
+ EventMachine.run {
111
+ http = EventMachine::HttpRequest.new('http://www.google.com/').get :redirect => 1
112
+ http.callback { p http.last_effective_url }
113
+ }
114
+
115
+
100
116
  == WebSocket example
101
117
  Bi-directional communication with WebSockets: simply pass in a ws:// resource and the client will
102
118
  negotiate the connection upgrade for you. On successfull handshake the callback is invoked, and
@@ -106,7 +122,7 @@ server at will by calling the "send" method!
106
122
 
107
123
  EventMachine.run {
108
124
  http = EventMachine::HttpRequest.new("ws://yourservice.com/websocket").get :timeout => 0
109
-
125
+
110
126
  http.errback { puts "oops" }
111
127
  http.callback {
112
128
  puts "WebSocket connected!"
@@ -117,4 +133,6 @@ server at will by calling the "send" method!
117
133
  puts "Recieved: #{msg}"
118
134
  http.send "Pong: #{msg}"
119
135
  }
136
+
137
+ http.disconnect { puts "oops, dropped connection?" }
120
138
  }
data/Rakefile CHANGED
@@ -35,7 +35,7 @@ task :ragel do
35
35
  end
36
36
 
37
37
  task :spec do
38
- sh 'spec spec/*_spec.rb'
38
+ sh 'spec spec/*_spec.rb'
39
39
  end
40
40
 
41
41
  def make(makedir)
@@ -55,8 +55,8 @@ def setup_extension(dir, extension)
55
55
  "#{ext}/extconf.rb",
56
56
  "#{ext}/Makefile",
57
57
  "lib"
58
- ]
59
-
58
+ ]
59
+
60
60
  task "lib" do
61
61
  directory "lib"
62
62
  end
@@ -92,13 +92,14 @@ begin
92
92
  gemspec.email = "ilya@igvita.com"
93
93
  gemspec.homepage = "http://github.com/igrigorik/em-http-request"
94
94
  gemspec.authors = ["Ilya Grigorik"]
95
+ gemspec.required_ruby_version = ">= 1.8.6"
95
96
  gemspec.extensions = ["ext/buffer/extconf.rb" , "ext/http11_client/extconf.rb"]
96
97
  gemspec.add_dependency('eventmachine', '>= 0.12.9')
97
98
  gemspec.add_dependency('addressable', '>= 2.0.0')
98
99
  gemspec.rubyforge_project = "em-http-request"
99
100
  gemspec.files = FileList[`git ls-files`.split]
100
101
  end
101
-
102
+
102
103
  Jeweler::GemcutterTasks.new
103
104
  rescue LoadError
104
105
  puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.7
1
+ 0.2.9
@@ -0,0 +1,97 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{em-http-request}
8
+ s.version = "0.2.9"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Ilya Grigorik"]
12
+ s.date = %q{2010-07-07}
13
+ s.description = %q{EventMachine based, async HTTP Request interface}
14
+ s.email = %q{ilya@igvita.com}
15
+ s.extensions = ["ext/buffer/extconf.rb", "ext/http11_client/extconf.rb"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "em-http-request.gemspec",
27
+ "examples/fetch.rb",
28
+ "examples/fibered-http.rb",
29
+ "examples/oauth-tweet.rb",
30
+ "examples/websocket-handler.rb",
31
+ "examples/websocket-server.rb",
32
+ "ext/buffer/em_buffer.c",
33
+ "ext/buffer/extconf.rb",
34
+ "ext/http11_client/ext_help.h",
35
+ "ext/http11_client/extconf.rb",
36
+ "ext/http11_client/http11_client.c",
37
+ "ext/http11_client/http11_parser.c",
38
+ "ext/http11_client/http11_parser.h",
39
+ "ext/http11_client/http11_parser.rl",
40
+ "lib/em-http-request.rb",
41
+ "lib/em-http.rb",
42
+ "lib/em-http/client.rb",
43
+ "lib/em-http/core_ext/bytesize.rb",
44
+ "lib/em-http/core_ext/hash.rb",
45
+ "lib/em-http/decoders.rb",
46
+ "lib/em-http/http_options.rb",
47
+ "lib/em-http/mock.rb",
48
+ "lib/em-http/multi.rb",
49
+ "lib/em-http/request.rb",
50
+ "spec/fixtures/google.ca",
51
+ "spec/hash_spec.rb",
52
+ "spec/helper.rb",
53
+ "spec/mock_spec.rb",
54
+ "spec/multi_spec.rb",
55
+ "spec/request_spec.rb",
56
+ "spec/stallion.rb",
57
+ "spec/stub_server.rb"
58
+ ]
59
+ s.homepage = %q{http://github.com/igrigorik/em-http-request}
60
+ s.rdoc_options = ["--charset=UTF-8"]
61
+ s.require_paths = ["lib"]
62
+ s.required_ruby_version = Gem::Requirement.new(">= 1.8.6")
63
+ s.rubyforge_project = %q{em-http-request}
64
+ s.rubygems_version = %q{1.3.6}
65
+ s.summary = %q{EventMachine based, async HTTP Request interface}
66
+ s.test_files = [
67
+ "spec/hash_spec.rb",
68
+ "spec/helper.rb",
69
+ "spec/mock_spec.rb",
70
+ "spec/multi_spec.rb",
71
+ "spec/request_spec.rb",
72
+ "spec/stallion.rb",
73
+ "spec/stub_server.rb",
74
+ "examples/fetch.rb",
75
+ "examples/fibered-http.rb",
76
+ "examples/oauth-tweet.rb",
77
+ "examples/websocket-handler.rb",
78
+ "examples/websocket-server.rb"
79
+ ]
80
+
81
+ if s.respond_to? :specification_version then
82
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
83
+ s.specification_version = 3
84
+
85
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
86
+ s.add_runtime_dependency(%q<eventmachine>, [">= 0.12.9"])
87
+ s.add_runtime_dependency(%q<addressable>, [">= 2.0.0"])
88
+ else
89
+ s.add_dependency(%q<eventmachine>, [">= 0.12.9"])
90
+ s.add_dependency(%q<addressable>, [">= 2.0.0"])
91
+ end
92
+ else
93
+ s.add_dependency(%q<eventmachine>, [">= 0.12.9"])
94
+ s.add_dependency(%q<addressable>, [">= 2.0.0"])
95
+ end
96
+ end
97
+
data/examples/fetch.rb CHANGED
@@ -21,7 +21,7 @@ EM.run do
21
21
  EM.stop if pending < 1
22
22
  }
23
23
  http.errback {
24
- puts "#{url}\n" + http.errors.join("\n")
24
+ puts "#{url}\n" + http.error
25
25
 
26
26
  pending -= 1
27
27
  EM.stop if pending < 1
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'lib/em-http'
3
+
4
+ module KBHandler
5
+ include EM::Protocols::LineText2
6
+
7
+ def receive_line(data)
8
+ p "Want to send: #{data}"
9
+ p "Error status: #{$http.error?}"
10
+ $http.send(data)
11
+ p "After send"
12
+ end
13
+ end
14
+
15
+ EventMachine.run {
16
+ $http = EventMachine::HttpRequest.new("ws://localhost:8080/").get :timeout => 0
17
+
18
+ $http.disconnect { puts 'oops' }
19
+ $http.callback {
20
+ puts "WebSocket connected!"
21
+ }
22
+
23
+ $http.stream { |msg|
24
+ puts "Recieved: #{msg}"
25
+ }
26
+
27
+ EM.open_keyboard(KBHandler)
28
+ }
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'em-websocket'
3
+
4
+ EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |ws|
5
+ ws.onopen { ws.send "Hello Client!"}
6
+ ws.onmessage { |msg| p "got: #{msg}"; ws.send "Pong: #{msg}" }
7
+ ws.onclose { puts "WebSocket closed" }
8
+ end
@@ -29,15 +29,15 @@
29
29
  #define PURGE_INTERVAL 10
30
30
 
31
31
  struct buffer {
32
- time_t last_purged_at;
32
+ time_t last_purged_at;
33
33
  unsigned size, node_size;
34
34
  struct buffer_node *head, *tail;
35
35
  struct buffer_node *pool_head, *pool_tail;
36
-
36
+
37
37
  };
38
38
 
39
39
  struct buffer_node {
40
- time_t last_used_at;
40
+ time_t last_used_at;
41
41
  unsigned start, end;
42
42
  struct buffer_node *next;
43
43
  unsigned char data[0];
@@ -72,7 +72,7 @@ static void buffer_copy(struct buffer *buf, char *str, unsigned len);
72
72
  static int buffer_read_from(struct buffer *buf, int fd);
73
73
  static int buffer_write_to(struct buffer *buf, int fd);
74
74
 
75
- /*
75
+ /*
76
76
  * High speed buffering geared towards non-blocking I/O.
77
77
  *
78
78
  * Data is stored in a byte queue implemented as a linked list of equal size
@@ -94,8 +94,8 @@ void Init_em_buffer()
94
94
  rb_define_method(cEm_Buffer, "append", Em_Buffer_append, 1);
95
95
  rb_define_method(cEm_Buffer, "prepend", Em_Buffer_prepend, 1);
96
96
  rb_define_method(cEm_Buffer, "read", Em_Buffer_read, -1);
97
- rb_define_method(cEm_Buffer, "to_str", Em_Buffer_to_str, 0);
98
- rb_define_method(cEm_Buffer, "read_from", Em_Buffer_read_from, 1);
97
+ rb_define_method(cEm_Buffer, "to_str", Em_Buffer_to_str, 0);
98
+ rb_define_method(cEm_Buffer, "read_from", Em_Buffer_read_from, 1);
99
99
  rb_define_method(cEm_Buffer, "write_to", Em_Buffer_write_to, 1);
100
100
  }
101
101
 
@@ -118,7 +118,7 @@ static void Em_Buffer_free(struct buffer *buf)
118
118
  /**
119
119
  * call-seq:
120
120
  * EventMachine::Buffer.new(size = DEFAULT_NODE_SIZE) -> EventMachine::Buffer
121
- *
121
+ *
122
122
  * Create a new EventMachine::Buffer with linked segments of the given size
123
123
  */
124
124
  static VALUE Em_Buffer_initialize(int argc, VALUE *argv, VALUE self)
@@ -147,7 +147,7 @@ static VALUE Em_Buffer_initialize(int argc, VALUE *argv, VALUE self)
147
147
  /**
148
148
  * call-seq:
149
149
  * EventMachine::Buffer#clear -> nil
150
- *
150
+ *
151
151
  * Clear all data from the EventMachine::Buffer
152
152
  */
153
153
  static VALUE Em_Buffer_clear(VALUE self)
@@ -163,10 +163,10 @@ static VALUE Em_Buffer_clear(VALUE self)
163
163
  /**
164
164
  * call-seq:
165
165
  * EventMachine::Buffer#size -> Integer
166
- *
166
+ *
167
167
  * Return the size of the buffer in bytes
168
168
  */
169
- static VALUE Em_Buffer_size(VALUE self)
169
+ static VALUE Em_Buffer_size(VALUE self)
170
170
  {
171
171
  struct buffer *buf;
172
172
  Data_Get_Struct(self, struct buffer, buf);
@@ -177,21 +177,21 @@ static VALUE Em_Buffer_size(VALUE self)
177
177
  /**
178
178
  * call-seq:
179
179
  * EventMachine::Buffer#empty? -> Boolean
180
- *
180
+ *
181
181
  * Is the buffer empty?
182
182
  */
183
- static VALUE Em_Buffer_empty(VALUE self)
183
+ static VALUE Em_Buffer_empty(VALUE self)
184
184
  {
185
185
  struct buffer *buf;
186
186
  Data_Get_Struct(self, struct buffer, buf);
187
187
 
188
- return buf->size > 0 ? Qfalse : Qtrue;
188
+ return buf->size > 0 ? Qfalse : Qtrue;
189
189
  }
190
190
 
191
191
  /**
192
192
  * call-seq:
193
193
  * EventMachine::Buffer#append(data) -> String
194
- *
194
+ *
195
195
  * Append the given data to the end of the buffer
196
196
  */
197
197
  static VALUE Em_Buffer_append(VALUE self, VALUE data)
@@ -209,7 +209,7 @@ static VALUE Em_Buffer_append(VALUE self, VALUE data)
209
209
  /**
210
210
  * call-seq:
211
211
  * EventMachine::Buffer#prepend(data) -> String
212
- *
212
+ *
213
213
  * Prepend the given data to the beginning of the buffer
214
214
  */
215
215
  static VALUE Em_Buffer_prepend(VALUE self, VALUE data)
@@ -226,7 +226,7 @@ static VALUE Em_Buffer_prepend(VALUE self, VALUE data)
226
226
  /**
227
227
  * call-seq:
228
228
  * EventMachine::Buffer#read(length = nil) -> String
229
- *
229
+ *
230
230
  * Read the specified abount of data from the buffer. If no value
231
231
  * is given the entire contents of the buffer are returned. Any data
232
232
  * read from the buffer is cleared.
@@ -263,31 +263,31 @@ static VALUE Em_Buffer_read(int argc, VALUE *argv, VALUE self)
263
263
  /**
264
264
  * call-seq:
265
265
  * EventMachine::Buffer#to_str -> String
266
- *
266
+ *
267
267
  * Convert the Buffer to a String. The original buffer is unmodified.
268
268
  */
269
269
  static VALUE Em_Buffer_to_str(VALUE self) {
270
- VALUE str;
271
- struct buffer *buf;
272
-
273
- Data_Get_Struct(self, struct buffer, buf);
274
-
275
- str = rb_str_new(0, buf->size);
276
- buffer_copy(buf, RSTRING_PTR(str), buf->size);
277
-
270
+ VALUE str;
271
+ struct buffer *buf;
272
+
273
+ Data_Get_Struct(self, struct buffer, buf);
274
+
275
+ str = rb_str_new(0, buf->size);
276
+ buffer_copy(buf, RSTRING_PTR(str), buf->size);
277
+
278
278
  return str;
279
279
  }
280
280
 
281
281
  /**
282
282
  * call-seq:
283
283
  * EventMachine::Buffer#read_from(io) -> Integer
284
- *
284
+ *
285
285
  * Perform a nonblocking read of the the given IO object and fill
286
286
  * the buffer with any data received. The call will read as much
287
287
  * data as it can until the read would block.
288
288
  */
289
289
  static VALUE Em_Buffer_read_from(VALUE self, VALUE io) {
290
- struct buffer *buf;
290
+ struct buffer *buf;
291
291
  #if HAVE_RB_IO_T
292
292
  rb_io_t *fptr;
293
293
  #else
@@ -298,20 +298,24 @@ static VALUE Em_Buffer_read_from(VALUE self, VALUE io) {
298
298
  GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
299
299
  rb_io_set_nonblock(fptr);
300
300
 
301
+ #ifdef HAVE_RB_IO_FD
302
+ return INT2NUM(buffer_read_from(buf, rb_io_fd(io)));
303
+ #else
301
304
  return INT2NUM(buffer_read_from(buf, FPTR_TO_FD(fptr)));
305
+ #endif
302
306
  }
303
307
 
304
308
  /**
305
309
  * call-seq:
306
310
  * EventMachine::Buffer#write_to(io) -> Integer
307
- *
311
+ *
308
312
  * Perform a nonblocking write of the buffer to the given IO object.
309
313
  * As much data as possible is written until the call would block.
310
314
  * Any data which is written is removed from the buffer.
311
315
  */
312
316
  static VALUE Em_Buffer_write_to(VALUE self, VALUE io) {
313
317
  struct buffer *buf;
314
- #if HAVE_RB_IO_T
318
+ #if HAVE_RB_IO_T
315
319
  rb_io_t *fptr;
316
320
  #else
317
321
  OpenFile *fptr;
@@ -321,11 +325,16 @@ static VALUE Em_Buffer_write_to(VALUE self, VALUE io) {
321
325
  GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
322
326
  rb_io_set_nonblock(fptr);
323
327
 
324
- return INT2NUM(buffer_write_to(buf, FPTR_TO_FD(fptr)));
328
+ #ifdef HAVE_RB_IO_FD
329
+ return INT2NUM(buffer_read_from(buf, rb_io_fd(io)));
330
+ #else
331
+ return INT2NUM(buffer_read_from(buf, FPTR_TO_FD(fptr)));
332
+ #endif
333
+
325
334
  }
326
335
 
327
336
  /*
328
- * Ruby bindings end here. Below is the actual implementation of
337
+ * Ruby bindings end here. Below is the actual implementation of
329
338
  * the underlying data structures.
330
339
  */
331
340
 
@@ -338,8 +347,8 @@ static struct buffer *buffer_new(void)
338
347
  buf->head = buf->tail = buf->pool_head = buf->pool_tail = 0;
339
348
  buf->size = 0;
340
349
  buf->node_size = DEFAULT_NODE_SIZE;
341
- time(&buf->last_purged_at);
342
-
350
+ time(&buf->last_purged_at);
351
+
343
352
  return buf;
344
353
  }
345
354
 
@@ -359,7 +368,7 @@ static void buffer_clear(struct buffer *buf)
359
368
  }
360
369
 
361
370
  /* Free a buffer */
362
- static void buffer_free(struct buffer *buf)
371
+ static void buffer_free(struct buffer *buf)
363
372
  {
364
373
  struct buffer_node *tmp;
365
374
 
@@ -381,11 +390,11 @@ static void buffer_gc(struct buffer *buf)
381
390
  time_t now;
382
391
  time(&now);
383
392
 
384
- /* Only purge if we've passed the purge interval */
385
- if(now - buf->last_purged_at < PURGE_INTERVAL)
386
- return;
387
-
388
- buf->last_purged_at = now;
393
+ /* Only purge if we've passed the purge interval */
394
+ if(now - buf->last_purged_at < PURGE_INTERVAL)
395
+ return;
396
+
397
+ buf->last_purged_at = now;
389
398
 
390
399
  while(buf->pool_head && now - buf->pool_head->last_used_at >= MAX_AGE) {
391
400
  tmp = buf->pool_head;
@@ -394,7 +403,7 @@ static void buffer_gc(struct buffer *buf)
394
403
  }
395
404
 
396
405
  if(!buf->pool_head)
397
- buf->pool_tail = 0;
406
+ buf->pool_tail = 0;
398
407
  }
399
408
 
400
409
  /* Create a new buffer_node (or pull one from the memory pool) */
@@ -494,11 +503,11 @@ static void buffer_append(struct buffer *buf, char *str, unsigned len)
494
503
  while(len > 0) {
495
504
  nbytes = buf->node_size - buf->tail->end;
496
505
  if(len < nbytes) nbytes = len;
497
-
506
+
498
507
  memcpy(buf->tail->data + buf->tail->end, str, nbytes);
499
- str += nbytes;
508
+ str += nbytes;
500
509
  len -= nbytes;
501
-
510
+
502
511
  buf->tail->end += nbytes;
503
512
 
504
513
  if(len > 0) {
@@ -541,7 +550,7 @@ static void buffer_copy(struct buffer *buf, char *str, unsigned len)
541
550
  unsigned nbytes;
542
551
  struct buffer_node *node;
543
552
 
544
- node = buf->head;
553
+ node = buf->head;
545
554
  while(node && len > 0) {
546
555
  nbytes = node->end - node->start;
547
556
  if(len < nbytes) nbytes = len;
@@ -551,7 +560,7 @@ static void buffer_copy(struct buffer *buf, char *str, unsigned len)
551
560
  len -= nbytes;
552
561
 
553
562
  if(node->start + nbytes == node->end)
554
- node = node->next;
563
+ node = node->next;
555
564
  }
556
565
  }
557
566
 
@@ -596,7 +605,7 @@ static int buffer_write_to(struct buffer *buf, int fd)
596
605
  /* Append data to the front of the buffer */
597
606
  static int buffer_read_from(struct buffer *buf, int fd)
598
607
  {
599
- int bytes_read, total_bytes_read = 0;
608
+ int bytes_read, total_bytes_read = 0;
600
609
  unsigned nbytes;
601
610
 
602
611
  /* Empty list needs initialized */
@@ -605,26 +614,26 @@ static int buffer_read_from(struct buffer *buf, int fd)
605
614
  buf->tail = buf->head;
606
615
  }
607
616
 
608
- do {
609
- nbytes = buf->node_size - buf->tail->end;
610
- bytes_read = read(fd, buf->tail->data + buf->tail->end, nbytes);
611
-
612
- if(bytes_read < 1) {
613
- if(errno != EAGAIN)
617
+ do {
618
+ nbytes = buf->node_size - buf->tail->end;
619
+ bytes_read = read(fd, buf->tail->data + buf->tail->end, nbytes);
620
+
621
+ if(bytes_read < 1) {
622
+ if(errno != EAGAIN)
614
623
  rb_sys_fail("read");
615
-
616
- return total_bytes_read;
617
- }
618
-
619
- total_bytes_read += bytes_read;
620
- buf->tail->end += nbytes;
621
- buf->size += nbytes;
622
-
623
- if(buf->tail->end == buf->node_size) {
624
+
625
+ return total_bytes_read;
626
+ }
627
+
628
+ total_bytes_read += bytes_read;
629
+ buf->tail->end += nbytes;
630
+ buf->size += nbytes;
631
+
632
+ if(buf->tail->end == buf->node_size) {
624
633
  buf->tail->next = buffer_node_new(buf);
625
634
  buf->tail = buf->tail->next;
626
- }
627
- } while(bytes_read == nbytes);
628
-
629
- return total_bytes_read;
635
+ }
636
+ } while(bytes_read == nbytes);
637
+
638
+ return total_bytes_read;
630
639
  }