async-http 0.52.0 → 0.52.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,86 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'async'
4
- require 'async/clock'
5
- require 'async/barrier'
6
- require 'async/semaphore'
7
- require_relative '../../lib/async/http/endpoint'
8
- require_relative '../../lib/async/http/client'
9
-
10
- Async do
11
- url = "https://static.openfoodfacts.org/data/en.openfoodfacts.org.products.csv"
12
-
13
- endpoint = Async::HTTP::Endpoint.parse(url)
14
- client = Async::HTTP::Client.new(endpoint)
15
-
16
- headers = {'user-agent' => 'curl/7.69.1', 'accept' => '*/*'}
17
-
18
- file = File.open("products.csv", "w")
19
- Async.logger.info(self) {"Saving download to #{Dir.pwd}"}
20
-
21
- begin
22
- response = client.head(endpoint.path, headers)
23
- content_length = nil
24
-
25
- if response.success?
26
- unless response.headers['accept-ranges'].include?('bytes')
27
- raise "Does not advertise support for accept-ranges: bytes!"
28
- end
29
-
30
- unless content_length = response.body&.length
31
- raise "Could not determine length of response!"
32
- end
33
- end
34
- ensure
35
- response&.close
36
- end
37
-
38
- Async.logger.info(self) {"Content length: #{content_length/(1024**2)}MiB"}
39
-
40
- parts = []
41
- offset = 0
42
- chunk_size = 1024*1024
43
-
44
- start_time = Async::Clock.now
45
- amount = 0
46
-
47
- while offset < content_length
48
- byte_range_start = offset
49
- byte_range_end = [offset + chunk_size, content_length].min
50
- parts << (byte_range_start...byte_range_end)
51
-
52
- offset += chunk_size
53
- end
54
-
55
- Async.logger.info(self) {"Breaking download into #{parts.size} parts..."}
56
-
57
- semaphore = Async::Semaphore.new(8)
58
- barrier = Async::Barrier.new(parent: semaphore)
59
-
60
- while !parts.empty?
61
- barrier.async do
62
- part = parts.shift
63
-
64
- Async.logger.info(self) {"Issuing range request range: bytes=#{part.min}-#{part.max}"}
65
-
66
- response = client.get(endpoint.path, [
67
- ["range", "bytes=#{part.min}-#{part.max-1}"],
68
- *headers
69
- ])
70
-
71
- if response.success?
72
- Async.logger.info(self) {"Got response: #{response}... writing data for #{part}."}
73
- written = file.pwrite(response.read, part.min)
74
-
75
- amount += written
76
-
77
- duration = Async::Clock.now - start_time
78
- Async.logger.info(self) {"Rate: #{((amount.to_f/(1024**2))/duration).round(2)}MiB/s"}
79
- end
80
- end
81
- end
82
-
83
- barrier.wait
84
- ensure
85
- client&.close
86
- end
@@ -1,3 +0,0 @@
1
-
2
- gem 'rack'
3
- gem 'falcon'
@@ -1,74 +0,0 @@
1
- GEM
2
- specs:
3
- async (1.24.2)
4
- console (~> 1.0)
5
- nio4r (~> 2.3)
6
- timers (~> 4.1)
7
- async-container (0.16.2)
8
- async (~> 1.0)
9
- async-io (~> 1.26)
10
- process-group
11
- async-http (0.50.5)
12
- async (~> 1.23)
13
- async-io (~> 1.27.0)
14
- async-pool (~> 0.2)
15
- protocol-http (~> 0.14.1)
16
- protocol-http1 (~> 0.10.0)
17
- protocol-http2 (~> 0.11.0)
18
- async-http-cache (0.1.2)
19
- async-http
20
- protocol-http (~> 0.14.4)
21
- async-io (1.27.4)
22
- async (~> 1.14)
23
- async-pool (0.2.0)
24
- async (~> 1.8)
25
- build-environment (1.13.0)
26
- coderay (1.1.2)
27
- console (1.8.2)
28
- falcon (0.35.6)
29
- async (~> 1.13)
30
- async-container (~> 0.16.0)
31
- async-http (~> 0.50.4)
32
- async-http-cache (~> 0.1.0)
33
- async-io (~> 1.22)
34
- build-environment (~> 1.13)
35
- localhost (~> 1.1)
36
- process-metrics (~> 0.1.0)
37
- rack (>= 1.0)
38
- samovar (~> 2.1)
39
- ffi (1.12.2)
40
- localhost (1.1.6)
41
- mapping (1.1.1)
42
- method_source (0.9.2)
43
- nio4r (2.5.2)
44
- process-group (1.2.1)
45
- process-terminal (~> 0.2.0)
46
- process-metrics (0.1.1)
47
- process-terminal (0.2.0)
48
- ffi
49
- protocol-hpack (1.4.2)
50
- protocol-http (0.14.4)
51
- protocol-http1 (0.10.2)
52
- protocol-http (~> 0.13)
53
- protocol-http2 (0.11.1)
54
- protocol-hpack (~> 1.4)
55
- protocol-http (~> 0.2)
56
- pry (0.12.2)
57
- coderay (~> 1.1.0)
58
- method_source (~> 0.9.0)
59
- rack (2.2.2)
60
- samovar (2.1.4)
61
- console (~> 1.0)
62
- mapping (~> 1.0)
63
- timers (4.3.0)
64
-
65
- PLATFORMS
66
- ruby
67
-
68
- DEPENDENCIES
69
- falcon
70
- pry
71
- rack
72
-
73
- BUNDLED WITH
74
- 1.17.3
@@ -1,3 +0,0 @@
1
- # Fetch
2
-
3
- This was an experiment to see how browsers handle bi-directional streaming.
@@ -1,28 +0,0 @@
1
-
2
- require 'rack'
3
-
4
- class Echo
5
- def initialize(app)
6
- @app = app
7
- end
8
-
9
- def call(env)
10
- request = Rack::Request.new(env)
11
-
12
- if request.path_info == "/echo"
13
- if output = request.body
14
- return [200, {}, output.body]
15
- else
16
- return [200, {}, ["Hello World?"]]
17
- end
18
- else
19
- return @app.call(env)
20
- end
21
- end
22
- end
23
-
24
- use Echo
25
-
26
- use Rack::Static, :urls => [''], :root => 'public', :index => 'index.html'
27
-
28
- run lambda{|env| [404, {}, []]}
@@ -1,23 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Streaming Fetch</title>
5
- </head>
6
- <body>
7
- <h1>Streams</h1>
8
-
9
- <button id="stopButton">Start</button>
10
-
11
- <h2>Sent</h2>
12
-
13
- <ul id="sent">
14
- </ul>
15
-
16
- <h2>Received</h2>
17
-
18
- <ul id="received">
19
- </ul>
20
-
21
- <script src="stream.js"></script>
22
- </body>
23
- </html>
@@ -1,56 +0,0 @@
1
- const inputStream = new ReadableStream({
2
- start(controller) {
3
- interval = setInterval(() => {
4
- let string = "Hello World!";
5
-
6
- // Add the string to the stream
7
- controller.enqueue(string);
8
-
9
- // show it on the screen
10
- let listItem = document.createElement('li');
11
- listItem.textContent = string;
12
- sent.appendChild(listItem);
13
- }, 10000);
14
-
15
- stopButton.addEventListener('click', function() {
16
- clearInterval(interval);
17
- controller.close();
18
- })
19
- },
20
- pull(controller) {
21
- // We don't really need a pull in this example
22
- },
23
- cancel() {
24
- // This is called if the reader cancels,
25
- // so we should stop generating strings
26
- clearInterval(interval);
27
- }
28
- });
29
-
30
- fetch("/echo", {method: 'POST', body: inputStream})
31
- .then(response => {
32
- const reader = response.body.getReader();
33
- const decoder = new TextDecoder("utf-8");
34
-
35
- function push() {
36
- reader.read().then(({done, value}) => {
37
- console.log("done:", done, "value:", value);
38
- const string = decoder.decode(value);
39
-
40
- // show it on the screen
41
- let listItem = document.createElement('li');
42
-
43
- if (done)
44
- listItem.textContent = "<EOF>"
45
- else
46
- listItem.textContent = string;
47
-
48
- received.appendChild(listItem);
49
-
50
- if (done) return;
51
- else push();
52
- });
53
- };
54
-
55
- push();
56
- });
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "async"
4
- require "async/clock"
5
- require "protocol/http/middleware"
6
- require_relative "../../lib/async/http"
7
-
8
- URL = "https://www.google.com/search"
9
- ENDPOINT = Async::HTTP::Endpoint.parse(URL)
10
-
11
- # Console.logger.enable(Async::IO::Stream, Console::Logger::DEBUG)
12
-
13
- class Google < Protocol::HTTP::Middleware
14
- def search(term)
15
- Async.logger.info(self) {"Searching for #{term}..."}
16
-
17
- self.get("/search?q=#{term}", {"user-agent" => "Hi Google!"})
18
- end
19
- end
20
-
21
- terms = %w{thoughtful fear size payment lethal modern recognise face morning sulky mountainous contain science snow uncle skirt truthful door travel snails closed rotten halting creator teeny-tiny beautiful cherries unruly level follow strip team things suggest pretty warm end cannon bad pig consider airport strengthen youthful fog three walk furry pickle moaning fax book ruddy sigh plate cakes shame stem faulty bushes dislike train sleet one colour behavior bitter suit count loutish squeak learn watery orange idiotic seat wholesale omniscient nostalgic arithmetic instruct committee puffy program cream cake whistle rely encourage war flagrant amusing fluffy prick utter wacky occur daily son check}
22
-
23
- if count = ENV.fetch('COUNT', 20)&.to_i
24
- terms = terms.first(count)
25
- end
26
-
27
- Async do |task|
28
- client = Async::HTTP::Client.new(ENDPOINT)
29
- google = Google.new(client)
30
-
31
- google.search("null").finish
32
-
33
- duration = Async::Clock.measure do
34
- counts = terms.map do |term|
35
- task.async do
36
- response = google.search(term)
37
- [term, response.read.scan(term).count]
38
- end
39
- end.map(&:wait).to_h
40
-
41
- Async.logger.info(self, name: 'counts') {counts}
42
- end
43
-
44
- Async.logger.info(self, name: 'duration') {duration}
45
- ensure
46
- google.close
47
- end
@@ -1,38 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # $LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
4
- # $LOAD_PATH.unshift(File.expand_path("../../http-protocol/lib", __dir__))
5
-
6
- require 'async'
7
- require 'async/logger'
8
- require 'async/http/client'
9
- require 'async/http/endpoint'
10
-
11
- # Async.logger.level = Logger::DEBUG
12
-
13
- Async do |task|
14
- endpoint = Async::HTTP::Endpoint.parse("https://www.google.com")
15
-
16
- client = Async::HTTP::Client.new(endpoint)
17
-
18
- headers = {
19
- 'accept' => 'text/html',
20
- }
21
-
22
- request = Protocol::HTTP::Request.new(client.scheme, "www.google.com", "GET", "/search?q=cats", headers)
23
-
24
- puts "Sending request..."
25
- response = client.call(request)
26
-
27
- puts "Reading response status=#{response.status}..."
28
-
29
- if body = response.body
30
- while chunk = body.read
31
- puts chunk.size
32
- end
33
- end
34
-
35
- response.close
36
-
37
- puts "Finish reading response."
38
- end
@@ -1,28 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'async'
4
- require 'async/http/internet'
5
-
6
- Async do |parent|
7
- internet = Async::HTTP::Internet.new
8
- connection = nil
9
-
10
- child = parent.async do
11
- response = internet.get("https://utopia-falcon-heroku.herokuapp.com/beer/index")
12
- connection = response.connection
13
-
14
- response.each do |chunk|
15
- Async.logger.info(response) {chunk}
16
- end
17
- ensure
18
- Async.logger.info(response) {"Closing response..."}
19
- response&.close
20
- end
21
-
22
- parent.sleep(5)
23
-
24
- Async.logger.info(parent) {"Killing #{child}..."}
25
- child.stop
26
- ensure
27
- internet&.close
28
- end
@@ -1,5 +0,0 @@
1
-
2
- source 'https://rubygems.org'
3
-
4
- gem "trenni"
5
- gem "async-http"
@@ -1,35 +0,0 @@
1
-
2
- require 'trenni/template'
3
-
4
- require 'async'
5
- require 'async/http/body/writable'
6
-
7
- # The template, using inline text. The sleep could be anything - database query, HTTP request, redis, etc.
8
- buffer = Trenni::Buffer.new(<<-EOF)
9
- The "\#{self[:count]} bottles of \#{self[:drink]} on the wall" song!
10
-
11
- <?r self[:count].downto(1) do |index| ?>
12
- \#{index} bottles of \#{self[:drink]} on the wall,
13
- \#{index} bottles of \#{self[:drink]},
14
- take one down, and pass it around,
15
- \#{index - 1} bottles of \#{self[:drink]} on the wall.
16
-
17
- <?r Async::Task.current.sleep(1) ?>
18
- <?r end ?>
19
- EOF
20
-
21
- template = Trenni::Template.new(buffer)
22
-
23
- Async do
24
- body = Async::HTTP::Body::Writable.new
25
-
26
- generator = Async do
27
- template.to_string({count: 100, drink: 'coffee'}, body)
28
- end
29
-
30
- while chunk = body.read
31
- $stdout.write chunk
32
- end
33
-
34
- generator.wait
35
- end.wait
@@ -1,39 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
4
-
5
- require 'async'
6
- require 'async/http/body/file'
7
- require 'async/http/body/delayed'
8
- require 'async/http/client'
9
- require 'async/http/endpoint'
10
-
11
- Async do
12
- endpoint = Async::HTTP::Endpoint.parse("http://localhost:9222")
13
- client = Async::HTTP::Client.new(endpoint, Async::HTTP::Protocol::HTTP2)
14
-
15
- headers = [
16
- ['accept', 'text/plain'],
17
- ]
18
-
19
- body = Async::HTTP::Body::Delayed.new(Async::HTTP::Body::File.open("data.txt", block_size: 32))
20
-
21
- response = client.post(endpoint.path, headers, body)
22
-
23
- puts response.status
24
-
25
- # response.read -> string
26
- # response.each {|chunk| ...}
27
- # response.close (forcefully ignore data)
28
- # body = response.finish (read and buffer response)
29
- # response.save("echo.txt")
30
-
31
- response.each do |chunk|
32
- puts chunk.inspect
33
- end
34
-
35
- ensure
36
- client.close if client
37
- end
38
-
39
- puts "Done."