agoo 2.15.7 → 2.15.9

Sign up to get free protection for your applications and to get access to all the features.
data/ext/agoo/bind.c CHANGED
@@ -16,70 +16,76 @@
16
16
 
17
17
  agooBind
18
18
  agoo_bind_port(agooErr err, int port) {
19
- agooBind b = (agooBind)AGOO_CALLOC(1, sizeof(struct _agooBind));
19
+ agooBind b = (agooBind)AGOO_CALLOC(1, sizeof(struct _agooBind));
20
20
 
21
21
  if (NULL != b) {
22
- char id[1024];
23
-
24
- b->port = port;
25
- b->family = AF_INET;
26
- snprintf(id, sizeof(id) - 1, "http://:%d", port);
27
- if (NULL == (b->id = AGOO_STRDUP(id))) {
28
- AGOO_ERR_MEM(err, "strdup()");
29
- AGOO_FREE(b);
30
- return NULL;
31
- }
32
- b->kind = AGOO_CON_HTTP;
33
- b->read = NULL;
34
- b->write = NULL;
35
- b->events = NULL;
22
+ char id[1024];
23
+
24
+ b->port = port;
25
+ b->family = AF_INET;
26
+ snprintf(id, sizeof(id) - 1, "http://:%d", port);
27
+ if (NULL == (b->id = AGOO_STRDUP(id))) {
28
+ AGOO_ERR_MEM(err, "strdup()");
29
+ AGOO_FREE(b);
30
+ return NULL;
31
+ }
32
+ b->kind = AGOO_CON_HTTP;
33
+ b->read = NULL;
34
+ b->write = NULL;
35
+ b->events = NULL;
36
36
  }
37
37
  return b;
38
38
  }
39
39
 
40
40
  static agooBind
41
41
  url_tcp(agooErr err, const char *url, const char *scheme) {
42
- char *colon = index(url, ':');
43
- struct in_addr addr = { .s_addr = 0 };
44
- int port;
45
- agooBind b;
42
+ char *colon = index(url, ':');
43
+ struct in_addr addr = { .s_addr = 0 };
44
+ int port;
45
+ agooBind b;
46
46
 
47
- if (NULL == colon) {
48
- port = 80;
47
+ if (NULL == colon || '\0' == colon[1]) {
48
+ port = 80;
49
49
  } else if (15 < colon - url) {
50
- agoo_err_set(err, AGOO_ERR_ARG, "%s bind address is not valid, too long. (%s)", scheme, url);
51
- return NULL;
50
+ agoo_err_set(err, AGOO_ERR_ARG, "%s bind address is not valid, too long. (%s)", scheme, url);
51
+ return NULL;
52
52
  } else if (':' == *url) {
53
- port = atoi(colon + 1);
53
+ port = atoi(colon + 1);
54
+ } else if (0 == strncmp("localhost", url, 9)) {
55
+ if (0 == inet_aton("127.0.0.1", &addr)) {
56
+ agoo_err_set(err, AGOO_ERR_ARG, "%s bind address is not valid. (%s)", scheme, url);
57
+ return NULL;
58
+ }
59
+ port = atoi(colon + 1);
54
60
  } else {
55
- char buf[32];
56
-
57
- strncpy(buf, url, colon - url);
58
- buf[colon - url] = '\0';
59
- if (0 == inet_aton(buf, &addr)) {
60
- agoo_err_set(err, AGOO_ERR_ARG, "%s bind address is not valid. (%s)", scheme, url);
61
- return NULL;
62
- }
63
- port = atoi(colon + 1);
61
+ char buf[32];
62
+
63
+ strncpy(buf, url, colon - url);
64
+ buf[colon - url] = '\0';
65
+ if (0 == inet_aton(buf, &addr)) {
66
+ agoo_err_set(err, AGOO_ERR_ARG, "%s bind address is not valid. (%s)", scheme, url);
67
+ return NULL;
68
+ }
69
+ port = atoi(colon + 1);
64
70
  }
65
71
  if (NULL != (b = (agooBind)AGOO_CALLOC(1, sizeof(struct _agooBind)))) {
66
- char id[64];
67
-
68
- b->port = port;
69
- b->addr4 = addr;
70
- b->family = AF_INET;
71
- snprintf(id, sizeof(id), "%s://%s:%d", scheme, inet_ntoa(addr), port);
72
- if (NULL == (b->id = AGOO_STRDUP(id))) {
73
- AGOO_ERR_MEM(err, "strdup()");
74
- AGOO_FREE(b);
75
- return NULL;
76
- }
77
- b->kind = AGOO_CON_HTTP;
78
- b->read = NULL;
79
- b->write = NULL;
80
- b->events = NULL;
81
-
82
- return b;
72
+ char id[64];
73
+
74
+ b->port = port;
75
+ b->addr4 = addr;
76
+ b->family = AF_INET;
77
+ snprintf(id, sizeof(id), "%s://%s:%d", scheme, inet_ntoa(addr), port);
78
+ if (NULL == (b->id = AGOO_STRDUP(id))) {
79
+ AGOO_ERR_MEM(err, "strdup()");
80
+ AGOO_FREE(b);
81
+ return NULL;
82
+ }
83
+ b->kind = AGOO_CON_HTTP;
84
+ b->read = NULL;
85
+ b->write = NULL;
86
+ b->events = NULL;
87
+
88
+ return b;
83
89
  }
84
90
  AGOO_ERR_MEM(err, "Bind");
85
91
 
@@ -88,40 +94,40 @@ url_tcp(agooErr err, const char *url, const char *scheme) {
88
94
 
89
95
  static agooBind
90
96
  url_tcp6(agooErr err, const char *url, const char *scheme) {
91
- struct in6_addr addr;
92
- char *end = index(url, ']');
93
- int port = 80;
94
- char buf[256];
95
- agooBind b;
97
+ struct in6_addr addr;
98
+ char *end = index(url, ']');
99
+ int port = 80;
100
+ char buf[256];
101
+ agooBind b;
96
102
 
97
103
  if (':' == *(end + 1)) {
98
- port = atoi(end + 2);
104
+ port = atoi(end + 2);
99
105
  }
100
106
  memcpy(buf, url + 1, end - url - 1);
101
107
  buf[end - url - 1] = '\0';
102
108
  memset(&addr, 0, sizeof(addr));
103
109
  if (0 == inet_pton(AF_INET6, buf, &addr)) {
104
- agoo_err_set(err, AGOO_ERR_ARG, "%s bind address is not valid. (%s)", scheme, url);
105
- return NULL;
110
+ agoo_err_set(err, AGOO_ERR_ARG, "%s bind address is not valid. (%s)", scheme, url);
111
+ return NULL;
106
112
  }
107
113
  if (NULL != (b = (agooBind)AGOO_CALLOC(1, sizeof(struct _agooBind)))) {
108
- char str[INET6_ADDRSTRLEN + 1];
109
-
110
- b->port = port;
111
- b->addr6 = addr;
112
- b->family = AF_INET6;
113
- snprintf(buf, sizeof(buf), "%s://[%s]:%d", scheme, inet_ntop(AF_INET6, &addr, str, INET6_ADDRSTRLEN), port);
114
- if (NULL == (b->id = AGOO_STRDUP(buf))) {
115
- AGOO_ERR_MEM(err, "strdup()");
116
- AGOO_FREE(b);
117
- return NULL;
118
- }
119
- b->kind = AGOO_CON_HTTP;
120
- b->read = NULL;
121
- b->write = NULL;
122
- b->events = NULL;
123
-
124
- return b;
114
+ char str[INET6_ADDRSTRLEN + 1];
115
+
116
+ b->port = port;
117
+ b->addr6 = addr;
118
+ b->family = AF_INET6;
119
+ snprintf(buf, sizeof(buf), "%s://[%s]:%d", scheme, inet_ntop(AF_INET6, &addr, str, INET6_ADDRSTRLEN), port);
120
+ if (NULL == (b->id = AGOO_STRDUP(buf))) {
121
+ AGOO_ERR_MEM(err, "strdup()");
122
+ AGOO_FREE(b);
123
+ return NULL;
124
+ }
125
+ b->kind = AGOO_CON_HTTP;
126
+ b->read = NULL;
127
+ b->write = NULL;
128
+ b->events = NULL;
129
+
130
+ return b;
125
131
  }
126
132
  AGOO_ERR_MEM(err, "Bind");
127
133
 
@@ -131,32 +137,32 @@ url_tcp6(agooErr err, const char *url, const char *scheme) {
131
137
  static agooBind
132
138
  url_named(agooErr err, const char *url) {
133
139
  if ('\0' == *url) {
134
- agoo_err_set(err, AGOO_ERR_ARG, "Named Unix sockets names must not be empty.");
135
- return NULL;
140
+ agoo_err_set(err, AGOO_ERR_ARG, "Named Unix sockets names must not be empty.");
141
+ return NULL;
136
142
  } else {
137
- agooBind b = (agooBind)AGOO_CALLOC(1, sizeof(struct _agooBind));
138
-
139
- if (NULL != b) {
140
- const char *fmt = "unix://%s";
141
- char id[1024];
142
-
143
- if (NULL == (b->name = AGOO_STRDUP(url))) {
144
- AGOO_ERR_MEM(err, "strdup()");
145
- AGOO_FREE(b);
146
- return NULL;
147
- }
148
- snprintf(id, sizeof(id) - 1, fmt, url);
149
- if (NULL == (b->id = AGOO_STRDUP(id))) {
150
- AGOO_ERR_MEM(err, "strdup()");
151
- AGOO_FREE(b);
152
- return NULL;
153
- }
154
- b->kind = AGOO_CON_HTTP;
155
- b->read = NULL;
156
- b->write = NULL;
157
- b->events = NULL;
158
- }
159
- return b;
143
+ agooBind b = (agooBind)AGOO_CALLOC(1, sizeof(struct _agooBind));
144
+
145
+ if (NULL != b) {
146
+ const char *fmt = "unix://%s";
147
+ char id[1024];
148
+
149
+ if (NULL == (b->name = AGOO_STRDUP(url))) {
150
+ AGOO_ERR_MEM(err, "strdup()");
151
+ AGOO_FREE(b);
152
+ return NULL;
153
+ }
154
+ snprintf(id, sizeof(id) - 1, fmt, url);
155
+ if (NULL == (b->id = AGOO_STRDUP(id))) {
156
+ AGOO_ERR_MEM(err, "strdup()");
157
+ AGOO_FREE(b);
158
+ return NULL;
159
+ }
160
+ b->kind = AGOO_CON_HTTP;
161
+ b->read = NULL;
162
+ b->write = NULL;
163
+ b->events = NULL;
164
+ }
165
+ return b;
160
166
  }
161
167
  AGOO_ERR_MEM(err, "Bind");
162
168
 
@@ -165,56 +171,56 @@ url_named(agooErr err, const char *url) {
165
171
 
166
172
  static agooBind
167
173
  url_ssl(agooErr err, const char *url) {
168
- char *colon = index(url, ':');
169
- struct in_addr addr = { .s_addr = 0 };
170
- int port;
171
- agooBind b;
174
+ char *colon = index(url, ':');
175
+ struct in_addr addr = { .s_addr = 0 };
176
+ int port;
177
+ agooBind b;
172
178
 
173
179
  #ifdef HAVE_OPENSSL_SSL_H
174
180
  if (NULL == agoo_server.ssl_ctx) {
175
- agoo_err_set(err, AGOO_ERR_ARG, "https requires an SSL certificate and private key. (%s)", url);
176
- return NULL;
181
+ agoo_err_set(err, AGOO_ERR_ARG, "https requires an SSL certificate and private key. (%s)", url);
182
+ return NULL;
177
183
  }
178
184
  #else
179
185
  agoo_err_set(err, AGOO_ERR_ARG, "https requires OpenSSL. Rebuild with OpenSSL. (%s)", url);
180
186
  return NULL;
181
187
  #endif
182
188
  if (NULL == colon) {
183
- port = 443;
189
+ port = 443;
184
190
  } else if (15 < colon - url) {
185
- agoo_err_set(err, AGOO_ERR_ARG, "https bind address is not valid, too long. (%s)", url);
186
- return NULL;
191
+ agoo_err_set(err, AGOO_ERR_ARG, "https bind address is not valid, too long. (%s)", url);
192
+ return NULL;
187
193
  } else if (':' == *url) {
188
- port = atoi(colon + 1);
194
+ port = atoi(colon + 1);
189
195
  } else {
190
- char buf[32];
191
-
192
- strncpy(buf, url, colon - url);
193
- buf[colon - url] = '\0';
194
- if (0 == inet_aton(buf, &addr)) {
195
- agoo_err_set(err, AGOO_ERR_ARG, "https bind address is not valid. (%s)", url);
196
- return NULL;
197
- }
198
- port = atoi(colon + 1);
196
+ char buf[32];
197
+
198
+ strncpy(buf, url, colon - url);
199
+ buf[colon - url] = '\0';
200
+ if (0 == inet_aton(buf, &addr)) {
201
+ agoo_err_set(err, AGOO_ERR_ARG, "https bind address is not valid. (%s)", url);
202
+ return NULL;
203
+ }
204
+ port = atoi(colon + 1);
199
205
  }
200
206
  if (NULL != (b = (agooBind)AGOO_CALLOC(1, sizeof(struct _agooBind)))) {
201
- char id[64];
202
-
203
- b->port = port;
204
- b->addr4 = addr;
205
- b->family = AF_INET;
206
- snprintf(id, sizeof(id), "https://%s:%d", inet_ntoa(addr), port);
207
- if (NULL == (b->id = AGOO_STRDUP(id))) {
208
- AGOO_ERR_MEM(err, "strdup()");
209
- AGOO_FREE(b);
210
- return NULL;
211
- }
212
- b->kind = AGOO_CON_HTTPS;
213
- b->read = NULL;
214
- b->write = NULL;
215
- b->events = NULL;
216
-
217
- return b;
207
+ char id[64];
208
+
209
+ b->port = port;
210
+ b->addr4 = addr;
211
+ b->family = AF_INET;
212
+ snprintf(id, sizeof(id), "https://%s:%d", inet_ntoa(addr), port);
213
+ if (NULL == (b->id = AGOO_STRDUP(id))) {
214
+ AGOO_ERR_MEM(err, "strdup()");
215
+ AGOO_FREE(b);
216
+ return NULL;
217
+ }
218
+ b->kind = AGOO_CON_HTTPS;
219
+ b->read = NULL;
220
+ b->write = NULL;
221
+ b->events = NULL;
222
+
223
+ return b;
218
224
  }
219
225
  AGOO_ERR_MEM(err, "Bind");
220
226
 
@@ -224,41 +230,42 @@ url_ssl(agooErr err, const char *url) {
224
230
  agooBind
225
231
  agoo_bind_url(agooErr err, const char *url) {
226
232
  if (0 == strncasecmp("tcp://", url, 6)) {
227
- if ('[' == url[6]) {
228
- return url_tcp6(err, url + 6, "tcp");
229
- }
230
- return url_tcp(err, url + 6, "tcp");
233
+ if ('[' == url[6]) {
234
+ return url_tcp6(err, url + 6, "tcp");
235
+ }
236
+ return url_tcp(err, url + 6, "tcp");
231
237
  }
232
238
  if (0 == strncasecmp("http://", url, 7)) {
233
- if ('[' == url[7]) {
234
- return url_tcp6(err, url + 7, "http");
235
- }
236
- return url_tcp(err, url + 7, "http");
239
+ if ('[' == url[7]) {
240
+ return url_tcp6(err, url + 7, "http");
241
+ }
242
+ return url_tcp(err, url + 7, "http");
237
243
  }
238
244
  if (0 == strncasecmp("unix://", url, 7)) {
239
- return url_named(err, url + 7);
245
+ return url_named(err, url + 7);
240
246
  }
241
247
  if (0 == strncasecmp("https://", url, 8)) {
242
- return url_ssl(err, url + 8);
248
+ return url_ssl(err, url + 8);
243
249
  }
244
250
  if (0 == strncasecmp("ssl://", url, 6)) {
245
- return url_ssl(err, url + 6);
251
+ return url_ssl(err, url + 6);
246
252
  }
247
253
  // All others assume http
248
254
  {
249
- char *colon = index(url, ':');
250
- char scheme[8];
251
-
252
- if (NULL != colon && colon - url < (int)sizeof(scheme)) {
253
- int slen = (int)(colon - url);
254
-
255
- memcpy(scheme, url, slen);
256
- scheme[slen] = '\0';
257
- if ('[' == url[slen + 3]) {
258
- return url_tcp6(err, url + slen + 3, scheme);
259
- }
260
- return url_tcp(err, url + slen + 3, scheme);
261
- }
255
+ char *colon = index(url, ':');
256
+ char scheme[8];
257
+
258
+ if (NULL != colon && colon - url < (int)sizeof(scheme)) {
259
+ int slen = (int)(colon - url);
260
+
261
+ memcpy(scheme, url, slen);
262
+ scheme[slen] = '\0';
263
+ if ('[' == url[slen + 3]) {
264
+ return url_tcp6(err, url + slen + 3, scheme);
265
+ }
266
+ return url_tcp(err, url + slen + 3, scheme);
267
+ }
268
+ return url_tcp(err, url, "http");
262
269
  }
263
270
  return NULL;
264
271
  }
@@ -272,16 +279,17 @@ agoo_bind_destroy(agooBind b) {
272
279
 
273
280
  static int
274
281
  usual_listen(agooErr err, agooBind b) {
275
- int optval = 1;
276
- int domain = PF_INET;
282
+ int optval = 1;
283
+ int domain = PF_INET;
284
+ int e;
277
285
 
278
286
  if (AF_INET6 == b->family) {
279
- domain = PF_INET6;
287
+ domain = PF_INET6;
280
288
  }
281
289
  if (0 >= (b->fd = socket(domain, SOCK_STREAM, IPPROTO_TCP))) {
282
- agoo_log_cat(&agoo_error_cat, "Server failed to open server socket on port %d. %s.", b->port, strerror(errno));
290
+ agoo_log_cat(&agoo_error_cat, "Server failed to open server socket on port %d. %s.", b->port, strerror(errno));
283
291
 
284
- return agoo_err_set(err, errno, "Server failed to open server socket. %s.", strerror(errno));
292
+ return agoo_err_set(err, errno, "Server failed to open server socket. %s.", strerror(errno));
285
293
  }
286
294
  #ifdef OSX_OS
287
295
  setsockopt(b->fd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval));
@@ -291,63 +299,66 @@ usual_listen(agooErr err, agooBind b) {
291
299
  #endif
292
300
  setsockopt(b->fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));
293
301
  if (AF_INET6 == b->family) {
294
- struct sockaddr_in6 addr;
295
-
296
- memset(&addr, 0, sizeof(addr));
297
- addr.sin6_flowinfo = 0;
298
- addr.sin6_family = b->family;
299
- addr.sin6_addr = b->addr6;
300
- addr.sin6_port = htons(b->port);
301
- if (0 > bind(b->fd, (struct sockaddr*)&addr, sizeof(addr))) {
302
- agoo_log_cat(&agoo_error_cat, "Server failed to bind server socket. %s.", strerror(errno));
303
-
304
- return agoo_err_set(err, errno, "Server failed to bind server socket. %s.", strerror(errno));
305
- }
302
+ struct sockaddr_in6 addr;
303
+
304
+ memset(&addr, 0, sizeof(addr));
305
+ addr.sin6_flowinfo = 0;
306
+ addr.sin6_family = b->family;
307
+ addr.sin6_addr = b->addr6;
308
+ addr.sin6_port = htons(b->port);
309
+ if (0 > bind(b->fd, (struct sockaddr*)&addr, sizeof(addr))) {
310
+ agoo_log_cat(&agoo_error_cat, "Server failed to bind server socket. %s.", strerror(errno));
311
+
312
+ return agoo_err_set(err, errno, "Server failed to bind server socket. %s.", strerror(errno));
313
+ }
306
314
  } else {
307
- struct sockaddr_in addr;
315
+ struct sockaddr_in addr;
308
316
 
309
- memset(&addr, 0, sizeof(addr));
310
- addr.sin_family = b->family;
311
- addr.sin_addr = b->addr4;
312
- addr.sin_port = htons(b->port);
313
- if (0 > bind(b->fd, (struct sockaddr*)&addr, sizeof(addr))) {
314
- agoo_log_cat(&agoo_error_cat, "Server failed to bind server socket. %s.", strerror(errno));
317
+ memset(&addr, 0, sizeof(addr));
318
+ addr.sin_family = b->family;
319
+ addr.sin_addr = b->addr4;
320
+ addr.sin_port = htons(b->port);
321
+ if (0 > bind(b->fd, (struct sockaddr*)&addr, sizeof(addr))) {
322
+ agoo_log_cat(&agoo_error_cat, "Server failed to bind server socket. %s.", strerror(errno));
315
323
 
316
- return agoo_err_set(err, errno, "Server failed to bind server socket. %s.", strerror(errno));
317
- }
324
+ return agoo_err_set(err, errno, "Server failed to bind server socket. %s.", strerror(errno));
325
+ }
326
+ }
327
+ if (0 != (e = listen(b->fd, 1000))) {
328
+ return agoo_err_set(err, e, "Server failed to bind to port %d. %s.", b->fd, strerror(e));
318
329
  }
319
- listen(b->fd, 1000);
320
-
321
330
  return AGOO_ERR_OK;
322
331
  }
323
332
 
324
333
  static int
325
334
  named_listen(agooErr err, agooBind b) {
326
- struct sockaddr_un addr;
335
+ struct sockaddr_un addr;
336
+ int e;
327
337
 
328
338
  remove(b->name);
329
339
  if (0 >= (b->fd = socket(AF_UNIX, SOCK_STREAM, 0))) {
330
- agoo_log_cat(&agoo_error_cat, "Server failed to open server socket on %s. %s.", b->name, strerror(errno));
340
+ agoo_log_cat(&agoo_error_cat, "Server failed to open server socket on %s. %s.", b->name, strerror(errno));
331
341
 
332
- return agoo_err_set(err, errno, "Server failed to open server socket on %s. %s.", b->name, strerror(errno));
342
+ return agoo_err_set(err, errno, "Server failed to open server socket on %s. %s.", b->name, strerror(errno));
333
343
  }
334
344
  memset(&addr, 0, sizeof(addr));
335
345
  addr.sun_family = AF_UNIX;
336
346
  strcpy(addr.sun_path, b->name);
337
347
  if (0 > bind(b->fd, (struct sockaddr*)&addr, sizeof(addr))) {
338
- agoo_log_cat(&agoo_error_cat, "Server failed to bind server socket. %s.", strerror(errno));
348
+ agoo_log_cat(&agoo_error_cat, "Server failed to bind server socket. %s.", strerror(errno));
339
349
 
340
- return agoo_err_set(err, errno, "Server failed to bind server socket. %s.", strerror(errno));
350
+ return agoo_err_set(err, errno, "Server failed to bind server socket. %s.", strerror(errno));
351
+ }
352
+ if (0 != (e = listen(b->fd, 100))) {
353
+ return agoo_err_set(err, e, "Server failed to bind to port %d. %s.", b->fd, strerror(e));
341
354
  }
342
- listen(b->fd, 100);
343
-
344
355
  return AGOO_ERR_OK;
345
356
  }
346
357
 
347
358
  int
348
359
  agoo_bind_listen(agooErr err, agooBind b) {
349
360
  if (NULL != b->name) {
350
- return named_listen(err, b);
361
+ return named_listen(err, b);
351
362
  }
352
363
  return usual_listen(err, b);
353
364
  }
@@ -355,7 +366,7 @@ agoo_bind_listen(agooErr err, agooBind b) {
355
366
  void
356
367
  agoo_bind_close(agooBind b) {
357
368
  if (0 != b->fd) {
358
- close(b->fd);
359
- b->fd = 0;
369
+ close(b->fd);
370
+ b->fd = 0;
360
371
  }
361
372
  }
data/ext/agoo/con.c CHANGED
@@ -26,9 +26,10 @@
26
26
  #include "upgraded.h"
27
27
  #include "websocket.h"
28
28
 
29
- #define CON_TIMEOUT 10.0
30
29
  #define INITIAL_POLL_SIZE 1024
31
30
 
31
+ double con_timeout = 30.0;
32
+
32
33
  typedef enum {
33
34
  HEAD_AGAIN = 'A',
34
35
  HEAD_ERR = 'E',
@@ -81,7 +82,7 @@ agoo_con_create(agooErr err, int sock, uint64_t id, agooBind b) {
81
82
  }
82
83
  c->sock = sock;
83
84
  c->id = id;
84
- c->timeout = dtime() + CON_TIMEOUT;
85
+ c->timeout = dtime() + con_timeout;
85
86
  c->bind = b;
86
87
  c->loop = NULL;
87
88
  pthread_mutex_init(&c->res_lock, 0);
@@ -289,6 +290,8 @@ con_header_read(agooCon c, size_t *mlenp) {
289
290
  char *query = NULL;
290
291
  char *qend;
291
292
  char *b;
293
+ char *proto;
294
+ char *pend;
292
295
  size_t clen = 0;
293
296
  long mlen;
294
297
  agooHook hook = NULL;
@@ -395,7 +398,12 @@ con_header_read(agooCon c, size_t *mlenp) {
395
398
  }
396
399
  mlen = hend - c->buf + 4 + clen;
397
400
  *mlenp = mlen;
398
-
401
+ proto = qend;
402
+ for (; ' ' == *proto; proto++) {
403
+ }
404
+ pend = proto;
405
+ for (; '\r' != *pend; pend++) {
406
+ }
399
407
  if (AGOO_GET == method) {
400
408
  char root_buf[20148];
401
409
  const char *root = NULL;
@@ -461,6 +469,8 @@ con_header_read(agooCon c, size_t *mlenp) {
461
469
  c->req->query.start = c->req->msg + (query - c->buf);
462
470
  c->req->query.len = (int)(qend - query);
463
471
  c->req->query.start[c->req->query.len] = '\0';
472
+ c->req->protocol.start = proto;
473
+ c->req->protocol.len = (int)(pend - proto);
464
474
  c->req->body.start = c->req->msg + (hend - c->buf + 4);
465
475
  c->req->body.len = (unsigned int)clen;
466
476
  b = strstr(b, "\r\n");
@@ -555,7 +565,7 @@ agoo_con_http_read(agooCon c) {
555
565
  cnt = recv(c->sock, c->buf + c->bcnt, sizeof(c->buf) - c->bcnt - 1, 0);
556
566
  }
557
567
  }
558
- c->timeout = dtime() + CON_TIMEOUT;
568
+ c->timeout = dtime() + con_timeout;
559
569
  if (0 >= cnt) {
560
570
  // If nothing read then no need to complain. Just close.
561
571
  if (0 < c->bcnt) {
@@ -658,7 +668,7 @@ agoo_con_http_write(agooCon c) {
658
668
  if (NULL == message) {
659
669
  return true;
660
670
  }
661
- c->timeout = dtime() + CON_TIMEOUT;
671
+ c->timeout = dtime() + con_timeout;
662
672
  if (0 == c->wcnt) {
663
673
  if (agoo_resp_cat.on) {
664
674
  char buf[4096];
@@ -736,7 +746,7 @@ con_ws_read(agooCon c) {
736
746
  } else {
737
747
  cnt = recv(c->sock, c->buf + c->bcnt, sizeof(c->buf) - c->bcnt - 1, 0);
738
748
  }
739
- c->timeout = dtime() + CON_TIMEOUT;
749
+ c->timeout = dtime() + con_timeout;
740
750
  if (0 >= cnt) {
741
751
  // If nothing read then no need to complain. Just close.
742
752
  if (0 < c->bcnt) {
@@ -883,7 +893,7 @@ con_ws_write(agooCon c) {
883
893
  }
884
894
  return true;
885
895
  }
886
- c->timeout = dtime() + CON_TIMEOUT;
896
+ c->timeout = dtime() + con_timeout;
887
897
  if (0 == c->wcnt) {
888
898
  agooText t;
889
899
 
@@ -943,7 +953,7 @@ con_sse_write(agooCon c) {
943
953
 
944
954
  return false;
945
955
  }
946
- c->timeout = dtime() + CON_TIMEOUT *2;
956
+ c->timeout = dtime() + con_timeout *2;
947
957
  if (0 == c->wcnt) {
948
958
  agooText t;
949
959
 
@@ -1177,7 +1187,7 @@ con_ready_check(void *ctx, double now) {
1177
1187
  return true;
1178
1188
  }
1179
1189
  } else if (AGOO_CON_WS == c->bind->kind || AGOO_CON_SSE == c->bind->kind) {
1180
- c->timeout = dtime() + CON_TIMEOUT;
1190
+ c->timeout = dtime() + con_timeout;
1181
1191
  if (AGOO_CON_WS == c->bind->kind) {
1182
1192
  agoo_ws_ping(c);
1183
1193
  }
data/ext/agoo/con.h CHANGED
@@ -20,6 +20,8 @@
20
20
 
21
21
  #define MAX_HEADER_SIZE 8192
22
22
 
23
+ extern double con_timeout;
24
+
23
25
  struct _agooUpgraded;
24
26
  struct _agooReq;
25
27
  struct _agooRes;
data/ext/agoo/req.c CHANGED
@@ -71,6 +71,13 @@ agoo_req_port(agooReq r) {
71
71
  return (int)strtol(colon + 1, NULL, 10);
72
72
  }
73
73
 
74
+ const char*
75
+ agoo_req_protocol(agooReq r, int *lenp) {
76
+ *lenp = r->protocol.len;
77
+
78
+ return r->protocol.start;
79
+ }
80
+
74
81
  const char*
75
82
  agoo_req_query_value(agooReq r, const char *key, int klen, int *vlenp) {
76
83
  const char *value;