or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

connection.mdevents.mdexceptions.mdindex.mdstates.md

connection.mddocs/

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

```