aboutsummaryrefslogtreecommitdiff
path: root/src/examples/mhd2spdy_spdy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/examples/mhd2spdy_spdy.c')
-rw-r--r--src/examples/mhd2spdy_spdy.c329
1 files changed, 180 insertions, 149 deletions
diff --git a/src/examples/mhd2spdy_spdy.c b/src/examples/mhd2spdy_spdy.c
index 8640df35..413de7f3 100644
--- a/src/examples/mhd2spdy_spdy.c
+++ b/src/examples/mhd2spdy_spdy.c
@@ -35,29 +35,27 @@
35#include "mhd2spdy_spdy.h" 35#include "mhd2spdy_spdy.h"
36#include "mhd2spdy_http.h" 36#include "mhd2spdy_http.h"
37 37
38enum
39{
40 IO_NONE,
41 WANT_READ,
42 WANT_WRITE
43};
44
45 38
46/* 39/*
47 * Prints error containing the function name |func| and message |msg| 40 * Prints error containing the function name |func| and message |msg|
48 * and exit. 41 * and exit.
49 */ 42 */
50static void spdy_dief(const char *func, const char *msg) 43static void
44spdy_dief(const char *func,
45 const char *msg)
51{ 46{
52 fprintf(stderr, "FATAL: %s: %s\n", func, msg); 47 fprintf(stderr, "FATAL: %s: %s\n", func, msg);
53 exit(EXIT_FAILURE); 48 exit(EXIT_FAILURE);
54} 49}
55 50
51
56/* 52/*
57 * Prints error containing the function name |func| and error code 53 * Prints error containing the function name |func| and error code
58 * |error_code| and exit. 54 * |error_code| and exit.
59 */ 55 */
60void spdy_diec(const char *func, int error_code) 56void
57spdy_diec(const char *func,
58 int error_code)
61{ 59{
62 fprintf(stderr, "FATAL: %s: error_code=%d, msg=%s\n", func, error_code, 60 fprintf(stderr, "FATAL: %s: error_code=%d, msg=%s\n", func, error_code,
63 spdylay_strerror(error_code)); 61 spdylay_strerror(error_code));
@@ -71,11 +69,12 @@ void spdy_diec(const char *func, int error_code)
71 * bytes actually written. See the documentation of 69 * bytes actually written. See the documentation of
72 * spdylay_send_callback for the details. 70 * spdylay_send_callback for the details.
73 */ 71 */
74static ssize_t spdy_cb_send(spdylay_session *session, 72static ssize_t
75 const uint8_t *data, 73spdy_cb_send(spdylay_session *session,
76 size_t length, 74 const uint8_t *data,
77 int flags, 75 size_t length,
78 void *user_data) 76 int flags,
77 void *user_data)
79{ 78{
80 (void)session; 79 (void)session;
81 (void)flags; 80 (void)flags;
@@ -126,15 +125,19 @@ static ssize_t spdy_cb_send(spdylay_session *session,
126 return rv; 125 return rv;
127} 126}
128 127
128
129/* 129/*
130 * The implementation of spdylay_recv_callback type. Here we read data 130 * The implementation of spdylay_recv_callback type. Here we read data
131 * from the network and write them in |buf|. The capacity of |buf| is 131 * from the network and write them in |buf|. The capacity of |buf| is
132 * |length| bytes. Returns the number of bytes stored in |buf|. See 132 * |length| bytes. Returns the number of bytes stored in |buf|. See
133 * the documentation of spdylay_recv_callback for the details. 133 * the documentation of spdylay_recv_callback for the details.
134 */ 134 */
135static ssize_t spdy_cb_recv(spdylay_session *session, 135static ssize_t
136 uint8_t *buf, size_t length, int flags, 136spdy_cb_recv(spdylay_session *session,
137 void *user_data) 137 uint8_t *buf,
138 size_t length,
139 int flags,
140 void *user_data)
138{ 141{
139 (void)session; 142 (void)session;
140 (void)flags; 143 (void)flags;
@@ -191,63 +194,47 @@ static ssize_t spdy_cb_recv(spdylay_session *session,
191 return rv; 194 return rv;
192} 195}
193 196
194/*
195 * The implementation of spdylay_before_ctrl_send_callback type. We
196 * use this function to get stream ID of the request. This is because
197 * stream ID is not known when we submit the request
198 * (spdylay_spdy_submit_request).
199 */
200/*static void spdy_cb_before_ctrl_send(spdylay_session *session,
201 spdylay_frame_type type,
202 spdylay_frame *frame,
203 void *user_data)
204{
205}*/
206
207 197
208static void spdy_cb_on_ctrl_send(spdylay_session *session, 198static void
209 spdylay_frame_type type, 199spdy_cb_on_ctrl_send(spdylay_session *session,
210 spdylay_frame *frame, void *user_data) 200 spdylay_frame_type type,
201 spdylay_frame *frame,
202 void *user_data)
211{ 203{
212 (void)user_data; 204 (void)user_data;
213 205
214 //char **nv;
215 //const char *name = NULL;
216 int32_t stream_id; 206 int32_t stream_id;
217 //size_t i;
218 struct Proxy *proxy; 207 struct Proxy *proxy;
219 208
220 switch(type) { 209 switch(type) {
221 case SPDYLAY_SYN_STREAM: 210 case SPDYLAY_SYN_STREAM:
222 //nv = frame->syn_stream.nv; 211 stream_id = frame->syn_stream.stream_id;
223 //name = "SYN_STREAM"; 212 proxy = spdylay_session_get_stream_user_data(session, stream_id);
224 stream_id = frame->syn_stream.stream_id; 213 ++glob_opt.streams_opened;
225 proxy = spdylay_session_get_stream_user_data(session, stream_id); 214 ++proxy->spdy_connection->streams_opened;
226 ++glob_opt.streams_opened; 215 PRINT_INFO2("opening stream: str open %i; %s", glob_opt.streams_opened, proxy->url);
227 ++proxy->spdy_connection->streams_opened; 216 break;
228 PRINT_INFO2("opening stream: str open %i; %s", glob_opt.streams_opened, proxy->url); 217 default:
229 break; 218 break;
230 default:
231 break;
232 } 219 }
233} 220}
234 221
235void spdy_cb_on_ctrl_recv(spdylay_session *session, 222
236 spdylay_frame_type type, 223void
237 spdylay_frame *frame, void *user_data) 224spdy_cb_on_ctrl_recv(spdylay_session *session,
225 spdylay_frame_type type,
226 spdylay_frame *frame,
227 void *user_data)
238{ 228{
239 (void)user_data; 229 (void)user_data;
240 230
241 //struct SPDY_Request *req;
242 char **nv; 231 char **nv;
243 //const char *name = NULL;
244 int32_t stream_id; 232 int32_t stream_id;
245 struct Proxy * proxy; 233 struct Proxy * proxy;
246 234
247 switch(type) { 235 switch(type) {
248 case SPDYLAY_SYN_REPLY: 236 case SPDYLAY_SYN_REPLY:
249 nv = frame->syn_reply.nv; 237 nv = frame->syn_reply.nv;
250 //name = "SYN_REPLY";
251 stream_id = frame->syn_reply.stream_id; 238 stream_id = frame->syn_reply.stream_id;
252 break; 239 break;
253 case SPDYLAY_RST_STREAM: 240 case SPDYLAY_RST_STREAM:
@@ -255,7 +242,6 @@ void spdy_cb_on_ctrl_recv(spdylay_session *session,
255 break; 242 break;
256 case SPDYLAY_HEADERS: 243 case SPDYLAY_HEADERS:
257 nv = frame->headers.nv; 244 nv = frame->headers.nv;
258 //name = "HEADERS";
259 stream_id = frame->headers.stream_id; 245 stream_id = frame->headers.stream_id;
260 break; 246 break;
261 default: 247 default:
@@ -269,34 +255,37 @@ void spdy_cb_on_ctrl_recv(spdylay_session *session,
269 255
270 switch(type) { 256 switch(type) {
271 case SPDYLAY_SYN_REPLY: 257 case SPDYLAY_SYN_REPLY:
272 PRINT_INFO2("received headers for %s", proxy->url); 258 PRINT_INFO2("received headers for %s", proxy->url);
273 http_create_response(proxy, nv); 259 http_create_response(proxy, nv);
274 break; 260 break;
275 case SPDYLAY_RST_STREAM: 261 case SPDYLAY_RST_STREAM:
276 PRINT_INFO2("received reset stream for %s", proxy->url); 262 PRINT_INFO2("received reset stream for %s", proxy->url);
277 proxy->error = true; 263 proxy->error = true;
278 break; 264 break;
279 case SPDYLAY_HEADERS: 265 case SPDYLAY_HEADERS:
280 PRINT_INFO2("received headers for %s", proxy->url); 266 PRINT_INFO2("received headers for %s", proxy->url);
281 http_create_response(proxy, nv); 267 http_create_response(proxy, nv);
282 break; 268 break;
283 default: 269 default:
284 return; 270 return;
285 break; 271 break;
286 } 272 }
273
287 glob_opt.spdy_data_received = true; 274 glob_opt.spdy_data_received = true;
288} 275}
289 276
277
290/* 278/*
291 * The implementation of spdylay_on_stream_close_callback type. We use 279 * The implementation of spdylay_on_stream_close_callback type. We use
292 * this function to know the response is fully received. Since we just 280 * this function to know the response is fully received. Since we just
293 * fetch 1 resource in this program, after reception of the response, 281 * fetch 1 resource in this program, after reception of the response,
294 * we submit GOAWAY and close the session. 282 * we submit GOAWAY and close the session.
295 */ 283 */
296static void spdy_cb_on_stream_close(spdylay_session *session, 284static void
297 int32_t stream_id, 285spdy_cb_on_stream_close(spdylay_session *session,
298 spdylay_status_code status_code, 286 int32_t stream_id,
299 void *user_data) 287 spdylay_status_code status_code,
288 void *user_data)
300{ 289{
301 (void)status_code; 290 (void)status_code;
302 (void)user_data; 291 (void)user_data;
@@ -315,24 +304,24 @@ static void spdy_cb_on_stream_close(spdylay_session *session,
315 proxy->spdy_active = false; 304 proxy->spdy_active = false;
316 else 305 else
317 free_proxy(proxy); 306 free_proxy(proxy);
318 return;
319} 307}
320 308
321#define SPDY_MAX_OUTLEN 4096
322 309
323/* 310/*
324 * The implementation of spdylay_on_data_chunk_recv_callback type. We 311 * The implementation of spdylay_on_data_chunk_recv_callback type. We
325 * use this function to print the received response body. 312 * use this function to print the received response body.
326 */ 313 */
327static void spdy_cb_on_data_chunk_recv(spdylay_session *session, uint8_t flags, 314static void
328 int32_t stream_id, 315spdy_cb_on_data_chunk_recv(spdylay_session *session,
329 const uint8_t *data, size_t len, 316 uint8_t flags,
330 void *user_data) 317 int32_t stream_id,
318 const uint8_t *data,
319 size_t len,
320 void *user_data)
331{ 321{
332 (void)flags; 322 (void)flags;
333 (void)user_data; 323 (void)user_data;
334 324
335 //struct SPDY_Request *req;
336 struct Proxy *proxy; 325 struct Proxy *proxy;
337 proxy = spdylay_session_get_stream_user_data(session, stream_id); 326 proxy = spdylay_session_get_stream_user_data(session, stream_id);
338 327
@@ -348,12 +337,17 @@ static void spdy_cb_on_data_chunk_recv(spdylay_session *session, uint8_t flags,
348 337
349 memcpy(proxy->http_body + proxy->http_body_size, data, len); 338 memcpy(proxy->http_body + proxy->http_body_size, data, len);
350 proxy->http_body_size += len; 339 proxy->http_body_size += len;
351 PRINT_INFO2("received data for %s; %zu bytes", proxy->url, len); 340 PRINT_INFO2("received data for %s; %zu bytes", proxy->url, len);
352 glob_opt.spdy_data_received = true; 341 glob_opt.spdy_data_received = true;
353} 342}
354 343
355static void spdy_cb_on_data_recv(spdylay_session *session, 344
356 uint8_t flags, int32_t stream_id, int32_t length, void *user_data) 345static void
346spdy_cb_on_data_recv(spdylay_session *session,
347 uint8_t flags,
348 int32_t stream_id,
349 int32_t length,
350 void *user_data)
357{ 351{
358 (void)length; 352 (void)length;
359 (void)user_data; 353 (void)user_data;
@@ -367,18 +361,19 @@ static void spdy_cb_on_data_recv(spdylay_session *session,
367 } 361 }
368} 362}
369 363
364
370/* 365/*
371 * Setup callback functions. Spdylay API offers many callback 366 * Setup callback functions. Spdylay API offers many callback
372 * functions, but most of them are optional. The send_callback is 367 * functions, but most of them are optional. The send_callback is
373 * always required. Since we use spdylay_session_recv(), the 368 * always required. Since we use spdylay_session_recv(), the
374 * recv_callback is also required. 369 * recv_callback is also required.
375 */ 370 */
376static void spdy_setup_spdylay_callbacks(spdylay_session_callbacks *callbacks) 371static void
372spdy_setup_spdylay_callbacks(spdylay_session_callbacks *callbacks)
377{ 373{
378 memset(callbacks, 0, sizeof(spdylay_session_callbacks)); 374 memset(callbacks, 0, sizeof(spdylay_session_callbacks));
379 callbacks->send_callback = spdy_cb_send; 375 callbacks->send_callback = spdy_cb_send;
380 callbacks->recv_callback = spdy_cb_recv; 376 callbacks->recv_callback = spdy_cb_recv;
381 //callbacks->before_ctrl_send_callback = spdy_cb_before_ctrl_send;
382 callbacks->on_ctrl_send_callback = spdy_cb_on_ctrl_send; 377 callbacks->on_ctrl_send_callback = spdy_cb_on_ctrl_send;
383 callbacks->on_ctrl_recv_callback = spdy_cb_on_ctrl_recv; 378 callbacks->on_ctrl_recv_callback = spdy_cb_on_ctrl_recv;
384 callbacks->on_stream_close_callback = spdy_cb_on_stream_close; 379 callbacks->on_stream_close_callback = spdy_cb_on_stream_close;
@@ -386,21 +381,25 @@ static void spdy_setup_spdylay_callbacks(spdylay_session_callbacks *callbacks)
386 callbacks->on_data_recv_callback = spdy_cb_on_data_recv; 381 callbacks->on_data_recv_callback = spdy_cb_on_data_recv;
387} 382}
388 383
384
389/* 385/*
390 * Callback function for SSL/TLS NPN. Since this program only supports 386 * Callback function for SSL/TLS NPN. Since this program only supports
391 * SPDY protocol, if server does not offer SPDY protocol the Spdylay 387 * SPDY protocol, if server does not offer SPDY protocol the Spdylay
392 * library supports, we terminate program. 388 * library supports, we terminate program.
393 */ 389 */
394static int spdy_cb_ssl_select_next_proto(SSL* ssl, 390static int
395 unsigned char **out, unsigned char *outlen, 391spdy_cb_ssl_select_next_proto(SSL* ssl,
396 const unsigned char *in, unsigned int inlen, 392 unsigned char **out,
393 unsigned char *outlen,
394 const unsigned char *in,
395 unsigned int inlen,
397 void *arg) 396 void *arg)
398{ 397{
399 (void)ssl; 398 (void)ssl;
400 399
401 //PRINT_INFO("spdy_cb_ssl_select_next_proto");
402 int rv; 400 int rv;
403 uint16_t *spdy_proto_version; 401 uint16_t *spdy_proto_version;
402
404 /* spdylay_select_next_protocol() selects SPDY protocol version the 403 /* spdylay_select_next_protocol() selects SPDY protocol version the
405 Spdylay library supports. */ 404 Spdylay library supports. */
406 rv = spdylay_select_next_protocol(out, outlen, in, inlen); 405 rv = spdylay_select_next_protocol(out, outlen, in, inlen);
@@ -413,11 +412,14 @@ static int spdy_cb_ssl_select_next_proto(SSL* ssl,
413 return SSL_TLSEXT_ERR_OK; 412 return SSL_TLSEXT_ERR_OK;
414} 413}
415 414
415
416/* 416/*
417 * Setup SSL context. We pass |spdy_proto_version| to get negotiated 417 * Setup SSL context. We pass |spdy_proto_version| to get negotiated
418 * SPDY protocol version in NPN callback. 418 * SPDY protocol version in NPN callback.
419 */ 419 */
420void spdy_ssl_init_ssl_ctx(SSL_CTX *ssl_ctx, uint16_t *spdy_proto_version) 420void
421spdy_ssl_init_ssl_ctx(SSL_CTX *ssl_ctx,
422 uint16_t *spdy_proto_version)
421{ 423{
422 /* Disable SSLv2 and enable all workarounds for buggy servers */ 424 /* Disable SSLv2 and enable all workarounds for buggy servers */
423 SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION); 425 SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION);
@@ -428,153 +430,184 @@ void spdy_ssl_init_ssl_ctx(SSL_CTX *ssl_ctx, uint16_t *spdy_proto_version)
428 spdy_proto_version); 430 spdy_proto_version);
429} 431}
430 432
431static int spdy_ssl_handshake(SSL *ssl, int fd) 433
434static int
435spdy_ssl_handshake(SSL *ssl,
436 int fd)
432{ 437{
433 int rv; 438 int rv;
434 if(SSL_set_fd(ssl, fd) == 0) { 439
440 if(SSL_set_fd(ssl, fd) == 0)
435 spdy_dief("SSL_set_fd", ERR_error_string(ERR_get_error(), NULL)); 441 spdy_dief("SSL_set_fd", ERR_error_string(ERR_get_error(), NULL));
436 } 442
437 ERR_clear_error(); 443 ERR_clear_error();
438 rv = SSL_connect(ssl); 444 rv = SSL_connect(ssl);
439 if(rv <= 0) { 445 if(rv <= 0)
440 PRINT_INFO2("SSL_connect %s", ERR_error_string(ERR_get_error(), NULL)); 446 PRINT_INFO2("SSL_connect %s", ERR_error_string(ERR_get_error(), NULL));
441 }
442 447
443 return rv; 448 return rv;
444} 449}
445 450
451
446/* 452/*
447 * Connects to the host |host| and port |port|. This function returns 453 * Connects to the host |host| and port |port|. This function returns
448 * the file descriptor of the client socket. 454 * the file descriptor of the client socket.
449 */ 455 */
450static int spdy_socket_connect_to(const char *host, uint16_t port) 456static int
457spdy_socket_connect_to(const char *host,
458 uint16_t port)
451{ 459{
452 struct addrinfo hints; 460 struct addrinfo hints;
453 int fd = -1; 461 int fd = -1;
454 int rv; 462 int rv;
455 char service[NI_MAXSERV]; 463 char service[NI_MAXSERV];
456 struct addrinfo *res, *rp; 464 struct addrinfo *res, *rp;
465
466 //TODO checks
457 snprintf(service, sizeof(service), "%u", port); 467 snprintf(service, sizeof(service), "%u", port);
458 memset(&hints, 0, sizeof(struct addrinfo)); 468 memset(&hints, 0, sizeof(struct addrinfo));
459 hints.ai_family = AF_UNSPEC; 469 hints.ai_family = AF_UNSPEC;
460 hints.ai_socktype = SOCK_STREAM; 470 hints.ai_socktype = SOCK_STREAM;
461 rv = getaddrinfo(host, service, &hints, &res); 471 rv = getaddrinfo(host, service, &hints, &res);
462 if(rv != 0) { 472 if(rv != 0)
473 {
463 printf("%s\n",host); 474 printf("%s\n",host);
464 spdy_dief("getaddrinfo", gai_strerror(rv)); 475 spdy_dief("getaddrinfo", gai_strerror(rv));
465 } 476 }
466 for(rp = res; rp; rp = rp->ai_next) { 477 for(rp = res; rp; rp = rp->ai_next)
478 {
467 fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); 479 fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
468 if(fd == -1) { 480 if(fd == -1)
469 continue; 481 continue;
470 }
471 while((rv = connect(fd, rp->ai_addr, rp->ai_addrlen)) == -1 && 482 while((rv = connect(fd, rp->ai_addr, rp->ai_addrlen)) == -1 &&
472 errno == EINTR); 483 errno == EINTR);
473 if(rv == 0) { 484 if(rv == 0)
474 break; 485 break;
475 }
476 close(fd); 486 close(fd);
477 fd = -1; 487 fd = -1;
478 } 488 }
479 freeaddrinfo(res); 489 freeaddrinfo(res);
490
480 return fd; 491 return fd;
481} 492}
482 493
483static void spdy_socket_make_non_block(int fd) 494
495static void
496spdy_socket_make_non_block(int fd)
484{ 497{
485 int flags, rv; 498 int flags;
499 int rv;
500
486 while((flags = fcntl(fd, F_GETFL, 0)) == -1 && errno == EINTR); 501 while((flags = fcntl(fd, F_GETFL, 0)) == -1 && errno == EINTR);
487 if(flags == -1) { 502
503 if(flags == -1)
488 spdy_dief("fcntl", strerror(errno)); 504 spdy_dief("fcntl", strerror(errno));
489 } 505
490 while((rv = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1 && errno == EINTR); 506 while((rv = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1 && errno == EINTR);
491 if(rv == -1) { 507
508 if(rv == -1)
492 spdy_dief("fcntl", strerror(errno)); 509 spdy_dief("fcntl", strerror(errno));
493 }
494} 510}
495 511
512
496/* 513/*
497 * Setting TCP_NODELAY is not mandatory for the SPDY protocol. 514 * Setting TCP_NODELAY is not mandatory for the SPDY protocol.
498 */ 515 */
499static void spdy_socket_set_tcp_nodelay(int fd) 516static void
517spdy_socket_set_tcp_nodelay(int fd)
500{ 518{
501 int val = 1; 519 int val = 1;
502 int rv; 520 int rv;
521
503 rv = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, (socklen_t)sizeof(val)); 522 rv = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, (socklen_t)sizeof(val));
504 if(rv == -1) { 523 if(rv == -1)
505 spdy_dief("setsockopt", strerror(errno)); 524 spdy_dief("setsockopt", strerror(errno));
506 }
507} 525}
508 526
509/* 527/*
510 * Update |pollfd| based on the state of |connection|. 528 * Update |pollfd| based on the state of |connection|.
511 */ 529 */
512void spdy_ctl_poll(struct pollfd *pollfd, struct SPDY_Connection *connection) 530void
531spdy_ctl_poll(struct pollfd *pollfd,
532 struct SPDY_Connection *connection)
513{ 533{
514 pollfd->events = 0; 534 pollfd->events = 0;
515 if(spdylay_session_want_read(connection->session) || 535 if(spdylay_session_want_read(connection->session) ||
516 connection->want_io == WANT_READ) { 536 connection->want_io == WANT_READ)
537 {
517 pollfd->events |= POLLIN; 538 pollfd->events |= POLLIN;
518 } 539 }
519 if(spdylay_session_want_write(connection->session) || 540 if(spdylay_session_want_write(connection->session) ||
520 connection->want_io == WANT_WRITE) { 541 connection->want_io == WANT_WRITE)
542 {
521 pollfd->events |= POLLOUT; 543 pollfd->events |= POLLOUT;
522 } 544 }
523} 545}
524 546
547
525/* 548/*
526 * Update |selectfd| based on the state of |connection|. 549 * Update |selectfd| based on the state of |connection|.
527 */ 550 */
528bool spdy_ctl_select(fd_set * read_fd_set, 551bool
529 fd_set * write_fd_set, 552spdy_ctl_select(fd_set * read_fd_set,
530 fd_set * except_fd_set, 553 fd_set * write_fd_set,
531 struct SPDY_Connection *connection) 554 fd_set * except_fd_set,
555 struct SPDY_Connection *connection)
532{ 556{
533 (void)except_fd_set; 557 (void)except_fd_set;
534 558
535 bool ret = false; 559 bool ret = false;
536 560
537 if(spdylay_session_want_read(connection->session) || 561 if(spdylay_session_want_read(connection->session) ||
538 connection->want_io == WANT_READ) { 562 connection->want_io == WANT_READ)
563 {
539 FD_SET(connection->fd, read_fd_set); 564 FD_SET(connection->fd, read_fd_set);
540 ret = true; 565 ret = true;
541 } 566 }
542 if(spdylay_session_want_write(connection->session) || 567 if(spdylay_session_want_write(connection->session) ||
543 connection->want_io == WANT_WRITE) { 568 connection->want_io == WANT_WRITE)
569 {
544 FD_SET(connection->fd, write_fd_set); 570 FD_SET(connection->fd, write_fd_set);
545 ret = true; 571 ret = true;
546 } 572 }
573
547 return ret; 574 return ret;
548} 575}
549 576
577
550/* 578/*
551 * Performs the network I/O. 579 * Performs the network I/O.
552 */ 580 */
553int spdy_exec_io(struct SPDY_Connection *connection) 581int
582spdy_exec_io(struct SPDY_Connection *connection)
554{ 583{
555 int rv; 584 int rv;
585
556 rv = spdylay_session_recv(connection->session); 586 rv = spdylay_session_recv(connection->session);
557 if(rv != 0) { 587 if(rv != 0)
588 {
558 PRINT_INFO2("spdylay_session_recv %i", rv); 589 PRINT_INFO2("spdylay_session_recv %i", rv);
559 return rv; 590 return rv;
560 } 591 }
561 rv = spdylay_session_send(connection->session); 592 rv = spdylay_session_send(connection->session);
562 if(rv != 0) { 593 if(rv != 0)
563 PRINT_INFO2("spdylay_session_send %i", rv); 594 PRINT_INFO2("spdylay_session_send %i", rv);
564 } 595
565 return rv; 596 return rv;
566} 597}
567 598
599
568/* 600/*
569 * Fetches the resource denoted by |uri|. 601 * Fetches the resource denoted by |uri|.
570 */ 602 */
571struct SPDY_Connection * spdy_connect(const struct URI *uri, uint16_t port, bool is_tls) 603struct SPDY_Connection *
604spdy_connect(const struct URI *uri,
605 uint16_t port,
606 bool is_tls)
572{ 607{
573 spdylay_session_callbacks callbacks; 608 spdylay_session_callbacks callbacks;
574 int fd; 609 int fd;
575 //SSL_CTX *ssl_ctx;
576 SSL *ssl=NULL; 610 SSL *ssl=NULL;
577 //struct SPDY_Request req;
578 struct SPDY_Connection * connection; 611 struct SPDY_Connection * connection;
579 int rv; 612 int rv;
580 613
@@ -583,19 +616,14 @@ struct SPDY_Connection * spdy_connect(const struct URI *uri, uint16_t port, bool
583 /* Establish connection and setup SSL */ 616 /* Establish connection and setup SSL */
584 PRINT_INFO2("connecting to %s:%i", uri->host, port); 617 PRINT_INFO2("connecting to %s:%i", uri->host, port);
585 fd = spdy_socket_connect_to(uri->host, port); 618 fd = spdy_socket_connect_to(uri->host, port);
586 if(fd == -1) { 619 if(fd == -1)
620 {
587 PRINT_INFO("Could not open file descriptor"); 621 PRINT_INFO("Could not open file descriptor");
588 return NULL;//glob_opt.spdy_connection; 622 return NULL;
589 } 623 }
590 624
591 if(is_tls) 625 if(is_tls)
592 { 626 {
593 /*ssl_ctx = SSL_CTX_new(SSLv23_client_method());
594 if(ssl_ctx == NULL) {
595 spdy_dief("SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL));
596 }
597 spdy_ssl_init_ssl_ctx(ssl_ctx, &spdy_proto_version);
598 */
599 ssl = SSL_new(glob_opt.ssl_ctx); 627 ssl = SSL_new(glob_opt.ssl_ctx);
600 if(ssl == NULL) { 628 if(ssl == NULL) {
601 spdy_dief("SSL_new", ERR_error_string(ERR_get_error(), NULL)); 629 spdy_dief("SSL_new", ERR_error_string(ERR_get_error(), NULL));
@@ -624,7 +652,6 @@ struct SPDY_Connection * spdy_connect(const struct URI *uri, uint16_t port, bool
624 652
625 if(NULL == (connection = au_malloc(sizeof(struct SPDY_Connection)))) 653 if(NULL == (connection = au_malloc(sizeof(struct SPDY_Connection))))
626 return NULL; 654 return NULL;
627 //memset(connection, 0 , sizeof(struct SPDY_Connection));
628 655
629 connection->is_tls = is_tls; 656 connection->is_tls = is_tls;
630 connection->ssl = ssl; 657 connection->ssl = ssl;
@@ -647,6 +674,7 @@ struct SPDY_Connection * spdy_connect(const struct URI *uri, uint16_t port, bool
647 return connection; 674 return connection;
648} 675}
649 676
677
650void 678void
651spdy_free_connection(struct SPDY_Connection * connection) 679spdy_free_connection(struct SPDY_Connection * connection)
652{ 680{
@@ -659,8 +687,10 @@ spdy_free_connection(struct SPDY_Connection * connection)
659 } 687 }
660} 688}
661 689
690
662int 691int
663spdy_request(const char **nv, struct Proxy *proxy) 692spdy_request(const char **nv,
693 struct Proxy *proxy)
664{ 694{
665 int ret; 695 int ret;
666 uint16_t port; 696 uint16_t port;
@@ -714,13 +744,18 @@ spdy_request(const char **nv, struct Proxy *proxy)
714 744
715 745
716void 746void
717spdy_get_pollfdset(struct pollfd fds[], struct SPDY_Connection *connections[], unsigned int max_size, nfds_t *real_size) 747spdy_get_pollfdset(struct pollfd fds[],
748 struct SPDY_Connection *connections[],
749 unsigned int max_size,
750 nfds_t *real_size)
718{ 751{
719 struct SPDY_Connection *connection; 752 struct SPDY_Connection *connection;
720 struct Proxy *proxy; 753 struct Proxy *proxy;
721 754
722 *real_size = 0; 755 *real_size = 0;
723 if(max_size<1) return; 756 if(max_size<1)
757 return;
758
724 if(NULL != glob_opt.spdy_connection) 759 if(NULL != glob_opt.spdy_connection)
725 { 760 {
726 spdy_ctl_poll(&(fds[*real_size]), glob_opt.spdy_connection); 761 spdy_ctl_poll(&(fds[*real_size]), glob_opt.spdy_connection);
@@ -781,9 +816,11 @@ spdy_get_pollfdset(struct pollfd fds[], struct SPDY_Connection *connections[], u
781 816
782int 817int
783spdy_get_selectfdset(fd_set * read_fd_set, 818spdy_get_selectfdset(fd_set * read_fd_set,
784 fd_set * write_fd_set, 819 fd_set * write_fd_set,
785 fd_set * except_fd_set, 820 fd_set * except_fd_set,
786 struct SPDY_Connection *connections[], unsigned int max_size, nfds_t *real_size) 821 struct SPDY_Connection *connections[],
822 unsigned int max_size,
823 nfds_t *real_size)
787{ 824{
788 struct SPDY_Connection *connection; 825 struct SPDY_Connection *connection;
789 struct Proxy *proxy; 826 struct Proxy *proxy;
@@ -791,7 +828,9 @@ spdy_get_selectfdset(fd_set * read_fd_set,
791 int maxfd = 0; 828 int maxfd = 0;
792 829
793 *real_size = 0; 830 *real_size = 0;
794 if(max_size<1) return 0; 831 if(max_size<1)
832 return 0;
833
795 if(NULL != glob_opt.spdy_connection) 834 if(NULL != glob_opt.spdy_connection)
796 { 835 {
797 ret = spdy_ctl_select(read_fd_set, 836 ret = spdy_ctl_select(read_fd_set,
@@ -857,12 +896,13 @@ spdy_get_selectfdset(fd_set * read_fd_set,
857 896
858 897
859void 898void
860spdy_run(struct pollfd fds[], struct SPDY_Connection *connections[], int size) 899spdy_run(struct pollfd fds[],
900 struct SPDY_Connection *connections[],
901 int size)
861{ 902{
862 int i; 903 int i;
863 int ret; 904 int ret;
864 struct Proxy *proxy; 905 struct Proxy *proxy;
865 //PRINT_INFO2("size is %i", size);
866 906
867 for(i=0; i<size; ++i) 907 for(i=0; i<size; ++i)
868 { 908 {
@@ -898,21 +938,20 @@ spdy_run(struct pollfd fds[], struct SPDY_Connection *connections[], int size)
898 } 938 }
899 } 939 }
900 else 940 else
901 {
902 PRINT_INFO("not called"); 941 PRINT_INFO("not called");
903 }
904 } 942 }
905} 943}
906 944
907void 945void
908spdy_run_select(fd_set * read_fd_set, 946spdy_run_select(fd_set * read_fd_set,
909 fd_set * write_fd_set, 947 fd_set * write_fd_set,
910 fd_set * except_fd_set, struct SPDY_Connection *connections[], int size) 948 fd_set * except_fd_set,
949 struct SPDY_Connection *connections[],
950 int size)
911{ 951{
912 int i; 952 int i;
913 int ret; 953 int ret;
914 struct Proxy *proxy; 954 struct Proxy *proxy;
915 //PRINT_INFO2("size is %i", size);
916 955
917 for(i=0; i<size; ++i) 956 for(i=0; i<size; ++i)
918 { 957 {
@@ -920,12 +959,6 @@ spdy_run_select(fd_set * read_fd_set,
920 if(FD_ISSET(connections[i]->fd, read_fd_set) || FD_ISSET(connections[i]->fd, write_fd_set) || FD_ISSET(connections[i]->fd, except_fd_set)) 959 if(FD_ISSET(connections[i]->fd, read_fd_set) || FD_ISSET(connections[i]->fd, write_fd_set) || FD_ISSET(connections[i]->fd, except_fd_set))
921 { 960 {
922 ret = spdy_exec_io(connections[i]); 961 ret = spdy_exec_io(connections[i]);
923 //PRINT_INFO2("%i",ret);
924 //if((spdy_pollfds[i].revents & POLLHUP) || (spdy_pollfds[0].revents & POLLERR))
925 // PRINT_INFO("SPDY SPDY_Connection error");
926
927 //TODO POLLRDHUP
928 // always close on ret != 0?
929 962
930 if(0 != ret) 963 if(0 != ret)
931 { 964 {
@@ -948,8 +981,6 @@ spdy_run_select(fd_set * read_fd_set,
948 } 981 }
949 } 982 }
950 else 983 else
951 {
952 PRINT_INFO("not called"); 984 PRINT_INFO("not called");
953 }
954 } 985 }
955} 986}