Skip to content

Commit 9fbd7aa

Browse files
committed
Allow non blocking socket to be not ready on connection
1 parent bdfd189 commit 9fbd7aa

4 files changed

+113
-32
lines changed

src/ngx_http_redirectionio_module.c

+23-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ static ngx_int_t ngx_http_redirectionio_create_ctx_handler(ngx_http_request_t *r
2020
static ngx_int_t ngx_http_redirectionio_redirect_handler(ngx_http_request_t *r);
2121
static ngx_int_t ngx_http_redirectionio_log_handler(ngx_http_request_t *r);
2222

23+
static ngx_int_t ngx_http_redirectionio_write_match_action(ngx_event_t *wev);
2324
static void ngx_http_redirectionio_write_match_action_handler(ngx_event_t *wev);
2425
static void ngx_http_redirectionio_read_match_action_handler(ngx_event_t *rev, const char *action_serialized);
2526
static void ngx_http_redirectionio_log_callback(const char* log_str, const void* data, short level);
@@ -319,10 +320,17 @@ static ngx_int_t ngx_http_redirectionio_redirect_handler(ngx_http_request_t *r)
319320
if (ctx->matched_action_status == API_NOT_CALLED) {
320321
ctx->matched_action_status = API_WAITING;
321322
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http redirectionio call match action");
322-
ngx_http_redirectionio_write_match_action_handler(ctx->resource->peer.connection->write);
323+
status = ngx_http_redirectionio_write_match_action(ctx->resource->peer.connection->write);
324+
325+
if (status == NGX_AGAIN) {
326+
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[redirectionio] send again");
327+
ctx->resource->peer.connection->write->handler = ngx_http_redirectionio_write_match_action_handler;
328+
329+
return NGX_AGAIN;
330+
}
323331

324332
// Handle when direct error after write
325-
if (ctx->connection_error) {
333+
if (status != NGX_OK || ctx->connection_error) {
326334
if (ctx->resource != NULL) {
327335
ngx_http_redirectionio_release_resource(conf->connection_pool, ctx, 1);
328336
}
@@ -639,7 +647,7 @@ static char *ngx_http_redirectionio_set_header(ngx_conf_t *cf, ngx_command_t *cm
639647
return NGX_CONF_OK;
640648
}
641649

642-
static void ngx_http_redirectionio_write_match_action_handler(ngx_event_t *wev) {
650+
static ngx_int_t ngx_http_redirectionio_write_match_action(ngx_event_t *wev) {
643651
ngx_http_redirectionio_ctx_t *ctx;
644652
ngx_connection_t *c;
645653
ngx_http_request_t *r;
@@ -653,7 +661,18 @@ static void ngx_http_redirectionio_write_match_action_handler(ngx_event_t *wev)
653661
ngx_add_timer(c->read, conf->server.timeout);
654662
ctx->read_handler = ngx_http_redirectionio_read_match_action_handler;
655663

656-
ngx_http_redirectionio_protocol_send_match(c, r, ctx, &ctx->project_key);
664+
return ngx_http_redirectionio_protocol_send_match(c, r, ctx, &ctx->project_key);
665+
}
666+
667+
static void ngx_http_redirectionio_write_match_action_handler(ngx_event_t *wev) {
668+
ngx_int_t rv;
669+
670+
wev->handler = ngx_http_redirectionio_dummy_handler;
671+
rv = ngx_http_redirectionio_write_match_action(wev);
672+
673+
if (rv == NGX_AGAIN) {
674+
wev->handler = ngx_http_redirectionio_write_match_action_handler;
675+
}
657676
}
658677

659678
static void ngx_http_redirectionio_read_match_action_handler(ngx_event_t *rev, const char *action_serialized) {

src/ngx_http_redirectionio_module.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define API_NOT_CALLED 0
2121
#define API_WAITING 1
2222
#define API_CALLED 2
23+
#define API_CONNECTED 3
2324

2425
#define REDIRECTIONIO_PROTOCOL_VERSION_MAJOR 1
2526
#define REDIRECTIONIO_PROTOCOL_VERSION_MINOR 0
@@ -67,6 +68,7 @@ typedef struct {
6768
ngx_peer_connection_t peer;
6869
ngx_uint_t usage;
6970
ngx_pool_t *pool;
71+
void *data;
7072
} ngx_http_redirectionio_resource_t;
7173

7274
typedef struct {
@@ -91,10 +93,13 @@ typedef struct {
9193
} ngx_http_redirectionio_ctx_t;
9294

9395
typedef struct {
94-
ngx_str_t project_key;
95-
const char *log_serialized;
96+
ngx_str_t project_key;
97+
const char *log_serialized;
98+
ngx_http_redirectionio_resource_t *resource;
99+
ngx_reslist_t *reslist;
96100
} ngx_http_redirectionio_log_t;
97101

102+
void ngx_http_redirectionio_dummy_handler(ngx_event_t *wev);
98103
void ngx_http_redirectionio_read_dummy_handler(ngx_event_t *rev, const char *json_str);
99104

100105
ngx_int_t ngx_http_redirectionio_match_on_response_status_header_filter(ngx_http_request_t *r);
@@ -113,7 +118,7 @@ ngx_int_t ngx_http_redirectionio_pool_available_log_handler(ngx_reslist_t *resli
113118
void ngx_http_redirectionio_release_resource(ngx_reslist_t *reslist, ngx_http_redirectionio_ctx_t *ctx, ngx_uint_t in_error);
114119
void ngx_http_redirectionio_read_handler(ngx_event_t *rev);
115120

116-
void ngx_http_redirectionio_protocol_send_match(ngx_connection_t *c, ngx_http_request_t *r, ngx_http_redirectionio_ctx_t *ctx, ngx_str_t *project_key);
121+
ngx_int_t ngx_http_redirectionio_protocol_send_match(ngx_connection_t *c, ngx_http_request_t *r, ngx_http_redirectionio_ctx_t *ctx, ngx_str_t *project_key);
117122
ngx_int_t ngx_http_redirectionio_protocol_send_log(ngx_connection_t *c, ngx_http_redirectionio_log_t *log);
118123
ngx_http_redirectionio_log_t* ngx_http_redirectionio_protocol_create_log(ngx_http_request_t *r, ngx_http_redirectionio_ctx_t *ctx, ngx_str_t *project_key);
119124
void ngx_http_redirectionio_protocol_free_log(ngx_http_redirectionio_log_t *log);

src/ngx_http_redirectionio_module_pool.c

+47-11
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
static ngx_int_t ngx_http_redirectionio_get_connection(ngx_peer_connection_t *pc, void *data);
44

5-
static void ngx_http_redirectionio_dummy_handler(ngx_event_t *wev);
6-
75
static ngx_int_t ngx_http_redirectionio_read_uint32(ngx_connection_t *c, uint32_t *uint32);
86

97
static ngx_int_t ngx_http_redirectionio_read_string(ngx_connection_t *c, char *string, ssize_t buf_size, ssize_t *readed);
108

9+
static ngx_int_t ngx_http_redirectionio_write_log(ngx_event_t *wev);
10+
11+
static void ngx_http_redirectionio_write_log_handler(ngx_event_t *wev);
12+
1113
ngx_int_t ngx_http_redirectionio_pool_construct(void **rp, void *params) {
1214
ngx_pool_t *pool;
1315
ngx_http_redirectionio_resource_t *resource;
@@ -33,6 +35,7 @@ ngx_int_t ngx_http_redirectionio_pool_construct(void **rp, void *params) {
3335
resource->peer.get = ngx_http_redirectionio_get_connection;
3436
resource->peer.log = pool->log;
3537
resource->peer.log_error = NGX_ERROR_ERR;
38+
resource->data = NULL;
3639

3740
rc = ngx_event_connect_peer(&resource->peer);
3841

@@ -108,25 +111,58 @@ ngx_int_t ngx_http_redirectionio_pool_available(ngx_reslist_t *reslist, void *re
108111
return NGX_OK;
109112
}
110113

114+
static ngx_int_t ngx_http_redirectionio_write_log(ngx_event_t *wev) {
115+
ngx_connection_t *c;
116+
ngx_http_redirectionio_log_t *log;
117+
118+
c = wev->data;
119+
log = c->data;
120+
121+
return ngx_http_redirectionio_protocol_send_log(c, log);
122+
}
123+
124+
static void ngx_http_redirectionio_write_log_handler(ngx_event_t *wev) {
125+
ngx_int_t rv;
126+
ngx_http_redirectionio_log_t *log;
127+
ngx_connection_t *c;
128+
129+
c = wev->data;
130+
log = c->data;
131+
132+
wev->handler = ngx_http_redirectionio_dummy_handler;
133+
rv = ngx_http_redirectionio_write_log(wev);
134+
135+
if (rv == NGX_AGAIN) {
136+
wev->handler = ngx_http_redirectionio_write_log_handler;
137+
138+
return;
139+
}
140+
141+
if (rv != NGX_OK) {
142+
ngx_reslist_invalidate(log->reslist, log->resource);
143+
} else {
144+
ngx_reslist_release(log->reslist, log->resource);
145+
}
146+
147+
ngx_http_redirectionio_protocol_free_log(log);
148+
}
149+
111150
ngx_int_t ngx_http_redirectionio_pool_available_log_handler(ngx_reslist_t *reslist, void *resource, void *data, ngx_int_t deferred) {
112151
ngx_http_redirectionio_log_t *log = (ngx_http_redirectionio_log_t *)data;
113152
ngx_http_redirectionio_resource_t *rr = (ngx_http_redirectionio_resource_t *)resource;
114-
ngx_int_t rv;
115153

116154
if (rr == NULL) {
117155
ngx_http_redirectionio_protocol_free_log(log);
118156

119157
return NGX_ERROR;
120158
}
121159

122-
rv = ngx_http_redirectionio_protocol_send_log(rr->peer.connection, log);
123-
ngx_http_redirectionio_protocol_free_log(log);
160+
log->reslist = reslist;
161+
log->resource = rr;
124162

125-
if (rv != NGX_OK) {
126-
ngx_reslist_invalidate(reslist, rr);
127-
} else {
128-
ngx_reslist_release(reslist, rr);
129-
}
163+
rr->peer.connection->data = log;
164+
165+
ngx_http_redirectionio_write_log_handler(rr->peer.connection->write);
130166

131167
return NGX_OK;
132168
}
@@ -225,7 +261,7 @@ void ngx_http_redirectionio_read_handler(ngx_event_t *rev) {
225261
ctx->read_handler(rev, (const char *)ctx->action_string);
226262
}
227263

228-
static void ngx_http_redirectionio_dummy_handler(ngx_event_t *wev) {
264+
void ngx_http_redirectionio_dummy_handler(ngx_event_t *wev) {
229265
return;
230266
}
231267

src/ngx_http_redirectionio_protocol.c

+35-14
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ static ngx_int_t ngx_http_redirectionio_send_string(ngx_connection_t *c, const c
1414

1515
static ngx_int_t ngx_http_redirectionio_send_protocol_header(ngx_connection_t *c, ngx_str_t *project_key, uint16_t command);
1616

17-
void ngx_http_redirectionio_protocol_send_match(ngx_connection_t *c, ngx_http_request_t *r, ngx_http_redirectionio_ctx_t *ctx, ngx_str_t *project_key) {
17+
ngx_int_t ngx_http_redirectionio_protocol_send_match(ngx_connection_t *c, ngx_http_request_t *r, ngx_http_redirectionio_ctx_t *ctx, ngx_str_t *project_key) {
1818
ngx_int_t rv;
1919
ngx_table_elt_t *h;
2020
ngx_list_part_t *part;
@@ -101,23 +101,27 @@ void ngx_http_redirectionio_protocol_send_match(ngx_connection_t *c, ngx_http_re
101101
ctx->request = (struct REDIRECTIONIO_Request *)redirectionio_request_create(uri, host, scheme, method, first_header);
102102

103103
if (ctx->request == NULL) {
104-
return;
104+
return NGX_ERROR;
105105
}
106106

107107
// Serialize request
108108
request_serialized = redirectionio_request_json_serialize(ctx->request);
109109

110110
if (request_serialized == NULL) {
111-
return;
111+
return NGX_ERROR;
112112
}
113113

114114
// Send protocol header
115115
rv = ngx_http_redirectionio_send_protocol_header(c, project_key, REDIRECTIONIO_PROTOCOL_COMMAND_MATCH_ACTION);
116116

117+
if (rv == NGX_AGAIN) {
118+
return rv;
119+
}
120+
117121
if (rv != NGX_OK) {
118122
ctx->connection_error = 1;
119123

120-
return;
124+
return NGX_ERROR;
121125
}
122126

123127
// Send serialized request length
@@ -126,7 +130,7 @@ void ngx_http_redirectionio_protocol_send_match(ngx_connection_t *c, ngx_http_re
126130
if (rv != NGX_OK) {
127131
ctx->connection_error = 1;
128132

129-
return;
133+
return NGX_ERROR;
130134
}
131135

132136
// Send serialized request
@@ -135,10 +139,13 @@ void ngx_http_redirectionio_protocol_send_match(ngx_connection_t *c, ngx_http_re
135139
free((void *)request_serialized);
136140

137141
if (rv != NGX_OK) {
142+
ngx_log_error(NGX_LOG_ERR, c->log, 0, "[redirectionio] error sending request: %d", rv);
138143
ctx->connection_error = 1;
139144

140-
return;
145+
return NGX_ERROR;
141146
}
147+
148+
return NGX_OK;
142149
}
143150

144151
ngx_int_t ngx_http_redirectionio_protocol_send_log(ngx_connection_t *c, ngx_http_redirectionio_log_t *log) {
@@ -148,18 +155,28 @@ ngx_int_t ngx_http_redirectionio_protocol_send_log(ngx_connection_t *c, ngx_http
148155
// Send protocol header
149156
rv = ngx_http_redirectionio_send_protocol_header(c, &log->project_key, REDIRECTIONIO_PROTOCOL_COMMAND_LOG);
150157

151-
if (rv != NGX_OK) {
158+
if (rv == NGX_AGAIN) {
152159
return rv;
153160
}
154161

162+
if (rv != NGX_OK) {
163+
return NGX_ERROR;
164+
}
165+
155166
// Send log length
156167
rv = ngx_http_redirectionio_send_uint32(c, wlen);
157168

158169
if (rv != NGX_OK) {
159-
return rv;
170+
return NGX_ERROR;
160171
}
161172

162-
return ngx_http_redirectionio_send_string(c, log->log_serialized, wlen);
173+
rv = ngx_http_redirectionio_send_string(c, log->log_serialized, wlen);
174+
175+
if (rv != NGX_OK) {
176+
return NGX_ERROR;
177+
}
178+
179+
return NGX_OK;
163180
}
164181

165182
ngx_http_redirectionio_log_t* ngx_http_redirectionio_protocol_create_log(ngx_http_request_t *r, ngx_http_redirectionio_ctx_t *ctx, ngx_str_t *project_key) {
@@ -294,8 +311,12 @@ static ngx_int_t ngx_http_redirectionio_send_protocol_header(ngx_connection_t *c
294311
// Send protocol major version
295312
rv = ngx_http_redirectionio_send_uint8(c, REDIRECTIONIO_PROTOCOL_VERSION_MAJOR);
296313

314+
if (rv == NGX_AGAIN) {
315+
return rv;
316+
}
317+
297318
if (rv != NGX_OK) {
298-
ngx_log_error(NGX_LOG_ERR, c->log, 0, "[redirectionio] error sending protocol major version");
319+
ngx_log_error(NGX_LOG_ERR, c->log, 0, "[redirectionio] error sending protocol major version: %d", rv);
299320

300321
return rv;
301322
}
@@ -304,7 +325,7 @@ static ngx_int_t ngx_http_redirectionio_send_protocol_header(ngx_connection_t *c
304325
rv = ngx_http_redirectionio_send_uint8(c, REDIRECTIONIO_PROTOCOL_VERSION_MINOR);
305326

306327
if (rv != NGX_OK) {
307-
ngx_log_error(NGX_LOG_ERR, c->log, 0, "[redirectionio] error sending protocol minor version");
328+
ngx_log_error(NGX_LOG_ERR, c->log, 0, "[redirectionio] error sending protocol minor version: %d", rv);
308329

309330
return rv;
310331
}
@@ -313,23 +334,23 @@ static ngx_int_t ngx_http_redirectionio_send_protocol_header(ngx_connection_t *c
313334
rv = ngx_http_redirectionio_send_uint8(c, (unsigned char)project_key->len);
314335

315336
if (rv != NGX_OK) {
316-
ngx_log_error(NGX_LOG_ERR, c->log, 0, "[redirectionio] error sending project key length");
337+
ngx_log_error(NGX_LOG_ERR, c->log, 0, "[redirectionio] error sending project key length: %d", rv);
317338

318339
return rv;
319340
}
320341

321342
rv = ngx_http_redirectionio_send_string(c, (const char *)project_key->data, project_key->len);
322343

323344
if (rv != NGX_OK) {
324-
ngx_log_error(NGX_LOG_ERR, c->log, 0, "[redirectionio] error sending project key");
345+
ngx_log_error(NGX_LOG_ERR, c->log, 0, "[redirectionio] error sending project key: %d", rv);
325346

326347
return rv;
327348
}
328349

329350
rv = ngx_http_redirectionio_send_uint16(c, command);
330351

331352
if (rv != NGX_OK) {
332-
ngx_log_error(NGX_LOG_ERR, c->log, 0, "[redirectionio] error sending command");
353+
ngx_log_error(NGX_LOG_ERR, c->log, 0, "[redirectionio] error sending command: %d", rv);
333354

334355
return rv;
335356
}

0 commit comments

Comments
 (0)