async-http 0.38.0 → 0.38.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89e83fd398432897302be1ddbb07fad391a285216320e282e218c2faf07f4183
4
- data.tar.gz: c9f37f4776390db5b0d050845397d7b530b145b6072f062b453957944683d7d6
3
+ metadata.gz: 83a5e5bd7e766404f4011a11d61d6cfcc75d1cff40c1822895f21f71ccf91925
4
+ data.tar.gz: ecdde5ee1128a0ee9f947a1da217c683fda1c65c281dba0694ff72749a31ca9f
5
5
  SHA512:
6
- metadata.gz: 53f726aec29bd9130015446d9e05b5b11be437c85978f9cb6d22647ebd17dd033182e647dda82c31bfb42e14cf01b9c1b8bae904e781370564f33df390470916
7
- data.tar.gz: c698697b2d53e17a2321d430b01cd5746ef4eaf5623cb59b8a08200f86c4d3357037d85444c4141b23198bf4eba1aedd4915c8e79646717a761c02e8dd7d79b9
6
+ metadata.gz: ce5c4265e43776b208ef51ebcb5b54b84f0b86e7d8d52dbccf3905869fc6094ec88d74b6afb35eba557ffcae0699dae5f130e7b72f507ac989c28e2904e55fbb
7
+ data.tar.gz: 74b16c8ad259f0aaded61ef8094d26043354b717d299c3de04b2a4aab0169b74ebc2808f889ff284468a5ffabd4ad1a2f0e988dd67b268d3a8660303df9b7fe3
@@ -0,0 +1,70 @@
1
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'writable'
22
+
23
+ require 'async/clock'
24
+
25
+ module Async
26
+ module HTTP
27
+ module Body
28
+ # A dynamic body which you can write to and read from.
29
+ class Slowloris < Writable
30
+ class ThroughputError < StandardError
31
+ def initialize(throughput, minimum_throughput, time_since_last_write)
32
+ super("Slow write: #{throughput.round(1)}bytes/s less than required #{minimum_throughput.round}bytes/s.")
33
+ end
34
+ end
35
+
36
+ # In order for this implementation to work correctly, you need to use a LimitedQueue.
37
+ # @param minimum_throughput [Integer] the minimum bytes per second otherwise this body will be forcefully closed.
38
+ def initialize(*args, minimum_throughput: 1024, **options)
39
+ super(*args, **options)
40
+
41
+ @minimum_throughput = minimum_throughput
42
+
43
+ @last_write_at = nil
44
+ @last_chunk_size = nil
45
+ end
46
+
47
+ attr :minimum_throughput
48
+
49
+ # If #read is called regularly to maintain throughput, that is good. If #read is not called, that is a problem. Throughput is dependent on data being available, from #write, so it doesn't seem particularly problimatic to do this check in #write.
50
+ def write(chunk)
51
+ if @last_chunk_size
52
+ time_since_last_write = Async::Clock.now - @last_write_at
53
+ throughput = @last_chunk_size / time_since_last_write
54
+
55
+ if throughput < @minimum_throughput
56
+ error = ThroughputError.new(throughput, @minimum_throughput, time_since_last_write)
57
+
58
+ self.close(error)
59
+ end
60
+ end
61
+
62
+ super.tap do
63
+ @last_write_at = Async::Clock.now
64
+ @last_chunk_size = chunk&.bytesize
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -51,6 +51,9 @@ module Async
51
51
  return request.stream
52
52
  end
53
53
 
54
+ def close!(state)
55
+ end
56
+
54
57
  # @return [Stream] the promised stream, on which to send data.
55
58
  def push(path, headers = nil)
56
59
  push_headers = [
@@ -52,6 +52,10 @@ module Async
52
52
  return promise.stream
53
53
  end
54
54
 
55
+ def close!(state)
56
+ self.promises.enqueue(nil)
57
+ end
58
+
55
59
  # Notify anyone waiting on the response headers to be received (or failure).
56
60
  protected def notify!
57
61
  if @notification
@@ -43,6 +43,12 @@ module Async
43
43
  @delegate.create_promise_stream(headers, stream_id)
44
44
  end
45
45
 
46
+ def close!(state = :closed)
47
+ super
48
+
49
+ @delegate.close!(state)
50
+ end
51
+
46
52
  def send_body(body, task: Async::Task.current)
47
53
  # TODO Might need to stop this task when body is cancelled.
48
54
  @task = task.async do |subtask|
@@ -20,6 +20,6 @@
20
20
 
21
21
  module Async
22
22
  module HTTP
23
- VERSION = "0.38.0"
23
+ VERSION = "0.38.1"
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.38.0
4
+ version: 0.38.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-09 00:00:00.000000000 Z
11
+ date: 2019-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -161,6 +161,7 @@ files:
161
161
  - lib/async/http/body/readable.rb
162
162
  - lib/async/http/body/reader.rb
163
163
  - lib/async/http/body/rewindable.rb
164
+ - lib/async/http/body/slowloris.rb
164
165
  - lib/async/http/body/streamable.rb
165
166
  - lib/async/http/body/wrapper.rb
166
167
  - lib/async/http/body/writable.rb