0
# Connection Management
1
2
Core connection handling and state management for HTTP/1.1 protocol implementation. The Connection class serves as the central state machine that manages the HTTP/1.1 protocol flow for both client and server roles.
3
4
## Capabilities
5
6
### Connection Class
7
8
The main class encapsulating HTTP connection state and protocol logic. Manages parsing, generation, and state transitions for HTTP/1.1 messages.
9
10
```python { .api }
11
class Connection:
12
def __init__(self, our_role, max_incomplete_event_size=16384):
13
"""
14
Create a new HTTP/1.1 connection state machine.
15
16
Args:
17
our_role: Either h11.CLIENT or h11.SERVER
18
max_incomplete_event_size (int): Maximum bytes to buffer for incomplete events (default: 16384)
19
"""
20
```
21
22
**Usage Example:**
23
```python
24
import h11
25
26
# Create client connection
27
client_conn = h11.Connection(h11.CLIENT)
28
29
# Create server connection
30
server_conn = h11.Connection(h11.SERVER, max_incomplete_event_size=8192)
31
```
32
33
### Event Processing
34
35
Parse incoming data into HTTP events and convert events into bytes for transmission.
36
37
```python { .api }
38
def next_event(self):
39
"""
40
Parse the next event from the receive buffer.
41
42
Returns:
43
Union[Event, Type[NEED_DATA], Type[PAUSED]]:
44
- An Event object if a complete event was parsed
45
- NEED_DATA if more data is needed from the socket
46
- PAUSED if connection is paused and needs start_next_cycle()
47
"""
48
49
def send(self, event):
50
"""
51
Convert an event to bytes for transmission over the wire.
52
53
Args:
54
event (Event): Event object to serialize
55
56
Returns:
57
Optional[bytes]: Bytes to send, or None if event should not be sent
58
59
Raises:
60
LocalProtocolError: If event is not valid for current connection state
61
"""
62
63
def send_with_data_passthrough(self, event):
64
"""
65
Like send() but preserves Data event objects in the output.
66
67
Args:
68
event (Event): Event object to serialize
69
70
Returns:
71
Optional[List[bytes]]: List of byte chunks to send, or None
72
73
Note:
74
Data events are returned as-is rather than serialized to bytes.
75
"""
76
```
77
78
### Data Handling
79
80
Manage incoming data and connection lifecycle.
81
82
```python { .api }
83
def receive_data(self, data):
84
"""
85
Add incoming data to the internal receive buffer.
86
87
Args:
88
data (bytes): Raw bytes received from socket
89
90
Note:
91
Call next_event() after this to parse events from the buffer.
92
"""
93
94
def start_next_cycle(self):
95
"""
96
Reset the connection state for a new request/response cycle.
97
98
Note:
99
Only call when both sides have finished the current cycle.
100
Required after receiving PAUSED from next_event().
101
"""
102
103
def send_failed(self):
104
"""
105
Notify the state machine that sending failed.
106
107
Note:
108
Call this if you were unable to send data returned by send().
109
Transitions connection to ERROR state.
110
"""
111
```
112
113
### Connection Properties
114
115
Access connection state and metadata.
116
117
```python { .api }
118
@property
119
def states(self):
120
"""
121
Dict mapping roles to their current states.
122
123
Returns:
124
Dict[Role, State]: Current states for CLIENT and SERVER roles
125
"""
126
127
@property
128
def our_state(self):
129
"""
130
Current state of our role.
131
132
Returns:
133
State: Current state (IDLE, SEND_BODY, DONE, etc.)
134
"""
135
136
@property
137
def their_state(self):
138
"""
139
Current state of the peer's role.
140
141
Returns:
142
State: Peer's current state
143
"""
144
145
our_role: Role
146
"""
147
Our role in the connection - either CLIENT or SERVER.
148
149
Attribute:
150
Role: Either CLIENT or SERVER
151
"""
152
153
their_role: Role
154
"""
155
The peer's role in the connection - either CLIENT or SERVER (opposite of our_role).
156
157
Attribute:
158
Role: Either CLIENT or SERVER
159
"""
160
161
their_http_version: Optional[bytes]
162
"""
163
HTTP version used by the peer.
164
165
Attribute:
166
Optional[bytes]: HTTP version like b"1.1" or b"1.0", or None if not determined yet
167
"""
168
169
@property
170
def they_are_waiting_for_100_continue(self):
171
"""
172
Whether peer is waiting for 100-continue response.
173
174
Returns:
175
bool: True if peer sent Expect: 100-continue header
176
"""
177
178
client_is_waiting_for_100_continue: bool
179
"""
180
Whether client is waiting for 100-continue response.
181
182
Attribute:
183
bool: True if client is waiting for 100-continue
184
"""
185
186
@property
187
def trailing_data(self):
188
"""
189
Get any unprocessed data after connection closed.
190
191
Returns:
192
Tuple[bytes, bool]:
193
- bytes: Unprocessed data
194
- bool: Whether connection was closed
195
"""
196
```
197
198
### Connection Control Sentinels
199
200
Special sentinel values returned by next_event() to indicate connection state.
201
202
```python { .api }
203
class NEED_DATA:
204
"""
205
Sentinel returned by next_event() when more data is needed.
206
207
Usage:
208
event = conn.next_event()
209
if event is h11.NEED_DATA:
210
# Read more data from socket and call receive_data()
211
"""
212
213
class PAUSED:
214
"""
215
Sentinel returned by next_event() when connection is paused.
216
217
Usage:
218
event = conn.next_event()
219
if event is h11.PAUSED:
220
# Call start_next_cycle() to begin new request/response
221
"""
222
```
223
224
## Usage Patterns
225
226
### Basic Client Pattern
227
228
```python
229
import h11
230
231
conn = h11.Connection(h11.CLIENT)
232
233
# Send request
234
req = h11.Request(method=b'GET', target=b'/', headers=[(b'host', b'example.com')])
235
data = conn.send(req)
236
send_to_socket(data)
237
238
# End request
239
eom = h11.EndOfMessage()
240
data = conn.send(eom)
241
send_to_socket(data)
242
243
# Receive response
244
while True:
245
data = receive_from_socket()
246
conn.receive_data(data)
247
248
event = conn.next_event()
249
if event is h11.NEED_DATA:
250
continue
251
elif isinstance(event, h11.Response):
252
print(f"Status: {event.status_code}")
253
elif isinstance(event, h11.EndOfMessage):
254
break
255
```
256
257
### Basic Server Pattern
258
259
```python
260
import h11
261
262
conn = h11.Connection(h11.SERVER)
263
264
# Receive request
265
while True:
266
data = receive_from_socket()
267
conn.receive_data(data)
268
269
event = conn.next_event()
270
if event is h11.NEED_DATA:
271
continue
272
elif isinstance(event, h11.Request):
273
print(f"Method: {event.method}, Target: {event.target}")
274
elif isinstance(event, h11.EndOfMessage):
275
break
276
277
# Send response
278
resp = h11.Response(status_code=200, headers=[(b'content-type', b'text/plain')])
279
data = conn.send(resp)
280
send_to_socket(data)
281
282
# Send body
283
body_data = h11.Data(data=b'Hello, World!')
284
data = conn.send(body_data)
285
send_to_socket(data)
286
287
# End response
288
eom = h11.EndOfMessage()
289
data = conn.send(eom)
290
send_to_socket(data)
291
```