You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Lua HTTP client cosocket driver for [OpenResty](http://openresty.org/) / [ngx_lua](https://github.com/chaoslawful/lua-nginx-module).
3
4
4
-
Lua HTTP client driver for [ngx_lua](https://github.com/chaoslawful/lua-nginx-module) based on the cosocket API. Supports HTTP 1.0 and 1.1, including chunked transfer encoding for response bodies, and provides a streaming interface to the body irrespective of transfer encoding.
5
+
# Status
5
6
6
-
## Status
7
+
Ready for testing. Probably production ready in most cases, though not yet proven in the wild. Please check the issues list and let me know if you have any problems / questions.
7
8
8
-
This is newish, but works and passes tests. Please send any design feedback or actual bugs on the issues page.
9
+
# Features
10
+
11
+
* HTTP 1.0 and 1.1
12
+
* Streaming interface to reading bodies using coroutines, for predictable memory usage in Lua land.
13
+
* Alternative simple interface for singleshot requests without manual connection step.
@@ -179,13 +116,13 @@ An optional Lua table can be specified as the last argument to this method to sp
179
116
*`pool`
180
117
: Specifies a custom name for the connection pool being used. If omitted, then the connection pool name will be generated from the string template `<host>:<port>` or `<unix-socket-path>`.
181
118
182
-
####set_timeout
119
+
## set_timeout
183
120
184
121
`syntax: httpc:set_timeout(time)`
185
122
186
123
Sets the timeout (in ms) protection for subsequent operations, including the `connect` method.
@@ -197,49 +134,28 @@ Only call this method in the place you would have called the `close` method inst
197
134
198
135
Note that calling this instead of `close` is "safe" in that it will conditionally close depending on the type of request. Specifically, a `1.0` request without `Connection: Keep-Alive` will be closed, as will a `1.1` request with `Connection: Close`.
199
136
200
-
In case of success, returns `1`. In case of errors, returns `nil` with a string describing the error. In the case where the conneciton is conditionally closed as described above, returns `2` and the error string `connection must be closed`.
137
+
In case of success, returns `1`. In case of errors, returns `nil, err`. In the case where the conneciton is conditionally closed as described above, returns `2` and the error string `connection must be closed`.
201
138
202
-
####get_reused_times
139
+
## get_reused_times
203
140
204
141
`syntax: times, err = httpc:get_reused_times()`
205
142
206
143
This method returns the (successfully) reused times for the current connection. In case of error, it returns `nil` and a string describing the error.
207
144
208
145
If the current connection does not come from the built-in connection pool, then this method always returns `0`, that is, the connection has never been reused (yet). If the connection comes from the connection pool, then the return value is always non-zero. So this method can also be used to determine if the current connection comes from the pool.
209
146
210
-
####close
147
+
## close
211
148
212
149
`syntax: ok, err = http:close()`
213
150
214
151
Closes the current connection and returns the status.
215
152
216
153
In case of success, returns `1`. In case of errors, returns `nil` with a string describing the error.
Returns an iterator function which can be used to read the downstream request body in a chunked fashion. This iterator can be used as the value for the body field in request params.
223
-
224
-
```lua
225
-
localreq_reader=httpc:get_client_body_reader()
226
-
227
-
repeat
228
-
localchunk, err=req_reader(8192)
229
-
iferrthen
230
-
ngx.log(ngx.ERR, err)
231
-
break
232
-
end
233
-
234
-
ifchunkthen
235
-
-- process
236
-
end
237
-
untilnotchunk
238
-
```
239
155
240
-
###Requesting
156
+
# Requesting
241
157
242
-
####request
158
+
## request
243
159
244
160
`syntax: res, err = httpc:request(params)`
245
161
@@ -251,7 +167,7 @@ The `params` table accepts the following fields:
251
167
*`method` The HTTP method string.
252
168
*`path` The path string.
253
169
*`headers` A table of request headers.
254
-
*`body` The request body as a string or an iterator function.
170
+
*`body` The request body as a string, or an iterator function (see [get_client_body_reader](#get_client_body_reader)).
255
171
256
172
When the request is successful, `res` will contain the following fields:
257
173
@@ -262,7 +178,7 @@ When the request is successful, `res` will contain the following fields:
262
178
*`read_body` A method to read the entire body into a string.
263
179
*`read_trailers` A method to merge any trailers underneath the headers, after reading the body.
264
180
265
-
#####res.body_reader
181
+
## res.body_reader
266
182
267
183
The `body_reader` iterator can be used to stream the response body in chunk sizes of your choosing, as follows:
268
184
@@ -286,21 +202,21 @@ If the reader is called with no arguments, the behaviour depends on the type of
286
202
287
203
Note that the size provided is actually a **maximum** size. So in the chunked transfer case, you may get chunks smaller than the size you ask, as a remainder of the actual HTTP chunks.
288
204
289
-
#####res:read_body
205
+
## res:read_body
290
206
291
207
`syntax: body, err = res:read_body()`
292
208
293
-
Reads the body into a local string.
209
+
Reads the entire body into a local string.
294
210
295
211
296
-
#####res:read_trailers
212
+
## res:read_trailers
297
213
298
214
`syntax: res:read_trailers()`
299
215
300
-
This merges any trailers headers underneath the `res.headers` table itself.
216
+
This merges any trailers underneath the `res.headers` table itself. Must be called after reading the body.
This method works as per the [request](#request) method above, but `params` is instead a table of param tables. Each request is sent in order, and `responses` is returned as a table of response handles. For example:
239
+
240
+
```lua
241
+
localresponses=httpc:request_pipeline{
242
+
{
243
+
path="/b",
244
+
},
245
+
{
246
+
path="/c",
247
+
},
248
+
{
249
+
path="/d",
250
+
}
251
+
}
252
+
253
+
fori,rinipairs(responses) do
254
+
ngx.say(r.status)
255
+
ngx.say(r:read_body())
256
+
end
257
+
```
258
+
259
+
Due to the nature of pipelining, no responses are actually read until you attempt to use the response fields (status / headers etc). And since the responses are read off in order, you must read the entire body (and any trailers if you have them), before attempting to read the next response.
260
+
319
261
320
-
#### parse_uri
262
+
# Utility
263
+
264
+
## parse_uri
321
265
322
266
`syntax: local scheme, host, port, path = unpack(httpc:parse_uri(uri))`
323
267
324
268
This is a convenience function allowing one to more easily use the generic interface, when the input data is a URI.
Returns an iterator function which can be used to read the downstream client request body in a streaming fashion. This iterator can also be used as the value for the body field in request params, allowing one to stream the request body into a proxied upstream request.
276
+
277
+
```lua
278
+
localreq_reader=httpc:get_client_body_reader()
279
+
280
+
repeat
281
+
localchunk, err=req_reader(8192)
282
+
iferrthen
283
+
ngx.log(ngx.ERR, err)
284
+
break
285
+
end
286
+
287
+
ifchunkthen
288
+
-- process
289
+
end
290
+
untilnotchunk
291
+
```
292
+
293
+
# Author
328
294
329
295
James Hurst <james@pintsized.co.uk>
330
296
331
297
Originally started life based on https://github.com/bakins/lua-resty-http-simple. Cosocket docs and implementation borrowed from the other lua-resty-* cosocket modules.
332
298
333
299
334
-
##Licence
300
+
# Licence
335
301
336
302
This module is licensed under the 2-clause BSD license.
0 commit comments