|
17 | 17 | #include "ngx_http_lua_output.h"
|
18 | 18 | #include "ngx_http_lua_contentby.h"
|
19 | 19 | #include "ngx_http_lua_probe.h"
|
| 20 | +#include "ngx_http_lua_event.h" |
20 | 21 |
|
21 | 22 |
|
22 | 23 | static int ngx_http_lua_socket_tcp(lua_State *L);
|
@@ -159,6 +160,12 @@ static void ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c);
|
159 | 160 | static int ngx_http_lua_ssl_free_session(lua_State *L);
|
160 | 161 | #endif
|
161 | 162 | static void ngx_http_lua_socket_tcp_close_connection(ngx_connection_t *c);
|
| 163 | +static ngx_int_t ngx_http_lua_socket_tcp_block_conn(ngx_http_request_t *r, |
| 164 | + ngx_http_lua_socket_tcp_upstream_t *u); |
| 165 | +static ngx_int_t ngx_http_lua_socket_tcp_block_write(ngx_http_request_t *r, |
| 166 | + ngx_http_lua_socket_tcp_upstream_t *u); |
| 167 | +static ngx_int_t ngx_http_lua_socket_tcp_block_read(ngx_http_request_t *r, |
| 168 | + ngx_http_lua_socket_tcp_upstream_t *u); |
162 | 169 |
|
163 | 170 |
|
164 | 171 | enum {
|
@@ -446,7 +453,7 @@ ngx_http_lua_socket_tcp(lua_State *L)
|
446 | 453 | return luaL_error(L, "no ctx found");
|
447 | 454 | }
|
448 | 455 |
|
449 |
| - ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_YIELDABLE); |
| 456 | + /* ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_YIELDABLE); */ |
450 | 457 |
|
451 | 458 | lua_createtable(L, 5 /* narr */, 1 /* nrec */);
|
452 | 459 | lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask(
|
@@ -888,7 +895,7 @@ ngx_http_lua_socket_tcp_connect(lua_State *L)
|
888 | 895 | return luaL_error(L, "no ctx found");
|
889 | 896 | }
|
890 | 897 |
|
891 |
| - ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_YIELDABLE); |
| 898 | + /* ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_YIELDABLE); */ |
892 | 899 |
|
893 | 900 | luaL_checktype(L, 1, LUA_TTABLE);
|
894 | 901 |
|
@@ -1477,11 +1484,16 @@ ngx_http_lua_socket_resolve_retval_handler(ngx_http_request_t *r,
|
1477 | 1484 | u->writer.last = &u->writer.out;
|
1478 | 1485 | #endif
|
1479 | 1486 |
|
1480 |
| - ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); |
| 1487 | + dd("setting data to %p", u); |
1481 | 1488 |
|
1482 |
| - coctx = ctx->cur_co_ctx; |
| 1489 | + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); |
1483 | 1490 |
|
1484 |
| - dd("setting data to %p", u); |
| 1491 | + if (rc == NGX_AGAIN && !(ctx->context & NGX_HTTP_LUA_CONTEXT_YIELDABLE)) { |
| 1492 | + rc = ngx_http_lua_socket_tcp_block_conn(r, u); |
| 1493 | + if (rc == NGX_ERROR) { |
| 1494 | + return ngx_http_lua_socket_conn_error_retval_handler(r, u, L); |
| 1495 | + } |
| 1496 | + } |
1485 | 1497 |
|
1486 | 1498 | if (rc == NGX_OK) {
|
1487 | 1499 | ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
@@ -1517,6 +1529,8 @@ ngx_http_lua_socket_resolve_retval_handler(ngx_http_request_t *r,
|
1517 | 1529 |
|
1518 | 1530 | /* rc == NGX_AGAIN */
|
1519 | 1531 |
|
| 1532 | + coctx = ctx->cur_co_ctx; |
| 1533 | + |
1520 | 1534 | ngx_http_lua_cleanup_pending_operation(coctx);
|
1521 | 1535 | coctx->cleanup = ngx_http_lua_coctx_cleanup;
|
1522 | 1536 | coctx->data = u;
|
@@ -1780,6 +1794,10 @@ ngx_http_lua_socket_tcp_sslhandshake(lua_State *L)
|
1780 | 1794 |
|
1781 | 1795 | dd("ngx_ssl_handshake returned %d", (int) rc);
|
1782 | 1796 |
|
| 1797 | + if (rc == NGX_AGAIN && !(ctx->context & NGX_HTTP_LUA_CONTEXT_YIELDABLE)) { |
| 1798 | + /* Do something */ |
| 1799 | + } |
| 1800 | + |
1783 | 1801 | if (rc == NGX_AGAIN) {
|
1784 | 1802 | if (c->write->timer_set) {
|
1785 | 1803 | ngx_del_timer(c->write);
|
@@ -2105,6 +2123,10 @@ ngx_http_lua_socket_tcp_receive_helper(ngx_http_request_t *r,
|
2105 | 2123 |
|
2106 | 2124 | rc = ngx_http_lua_socket_tcp_read(r, u);
|
2107 | 2125 |
|
| 2126 | + if (rc == NGX_AGAIN && !(ctx->context & NGX_HTTP_LUA_CONTEXT_YIELDABLE)) { |
| 2127 | + rc = ngx_http_lua_socket_tcp_block_read(r, u); |
| 2128 | + } |
| 2129 | + |
2108 | 2130 | if (rc == NGX_ERROR) {
|
2109 | 2131 | dd("read failed: %d", (int) u->ft_type);
|
2110 | 2132 | rc = ngx_http_lua_socket_tcp_receive_retval_handler(r, u, L);
|
@@ -2917,6 +2939,10 @@ ngx_http_lua_socket_tcp_send(lua_State *L)
|
2917 | 2939 |
|
2918 | 2940 | dd("socket send returned %d", (int) rc);
|
2919 | 2941 |
|
| 2942 | + if (rc == NGX_AGAIN && !(ctx->context & NGX_HTTP_LUA_CONTEXT_YIELDABLE)) { |
| 2943 | + rc = ngx_http_lua_socket_tcp_block_write(r, u); |
| 2944 | + } |
| 2945 | + |
2920 | 2946 | if (rc == NGX_ERROR) {
|
2921 | 2947 | return ngx_http_lua_socket_write_error_retval_handler(r, u, L);
|
2922 | 2948 | }
|
@@ -4499,6 +4525,10 @@ ngx_http_lua_socket_receiveuntil_iterator(lua_State *L)
|
4499 | 4525 |
|
4500 | 4526 | rc = ngx_http_lua_socket_tcp_read(r, u);
|
4501 | 4527 |
|
| 4528 | + if (rc == NGX_AGAIN && !(ctx->context & NGX_HTTP_LUA_CONTEXT_YIELDABLE)) { |
| 4529 | + rc = ngx_http_lua_socket_tcp_block_read(r, u); |
| 4530 | + } |
| 4531 | + |
4502 | 4532 | if (rc == NGX_ERROR) {
|
4503 | 4533 | dd("read failed: %d", (int) u->ft_type);
|
4504 | 4534 | rc = ngx_http_lua_socket_tcp_receive_retval_handler(r, u, L);
|
@@ -6115,6 +6145,143 @@ ngx_http_lua_coctx_cleanup(void *data)
|
6115 | 6145 | }
|
6116 | 6146 |
|
6117 | 6147 |
|
| 6148 | +static ngx_int_t |
| 6149 | +ngx_http_lua_socket_tcp_block_conn(ngx_http_request_t *r, |
| 6150 | + ngx_http_lua_socket_tcp_upstream_t *u) |
| 6151 | +{ |
| 6152 | + ngx_int_t rc; |
| 6153 | + ngx_msec_t delta; |
| 6154 | + ngx_connection_t *c = u->peer.connection; |
| 6155 | + ngx_msec_t timer = u->connect_timeout; |
| 6156 | + |
| 6157 | + ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); |
| 6158 | + ngx_http_lua_kqueue_set_event(c->write, NGX_WRITE_EVENT); |
| 6159 | + |
| 6160 | + delta = ngx_current_msec; |
| 6161 | + |
| 6162 | + rc = ngx_http_lua_kqueue_process_events(r, timer); |
| 6163 | + |
| 6164 | + if (rc == NGX_ERROR) { |
| 6165 | + ngx_http_lua_socket_handle_conn_error(r, u, |
| 6166 | + NGX_HTTP_LUA_SOCKET_FT_ERROR); |
| 6167 | + |
| 6168 | + return rc; |
| 6169 | + } |
| 6170 | + |
| 6171 | + ngx_time_update(); |
| 6172 | + |
| 6173 | + if (ngx_current_msec - delta >= timer) { |
| 6174 | + ngx_http_lua_socket_handle_conn_error(r, u, |
| 6175 | + NGX_HTTP_LUA_SOCKET_FT_TIMEOUT); |
| 6176 | + |
| 6177 | + return NGX_ERROR; |
| 6178 | + } |
| 6179 | + |
| 6180 | + return NGX_OK; |
| 6181 | +} |
| 6182 | + |
| 6183 | + |
| 6184 | +static ngx_int_t |
| 6185 | +ngx_http_lua_socket_tcp_block_write(ngx_http_request_t *r, |
| 6186 | + ngx_http_lua_socket_tcp_upstream_t *u) |
| 6187 | +{ |
| 6188 | + int rc; |
| 6189 | + ngx_msec_t delta; |
| 6190 | + ngx_connection_t *c = u->peer.connection; |
| 6191 | + ngx_msec_t timer = u->connect_timeout; |
| 6192 | + |
| 6193 | + ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); |
| 6194 | + ngx_http_lua_kqueue_set_event(c->write, NGX_WRITE_EVENT); |
| 6195 | + |
| 6196 | + delta = ngx_current_msec; |
| 6197 | + |
| 6198 | + rc = ngx_http_lua_kqueue_process_events(r, timer); |
| 6199 | + |
| 6200 | + if (rc == NGX_ERROR) { |
| 6201 | + ngx_http_lua_socket_handle_write_error(r, u, |
| 6202 | + NGX_HTTP_LUA_SOCKET_FT_ERROR); |
| 6203 | + |
| 6204 | + return rc; |
| 6205 | + } |
| 6206 | + |
| 6207 | + ngx_time_update(); |
| 6208 | + |
| 6209 | + if (ngx_current_msec - delta >= timer) { |
| 6210 | + ngx_http_lua_socket_handle_write_error(r, u, |
| 6211 | + NGX_HTTP_LUA_SOCKET_FT_TIMEOUT); |
| 6212 | + |
| 6213 | + return NGX_ERROR; |
| 6214 | + } |
| 6215 | + |
| 6216 | + return NGX_OK; |
| 6217 | +} |
| 6218 | + |
| 6219 | + |
| 6220 | +static ngx_int_t |
| 6221 | +ngx_http_lua_socket_tcp_block_read(ngx_http_request_t *r, |
| 6222 | + ngx_http_lua_socket_tcp_upstream_t *u) |
| 6223 | +{ |
| 6224 | + int rc; |
| 6225 | + ngx_msec_t delta; |
| 6226 | + ngx_event_t *rev; |
| 6227 | + ngx_connection_t *c = u->peer.connection; |
| 6228 | + ngx_msec_t timer = u->connect_timeout; |
| 6229 | + |
| 6230 | + ngx_http_lua_kqueue_set_event(c->read, NGX_READ_EVENT); |
| 6231 | + |
| 6232 | + delta = ngx_current_msec; |
| 6233 | + |
| 6234 | + for (;;) { |
| 6235 | + |
| 6236 | + ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); |
| 6237 | + |
| 6238 | + if (c->read->timer_set) { |
| 6239 | + ngx_del_timer(c->read); |
| 6240 | + } |
| 6241 | + |
| 6242 | + rc = ngx_http_lua_kqueue_process_events(r, timer); |
| 6243 | + if (rc == NGX_ERROR) { |
| 6244 | + ngx_http_lua_socket_handle_read_error(r, u, |
| 6245 | + NGX_HTTP_LUA_SOCKET_FT_ERROR); |
| 6246 | + |
| 6247 | + return rc; |
| 6248 | + } |
| 6249 | + |
| 6250 | + ngx_time_update(); |
| 6251 | + |
| 6252 | + /* timeout */ |
| 6253 | + if (ngx_current_msec - delta >= timer) { |
| 6254 | + ngx_http_lua_socket_handle_read_error(r, u, |
| 6255 | + NGX_HTTP_LUA_SOCKET_FT_TIMEOUT); |
| 6256 | + |
| 6257 | + return NGX_ERROR; |
| 6258 | + } |
| 6259 | + |
| 6260 | + timer -= ngx_current_msec - delta; |
| 6261 | + |
| 6262 | + if (u->buffer.start != NULL) { |
| 6263 | + rev = c->read; |
| 6264 | + |
| 6265 | + rev->ready = 1; |
| 6266 | +#if (NGX_HAVE_KQUEUE || NGX_HAVE_EPOLLRDHUP) |
| 6267 | + rev->available = 1; |
| 6268 | +#endif |
| 6269 | + |
| 6270 | + rc = ngx_http_lua_socket_tcp_read(r, u); |
| 6271 | + |
| 6272 | + if (rc == NGX_ERROR || rc == NGX_OK) { |
| 6273 | + return rc; |
| 6274 | + } |
| 6275 | + |
| 6276 | + /* NGX_AGAIN, continue in loop*/ |
| 6277 | + } |
| 6278 | + } |
| 6279 | + |
| 6280 | + /* unreachable */ |
| 6281 | + return NGX_ERROR; |
| 6282 | +} |
| 6283 | + |
| 6284 | + |
6118 | 6285 | #if (NGX_HTTP_SSL)
|
6119 | 6286 |
|
6120 | 6287 | static int
|
|
0 commit comments