diff options
| -rw-r--r-- | docs/http.html | 36 | ||||
| -rw-r--r-- | src/http.lua | 10 |
2 files changed, 38 insertions, 8 deletions
diff --git a/docs/http.html b/docs/http.html index c6423ba..15f9c26 100644 --- a/docs/http.html +++ b/docs/http.html | |||
| @@ -136,7 +136,8 @@ http.<b>request{</b><br> | |||
| 136 | [proxy = <i>string</i>,]<br> | 136 | [proxy = <i>string</i>,]<br> |
| 137 | [redirect = <i>boolean</i>,]<br> | 137 | [redirect = <i>boolean</i>,]<br> |
| 138 | [create = <i>function</i>,]<br> | 138 | [create = <i>function</i>,]<br> |
| 139 | [maxredirects = <i>number</i>]<br> | 139 | [maxredirects = <i>number</i>,]<br> |
| 140 | [headers_callback = <i>function</i>]<br> | ||
| 140 | <b>}</b> | 141 | <b>}</b> |
| 141 | </p> | 142 | </p> |
| 142 | 143 | ||
| @@ -189,6 +190,39 @@ function from automatically following 301 or 302 server redirect messages;</li> | |||
| 189 | <li><tt>maxredirects</tt>: An optional number specifying the maximum number of | 190 | <li><tt>maxredirects</tt>: An optional number specifying the maximum number of |
| 190 | redirects to follow. Defaults to <tt>5</tt> if not specified. A boolean | 191 | redirects to follow. Defaults to <tt>5</tt> if not specified. A boolean |
| 191 | <tt>false</tt> value means no maximum (unlimited).</li> | 192 | <tt>false</tt> value means no maximum (unlimited).</li> |
| 193 | <li><tt>headers_callback</tt>: An optional function, called once per request | ||
| 194 | right after the headers have been received (this | ||
| 195 | is after any redirect has already been followed, so it only fires for the | ||
| 196 | final response) and before the response body would be read. It is called | ||
| 197 | as: <tt>ok, new_sink = headers_callback(code, headers, status, sock)</tt>, where | ||
| 198 | <tt>sock</tt> is the raw socket used for the request (the | ||
| 199 | <a href="tcp.html#socket.tcp"><tt>socket.tcp</tt></a>-like object returned | ||
| 200 | by <tt>create</tt>, or the default one). It is not called for an HTTP/0.9 | ||
| 201 | reply (no headers at all), for a <tt>408</tt> response, or for a response | ||
| 202 | that is going to be redirected. | ||
| 203 | <br> | ||
| 204 | The callback should return two values, <tt>ok</tt> and a second value whose | ||
| 205 | meaning depends on <tt>ok</tt>: | ||
| 206 | <ul> | ||
| 207 | <li>If <tt>ok</tt> is falsy, the second value is used as an error | ||
| 208 | message: the connection is closed and <tt>request</tt> returns | ||
| 209 | <tt><b>nil</b></tt> followed by that message, just like any other request | ||
| 210 | failure.</li> | ||
| 211 | <li>If <tt>ok</tt> is truthy, the request continues normally. If the | ||
| 212 | second value is also provided, it replaces <tt>sink</tt> for reading the | ||
| 213 | response body; otherwise the original sink is used.</li> | ||
| 214 | </ul> | ||
| 215 | Note that a swapped-in sink is only ever read from when the response | ||
| 216 | actually has a body to receive: for a <tt>HEAD</tt> request or a | ||
| 217 | <tt>204</tt>/<tt>304</tt> response there is nothing to read regardless of | ||
| 218 | which sink is set. | ||
| 219 | <br> | ||
| 220 | This makes it possible to inspect headers before committing to read a | ||
| 221 | body -- for example to reject a response early based on | ||
| 222 | <tt>content-type</tt> or <tt>content-length</tt>, to pick a different | ||
| 223 | sink depending on the headers, or -- combined with the raw | ||
| 224 | <tt>sock</tt> -- to hand the socket off for a protocol upgrade | ||
| 225 | such as WebSockets (<tt>101 Switching Protocols</tt>).</li> | ||
| 192 | </ul> | 226 | </ul> |
| 193 | 227 | ||
| 194 | <p class="return"> | 228 | <p class="return"> |
diff --git a/src/http.lua b/src/http.lua index 6cdc90a..3e2c789 100644 --- a/src/http.lua +++ b/src/http.lua | |||
| @@ -360,7 +360,7 @@ local trequest, tredirect | |||
| 360 | headers = reqt.headers, | 360 | headers = reqt.headers, |
| 361 | proxy = reqt.proxy, | 361 | proxy = reqt.proxy, |
| 362 | maxredirects = reqt.maxredirects, | 362 | maxredirects = reqt.maxredirects, |
| 363 | response_headers = reqt.response_headers, | 363 | headers_callback = reqt.headers_callback, |
| 364 | nredirects = (reqt.nredirects or 0) + 1, | 364 | nredirects = (reqt.nredirects or 0) + 1, |
| 365 | create = reqt.create | 365 | create = reqt.create |
| 366 | } | 366 | } |
| @@ -405,12 +405,8 @@ end | |||
| 405 | end | 405 | end |
| 406 | -- here we are finally done | 406 | -- here we are finally done |
| 407 | -- provide an opportunity to abort or replace the sink based on the response headers | 407 | -- provide an opportunity to abort or replace the sink based on the response headers |
| 408 | if nreqt.response_headers then | 408 | if nreqt.headers_callback then |
| 409 | local abort, sink = nreqt.response_headers(code, headers, status) | 409 | local _, sink = h.try(nreqt.headers_callback(code, headers, status, h.c)) |
| 410 | if abort then | ||
| 411 | h:close() | ||
| 412 | return 1, code, headers, status | ||
| 413 | end | ||
| 414 | if sink then | 410 | if sink then |
| 415 | nreqt.sink = sink | 411 | nreqt.sink = sink |
| 416 | end | 412 | end |
