diff options
Diffstat (limited to 'src/examples/mhd2spdy_spdy.c')
-rw-r--r-- | src/examples/mhd2spdy_spdy.c | 112 |
1 files changed, 102 insertions, 10 deletions
diff --git a/src/examples/mhd2spdy_spdy.c b/src/examples/mhd2spdy_spdy.c index 413de7f3..fb749291 100644 --- a/src/examples/mhd2spdy_spdy.c +++ b/src/examples/mhd2spdy_spdy.c | |||
@@ -63,6 +63,69 @@ spdy_diec(const char *func, | |||
63 | } | 63 | } |
64 | 64 | ||
65 | 65 | ||
66 | static ssize_t | ||
67 | spdy_cb_data_source_read(spdylay_session *session, int32_t stream_id, uint8_t *buf, size_t length, int *eof, spdylay_data_source *source, void *user_data) | ||
68 | { | ||
69 | (void)session; | ||
70 | (void)stream_id; | ||
71 | (void)user_data; | ||
72 | |||
73 | ssize_t ret; | ||
74 | assert(NULL != source); | ||
75 | assert(NULL != source->ptr); | ||
76 | struct Proxy *proxy = (struct Proxy *)(source->ptr); | ||
77 | void *newbody; | ||
78 | |||
79 | |||
80 | if(length < 1) | ||
81 | { | ||
82 | PRINT_INFO("spdy_cb_data_source_read: length is 0"); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | if(!proxy->received_body_size)//nothing to write now | ||
87 | { | ||
88 | if(proxy->receiving_done) | ||
89 | { | ||
90 | PRINT_INFO("POST spdy EOF"); | ||
91 | *eof = 1; | ||
92 | } | ||
93 | PRINT_INFO("POST SPDYLAY_ERR_DEFERRED"); | ||
94 | return SPDYLAY_ERR_DEFERRED;//TODO SPDYLAY_ERR_DEFERRED should be used | ||
95 | } | ||
96 | |||
97 | if(length >= proxy->received_body_size) | ||
98 | { | ||
99 | ret = proxy->received_body_size; | ||
100 | newbody = NULL; | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | ret = length; | ||
105 | if(NULL == (newbody = malloc(proxy->received_body_size - length))) | ||
106 | { | ||
107 | PRINT_INFO("no memory"); | ||
108 | return SPDYLAY_ERR_TEMPORAL_CALLBACK_FAILURE; | ||
109 | } | ||
110 | memcpy(newbody, proxy->received_body + length, proxy->received_body_size - length); | ||
111 | } | ||
112 | memcpy(buf, proxy->received_body, ret); | ||
113 | free(proxy->received_body); | ||
114 | proxy->received_body = newbody; | ||
115 | proxy->received_body_size -= ret; | ||
116 | |||
117 | if(0 == proxy->received_body_size && proxy->receiving_done) | ||
118 | { | ||
119 | PRINT_INFO("POST spdy EOF"); | ||
120 | *eof = 1; | ||
121 | } | ||
122 | |||
123 | PRINT_INFO2("given POST bytes to spdylay: %zd", ret); | ||
124 | |||
125 | return ret; | ||
126 | } | ||
127 | |||
128 | |||
66 | /* | 129 | /* |
67 | * The implementation of spdylay_send_callback type. Here we write | 130 | * The implementation of spdylay_send_callback type. Here we write |
68 | * |data| with size |length| to the network and return the number of | 131 | * |data| with size |length| to the network and return the number of |
@@ -91,7 +154,7 @@ spdy_cb_send(spdylay_session *session, | |||
91 | if(rv < 0) { | 154 | if(rv < 0) { |
92 | int err = SSL_get_error(connection->ssl, rv); | 155 | int err = SSL_get_error(connection->ssl, rv); |
93 | if(err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) { | 156 | if(err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) { |
94 | connection->want_io = (err == SSL_ERROR_WANT_READ ? | 157 | connection->want_io |= (err == SSL_ERROR_WANT_READ ? |
95 | WANT_READ : WANT_WRITE); | 158 | WANT_READ : WANT_WRITE); |
96 | rv = SPDYLAY_ERR_WOULDBLOCK; | 159 | rv = SPDYLAY_ERR_WOULDBLOCK; |
97 | } else { | 160 | } else { |
@@ -113,7 +176,7 @@ spdy_cb_send(spdylay_session *session, | |||
113 | #if EAGAIN != EWOULDBLOCK | 176 | #if EAGAIN != EWOULDBLOCK |
114 | case EWOULDBLOCK: | 177 | case EWOULDBLOCK: |
115 | #endif | 178 | #endif |
116 | connection->want_io = WANT_WRITE; | 179 | connection->want_io |= WANT_WRITE; |
117 | rv = SPDYLAY_ERR_WOULDBLOCK; | 180 | rv = SPDYLAY_ERR_WOULDBLOCK; |
118 | break; | 181 | break; |
119 | 182 | ||
@@ -122,6 +185,9 @@ spdy_cb_send(spdylay_session *session, | |||
122 | } | 185 | } |
123 | } | 186 | } |
124 | } | 187 | } |
188 | |||
189 | PRINT_INFO2("%zd bytes written by spdy", rv); | ||
190 | |||
125 | return rv; | 191 | return rv; |
126 | } | 192 | } |
127 | 193 | ||
@@ -156,7 +222,7 @@ spdy_cb_recv(spdylay_session *session, | |||
156 | if(rv < 0) { | 222 | if(rv < 0) { |
157 | int err = SSL_get_error(connection->ssl, rv); | 223 | int err = SSL_get_error(connection->ssl, rv); |
158 | if(err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) { | 224 | if(err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) { |
159 | connection->want_io = (err == SSL_ERROR_WANT_READ ? | 225 | connection->want_io |= (err == SSL_ERROR_WANT_READ ? |
160 | WANT_READ : WANT_WRITE); | 226 | WANT_READ : WANT_WRITE); |
161 | rv = SPDYLAY_ERR_WOULDBLOCK; | 227 | rv = SPDYLAY_ERR_WOULDBLOCK; |
162 | } else { | 228 | } else { |
@@ -180,7 +246,7 @@ spdy_cb_recv(spdylay_session *session, | |||
180 | #if EAGAIN != EWOULDBLOCK | 246 | #if EAGAIN != EWOULDBLOCK |
181 | case EWOULDBLOCK: | 247 | case EWOULDBLOCK: |
182 | #endif | 248 | #endif |
183 | connection->want_io = WANT_READ; | 249 | connection->want_io |= WANT_READ; |
184 | rv = SPDYLAY_ERR_WOULDBLOCK; | 250 | rv = SPDYLAY_ERR_WOULDBLOCK; |
185 | break; | 251 | break; |
186 | 252 | ||
@@ -210,6 +276,7 @@ spdy_cb_on_ctrl_send(spdylay_session *session, | |||
210 | case SPDYLAY_SYN_STREAM: | 276 | case SPDYLAY_SYN_STREAM: |
211 | stream_id = frame->syn_stream.stream_id; | 277 | stream_id = frame->syn_stream.stream_id; |
212 | proxy = spdylay_session_get_stream_user_data(session, stream_id); | 278 | proxy = spdylay_session_get_stream_user_data(session, stream_id); |
279 | proxy->stream_id = stream_id; | ||
213 | ++glob_opt.streams_opened; | 280 | ++glob_opt.streams_opened; |
214 | ++proxy->spdy_connection->streams_opened; | 281 | ++proxy->spdy_connection->streams_opened; |
215 | PRINT_INFO2("opening stream: str open %i; %s", glob_opt.streams_opened, proxy->url); | 282 | PRINT_INFO2("opening stream: str open %i; %s", glob_opt.streams_opened, proxy->url); |
@@ -325,6 +392,13 @@ spdy_cb_on_data_chunk_recv(spdylay_session *session, | |||
325 | struct Proxy *proxy; | 392 | struct Proxy *proxy; |
326 | proxy = spdylay_session_get_stream_user_data(session, stream_id); | 393 | proxy = spdylay_session_get_stream_user_data(session, stream_id); |
327 | 394 | ||
395 | if(!copy_buffer(data, len, &proxy->http_body, &proxy->http_body_size)) | ||
396 | { | ||
397 | //TODO handle it better? | ||
398 | PRINT_INFO("not enough memory (malloc/realloc returned NULL)"); | ||
399 | return; | ||
400 | } | ||
401 | /* | ||
328 | if(NULL == proxy->http_body) | 402 | if(NULL == proxy->http_body) |
329 | proxy->http_body = au_malloc(len); | 403 | proxy->http_body = au_malloc(len); |
330 | else | 404 | else |
@@ -337,6 +411,7 @@ spdy_cb_on_data_chunk_recv(spdylay_session *session, | |||
337 | 411 | ||
338 | memcpy(proxy->http_body + proxy->http_body_size, data, len); | 412 | memcpy(proxy->http_body + proxy->http_body_size, data, len); |
339 | proxy->http_body_size += len; | 413 | proxy->http_body_size += len; |
414 | */ | ||
340 | PRINT_INFO2("received data for %s; %zu bytes", proxy->url, len); | 415 | PRINT_INFO2("received data for %s; %zu bytes", proxy->url, len); |
341 | glob_opt.spdy_data_received = true; | 416 | glob_opt.spdy_data_received = true; |
342 | } | 417 | } |
@@ -533,12 +608,12 @@ spdy_ctl_poll(struct pollfd *pollfd, | |||
533 | { | 608 | { |
534 | pollfd->events = 0; | 609 | pollfd->events = 0; |
535 | if(spdylay_session_want_read(connection->session) || | 610 | if(spdylay_session_want_read(connection->session) || |
536 | connection->want_io == WANT_READ) | 611 | connection->want_io & WANT_READ) |
537 | { | 612 | { |
538 | pollfd->events |= POLLIN; | 613 | pollfd->events |= POLLIN; |
539 | } | 614 | } |
540 | if(spdylay_session_want_write(connection->session) || | 615 | if(spdylay_session_want_write(connection->session) || |
541 | connection->want_io == WANT_WRITE) | 616 | connection->want_io & WANT_WRITE) |
542 | { | 617 | { |
543 | pollfd->events |= POLLOUT; | 618 | pollfd->events |= POLLOUT; |
544 | } | 619 | } |
@@ -559,13 +634,13 @@ spdy_ctl_select(fd_set * read_fd_set, | |||
559 | bool ret = false; | 634 | bool ret = false; |
560 | 635 | ||
561 | if(spdylay_session_want_read(connection->session) || | 636 | if(spdylay_session_want_read(connection->session) || |
562 | connection->want_io == WANT_READ) | 637 | connection->want_io & WANT_READ) |
563 | { | 638 | { |
564 | FD_SET(connection->fd, read_fd_set); | 639 | FD_SET(connection->fd, read_fd_set); |
565 | ret = true; | 640 | ret = true; |
566 | } | 641 | } |
567 | if(spdylay_session_want_write(connection->session) || | 642 | if(spdylay_session_want_write(connection->session) || |
568 | connection->want_io == WANT_WRITE) | 643 | connection->want_io & WANT_WRITE) |
569 | { | 644 | { |
570 | FD_SET(connection->fd, write_fd_set); | 645 | FD_SET(connection->fd, write_fd_set); |
571 | ret = true; | 646 | ret = true; |
@@ -690,11 +765,13 @@ spdy_free_connection(struct SPDY_Connection * connection) | |||
690 | 765 | ||
691 | int | 766 | int |
692 | spdy_request(const char **nv, | 767 | spdy_request(const char **nv, |
693 | struct Proxy *proxy) | 768 | struct Proxy *proxy, |
769 | bool with_body) | ||
694 | { | 770 | { |
695 | int ret; | 771 | int ret; |
696 | uint16_t port; | 772 | uint16_t port; |
697 | struct SPDY_Connection *connection; | 773 | struct SPDY_Connection *connection; |
774 | spdylay_data_provider post_data; | ||
698 | 775 | ||
699 | if(glob_opt.only_proxy) | 776 | if(glob_opt.only_proxy) |
700 | { | 777 | { |
@@ -733,7 +810,15 @@ spdy_request(const char **nv, | |||
733 | } | 810 | } |
734 | 811 | ||
735 | proxy->spdy_connection = connection; | 812 | proxy->spdy_connection = connection; |
736 | ret = spdylay_submit_request(connection->session, 0, nv, NULL, proxy); | 813 | if(with_body) |
814 | { | ||
815 | post_data.source.ptr = proxy; | ||
816 | post_data.read_callback = &spdy_cb_data_source_read; | ||
817 | ret = spdylay_submit_request(connection->session, 0, nv, &post_data, proxy); | ||
818 | } | ||
819 | else | ||
820 | ret = spdylay_submit_request(connection->session, 0, nv, NULL, proxy); | ||
821 | |||
737 | if(ret != 0) { | 822 | if(ret != 0) { |
738 | spdy_diec("spdylay_spdy_submit_request", ret); | 823 | spdy_diec("spdylay_spdy_submit_request", ret); |
739 | } | 824 | } |
@@ -958,6 +1043,7 @@ spdy_run_select(fd_set * read_fd_set, | |||
958 | // PRINT_INFO2("exec about to be called for %s", connections[i]->host); | 1043 | // PRINT_INFO2("exec about to be called for %s", connections[i]->host); |
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)) | 1044 | 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)) |
960 | { | 1045 | { |
1046 | //raise(SIGINT); | ||
961 | ret = spdy_exec_io(connections[i]); | 1047 | ret = spdy_exec_io(connections[i]); |
962 | 1048 | ||
963 | if(0 != ret) | 1049 | if(0 != ret) |
@@ -981,6 +1067,12 @@ spdy_run_select(fd_set * read_fd_set, | |||
981 | } | 1067 | } |
982 | } | 1068 | } |
983 | else | 1069 | else |
1070 | { | ||
984 | PRINT_INFO("not called"); | 1071 | PRINT_INFO("not called"); |
1072 | PRINT_INFO2("connection->want_io %i",connections[i]->want_io); | ||
1073 | PRINT_INFO2("read %i",spdylay_session_want_read(connections[i]->session)); | ||
1074 | PRINT_INFO2("write %i",spdylay_session_want_write(connections[i]->session)); | ||
1075 | //raise(SIGINT); | ||
1076 | } | ||
985 | } | 1077 | } |
986 | } | 1078 | } |