1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
# Getting Started
This guide explains how to get started with `protocol-http1`, a low-level implementation of the HTTP/1 protocol for building HTTP clients and servers.
## Installation
Add the gem to your project:
```bash
$ bundle add protocol-http1
```
## Core Concepts
`protocol-http1` provides a low-level implementation of the HTTP/1 protocol with several core concepts:
- A {ruby Protocol::HTTP1::Connection} which represents the main entry point for creating HTTP/1.1 clients and servers.
- Integration with the `Protocol::HTTP::Body` classes for handling request and response bodies.
## Usage
`protocol-http1` can be used to build both HTTP clients and servers.
### HTTP Server
Here's a simple HTTP/1.1 server that responds to all requests with "Hello World":
```ruby
#!/usr/bin/env ruby
require "socket"
require "protocol/http1/connection"
require "protocol/http/body/buffered"
# Test with: curl http://localhost:8080/
Addrinfo.tcp("0.0.0.0", 8080).listen do |server|
loop do
client, address = server.accept
connection = Protocol::HTTP1::Connection.new(client)
# Read request:
while request = connection.read_request
authority, method, path, version, headers, body = request
# Write response:
connection.write_response(version, 200, [["content-type", "text/plain"]])
connection.write_body(version, Protocol::HTTP::Body::Buffered.wrap(["Hello World"]))
break unless connection.persistent
end
end
end
```
The server:
1. Creates a new {ruby Protocol::HTTP1::Connection} for each client connection.
2. Reads incoming requests using `read_request`.
3. Sends responses using `write_response` and `write_body`.
4. Supports persistent connections by checking `connection.persistent`.
### HTTP Client
Here's a simple HTTP/1.1 client that makes multiple requests:
```ruby
#!/usr/bin/env ruby
require "async"
require "async/http/endpoint"
require "protocol/http1/connection"
Async do
endpoint = Async::HTTP::Endpoint.parse("http://localhost:8080")
peer = endpoint.connect
puts "Connected to #{peer} #{peer.remote_address.inspect}"
# IO Buffering...
client = Protocol::HTTP1::Connection.new(peer)
puts "Writing request..."
3.times do
client.write_request("localhost", "GET", "/", "HTTP/1.1", [["Accept", "*/*"]])
client.write_body("HTTP/1.1", nil)
puts "Reading response..."
response = client.read_response("GET")
version, status, reason, headers, body = response
puts "Got response: #{response.inspect}"
puts body&.read
end
puts "Closing client..."
client.close
end
```
The client:
1. Creates a connection to a server using `Async::HTTP::Endpoint`.
2. Creates a {ruby Protocol::HTTP1::Connection} wrapper around the socket.
3. Sends requests using `write_request` and `write_body`.
4. Reads responses using `read_response`.
5. Properly closes the connection when done.
### Connection Management
The {ruby Protocol::HTTP1::Connection} handles:
- **Request/Response Parsing**: Automatically parses HTTP/1.1 request and response formats.
- **Persistent Connections**: Supports HTTP/1.1 keep-alive for multiple requests over one connection.
- **Body Handling**: Integrates with `Protocol::HTTP::Body` classes for streaming and buffered content.
- **Header Management**: Properly handles HTTP headers as arrays of key-value pairs.
|