Skip to content

Commit bb87b1c

Browse files
committed
Bump minor version.
1 parent 1328c71 commit bb87b1c

File tree

6 files changed

+246
-8
lines changed

6 files changed

+246
-8
lines changed

context/getting-started.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# Getting Started
2+
3+
This guide explains how to get started with `Async::HTTP`.
4+
5+
## Installation
6+
7+
Add the gem to your project:
8+
9+
~~~ bash
10+
$ bundle add async-http
11+
~~~
12+
13+
## Core Concepts
14+
15+
- {ruby Async::HTTP::Client} is the main class for making HTTP requests.
16+
- {ruby Async::HTTP::Internet} provides a simple interface for making requests to any server "on the internet".
17+
- {ruby Async::HTTP::Server} is the main class for handling HTTP requests.
18+
- {ruby Async::HTTP::Endpoint} can parse HTTP URLs in order to create a client or server.
19+
- [`protocol-http`](https://github.com/socketry/protocol-http) provides the abstract HTTP protocol interfaces.
20+
21+
## Usage
22+
23+
### Making a Request
24+
25+
To make a request, use {ruby Async::HTTP::Internet} and call the appropriate method:
26+
27+
~~~ ruby
28+
require 'async/http/internet/instance'
29+
30+
Sync do
31+
Async::HTTP::Internet.get("https://httpbin.org/get") do |response|
32+
puts response.read
33+
end
34+
end
35+
~~~
36+
37+
The following methods are supported:
38+
39+
~~~ ruby
40+
Async::HTTP::Internet.methods(false)
41+
# => [:patch, :options, :connect, :post, :get, :delete, :head, :trace, :put]
42+
~~~
43+
44+
Using a block will automatically close the response when the block completes. If you want to keep the response open, you can manage it manually:
45+
46+
~~~ ruby
47+
require 'async/http/internet/instance'
48+
49+
Sync do
50+
response = Async::HTTP::Internet.get("https://httpbin.org/get")
51+
puts response.read
52+
ensure
53+
response&.close
54+
end
55+
~~~
56+
57+
As responses are streamed, you must ensure it is closed when you are finished with it.
58+
59+
#### Persistence
60+
61+
By default, {ruby Async::HTTP::Internet} will create a {ruby Async::HTTP::Client} for each remote host you communicate with, and will keep those connections open for as long as possible. This is useful for reducing the latency of subsequent requests to the same host. When you exit the event loop, the connections will be closed automatically.
62+
63+
### Downloading a File
64+
65+
~~~ ruby
66+
require 'async/http/internet/instance'
67+
68+
Sync do
69+
# Issue a GET request to Google:
70+
response = Async::HTTP::Internet.get("https://www.google.com/search?q=kittens")
71+
72+
# Save the response body to a local file:
73+
response.save("/tmp/search.html")
74+
ensure
75+
response&.close
76+
end
77+
~~~
78+
79+
### Posting Data
80+
81+
To post data, use the `post` method:
82+
83+
~~~ ruby
84+
require 'async/http/internet/instance'
85+
86+
data = {'life' => 42}
87+
88+
Sync do
89+
# Prepare the request:
90+
headers = [['accept', 'application/json']]
91+
body = JSON.dump(data)
92+
93+
# Issues a POST request:
94+
response = Async::HTTP::Internet.post("https://httpbin.org/anything", headers, body)
95+
96+
# Save the response body to a local file:
97+
pp JSON.parse(response.read)
98+
ensure
99+
response&.close
100+
end
101+
~~~
102+
103+
For more complex scenarios, including HTTP APIs, consider using [async-rest](https://github.com/socketry/async-rest) instead.
104+
105+
### Timeouts
106+
107+
To set a timeout for a request, use the `Task#with_timeout` method:
108+
109+
~~~ ruby
110+
require 'async/http/internet/instance'
111+
112+
Sync do |task|
113+
# Request will timeout after 2 seconds
114+
task.with_timeout(2) do
115+
response = Async::HTTP::Internet.get "https://httpbin.org/delay/10"
116+
ensure
117+
response&.close
118+
end
119+
rescue Async::TimeoutError
120+
puts "The request timed out"
121+
end
122+
~~~
123+
124+
### Making a Server
125+
126+
To create a server, use an instance of {ruby Async::HTTP::Server}:
127+
128+
~~~ ruby
129+
require 'async/http'
130+
131+
endpoint = Async::HTTP::Endpoint.parse('http://localhost:9292')
132+
133+
Sync do |task|
134+
Async(transient: true) do
135+
server = Async::HTTP::Server.for(endpoint) do |request|
136+
::Protocol::HTTP::Response[200, {}, ["Hello World"]]
137+
end
138+
139+
server.run
140+
end
141+
142+
client = Async::HTTP::Client.new(endpoint)
143+
response = client.get("/")
144+
puts response.read
145+
ensure
146+
response&.close
147+
end
148+
~~~

context/index.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Automatically generated context index for Utopia::Project guides.
2+
# Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
3+
---
4+
description: A HTTP client and server library.
5+
metadata:
6+
documentation_uri: https://socketry.github.io/async-http/
7+
source_code_uri: https://github.com/socketry/async-http.git
8+
files:
9+
- path: getting-started.md
10+
title: Getting Started
11+
description: This guide explains how to get started with `Async::HTTP`.
12+
- path: testing.md
13+
title: Testing
14+
description: This guide explains how to use `Async::HTTP` clients and servers in
15+
your tests.

context/testing.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Testing
2+
3+
This guide explains how to use `Async::HTTP` clients and servers in your tests.
4+
5+
In general, you should avoid making real HTTP requests in your tests. Instead, you should use a mock server or a fake client.
6+
7+
## Mocking HTTP Responses
8+
9+
The mocking feature of `Async::HTTP` uses a real server running in a separate task, and routes all requests to it. This allows you to intercept requests and return custom responses, but still use the real HTTP client.
10+
11+
In order to enable this feature, you must create an instance of {ruby Async::HTTP::Mock::Endpoint} which will handle the requests.
12+
13+
~~~ ruby
14+
require 'async/http'
15+
require 'async/http/mock'
16+
17+
mock_endpoint = Async::HTTP::Mock::Endpoint.new
18+
19+
Sync do
20+
# Start a background server:
21+
server_task = Async(transient: true) do
22+
mock_endpoint.run do |request|
23+
# Respond to the request:
24+
::Protocol::HTTP::Response[200, {}, ["Hello, World"]]
25+
end
26+
end
27+
28+
endpoint = Async::HTTP::Endpoint.parse("https://www.google.com")
29+
mocked_endpoint = mock_endpoint.wrap(endpoint)
30+
client = Async::HTTP::Client.new(mocked_endpoint)
31+
32+
response = client.get("/")
33+
puts response.read
34+
# => "Hello, World"
35+
end
36+
~~~
37+
38+
## Transparent Mocking
39+
40+
Using your test framework's mocking capabilities, you can easily replace the `Async::HTTP::Client#new` with a method that returns a client with a mocked endpoint.
41+
42+
### Sus Integration
43+
44+
~~~ ruby
45+
require 'async/http'
46+
require 'async/http/mock'
47+
require 'sus/fixtures/async/reactor_context'
48+
49+
include Sus::Fixtures::Async::ReactorContext
50+
51+
let(:mock_endpoint) {Async::HTTP::Mock::Endpoint.new}
52+
53+
def before
54+
super
55+
56+
# Mock the HTTP client:
57+
mock(Async::HTTP::Client) do |mock|
58+
mock.wrap(:new) do |original, endpoint|
59+
original.call(mock_endpoint.wrap(endpoint))
60+
end
61+
end
62+
63+
# Run the mock server:
64+
Async(transient: true) do
65+
mock_endpoint.run do |request|
66+
::Protocol::HTTP::Response[200, {}, ["Hello, World"]]
67+
end
68+
end
69+
end
70+
71+
it "should perform a web request" do
72+
client = Async::HTTP::Client.new(Async::HTTP::Endpoint.parse("https://www.google.com"))
73+
response = client.get("/")
74+
# The response is mocked:
75+
expect(response.read).to be == "Hello, World"
76+
end
77+
~~~

lib/async/http/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55

66
module Async
77
module HTTP
8-
VERSION = "0.91.0"
8+
VERSION = "0.92.0"
99
end
1010
end

readme.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ Please see the [project documentation](https://socketry.github.io/async-http/) f
1616

1717
Please see the [project releases](https://socketry.github.io/async-http/releases/index) for all releases.
1818

19+
### v0.92.0
20+
21+
- **Breaking**: Remove `Async::HTTP::Reference`. Use `Protocol::URL::Reference` directly instead.
22+
1923
### v0.91.0
2024

2125
- Move all default trace providers into `traces/provider/async/http`.
@@ -53,12 +57,6 @@ Please see the [project releases](https://socketry.github.io/async-http/releases
5357
- Improved HTTP/1 connection handling.
5458
- The input stream is no longer closed when the output stream is closed.
5559

56-
### v0.76.0
57-
58-
- `Async::HTTP::Body::Writable` is moved to `Protocol::HTTP::Body::Writable`.
59-
- Remove `Async::HTTP::Body::Delayed` with no replacement.
60-
- Remove `Async::HTTP::Body::Slowloris` with no replacement.
61-
6260
## See Also
6361

6462
- [benchmark-http](https://github.com/socketry/benchmark-http) — A benchmarking tool to report on web server concurrency.

releases.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Releases
22

3-
## Unreleased
3+
## v0.92.0
44

55
- **Breaking**: Remove `Async::HTTP::Reference`. Use `Protocol::URL::Reference` directly instead.
66

0 commit comments

Comments
 (0)