/* * The implementation of spdylay_on_data_chunk_recv_callback type. We * use this function to print the received response body. */ static void on_data_chunk_recv_callback(spdylay_session *session, uint8_t flags, int32_t stream_id, const uint8_t *data, size_t len, void *user_data) { struct Request *req; req = spdylay_session_get_stream_user_data(session, stream_id); if(req) { printf("[INFO] C <---------------------------- S (DATA)\n"); printf(" %lu bytes\n", (unsigned long int)len); if(req->inflater) { while(len > 0) { uint8_t out[MAX_OUTLEN]; size_t outlen = MAX_OUTLEN; size_t tlen = len; int rv; rv = spdylay_gzip_inflate(req->inflater, out, &outlen, data, &tlen); if(rv == -1) { spdylay_submit_rst_stream(session, stream_id, SPDYLAY_INTERNAL_ERROR); break; } fwrite(out, 1, outlen, stdout); data += tlen; len -= tlen; } } else { /* TODO add support gzip */ fwrite(data, 1, len, stdout); } printf("\n"); } }
void http_cb_request_completed (void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe) { (void)cls; (void)connection; struct HTTP_URI *http_uri; struct Proxy *proxy; http_uri = (struct HTTP_URI *)*con_cls; if(NULL == http_uri) return; proxy = (struct Proxy *)http_uri->proxy; assert(NULL != proxy); PRINT_INFO2("http_cb_request_completed %i for %s; id %i",toe, http_uri->uri, proxy->id); if(NULL != proxy->http_response) { MHD_destroy_response (proxy->http_response); proxy->http_response = NULL; } if(proxy->spdy_active) { proxy->http_active = false; if(MHD_REQUEST_TERMINATED_COMPLETED_OK != toe) { proxy->http_error = true; if(proxy->stream_id > 0 /*&& NULL != proxy->spdy_connection->session*/) { //send RST_STREAM_STATUS_CANCEL PRINT_INFO2("send rst_stream %i %i",proxy->spdy_active, proxy->stream_id ); spdylay_submit_rst_stream(proxy->spdy_connection->session, proxy->stream_id, 5); } /*else { DLL_remove(proxy->spdy_connection->proxies_head, proxy->spdy_connection->proxies_tail, proxy); free_proxy(proxy); }*/ } } else { PRINT_INFO2("proxy free http id %i ", proxy->id); free_proxy(proxy); } --glob_opt.responses_pending; }
/* * The implementation of spdylay_on_data_chunk_recv_callback type. We * use this function to print the received response body. */ static void on_data_chunk_recv_callback(spdylay_session *session, uint8_t flags, int32_t stream_id, const uint8_t *data, size_t len, void *user_data) { (void)user_data; (void)flags; struct Request *req; req = spdylay_session_get_stream_user_data(session, stream_id); if(req) { printf("[INFO] C <---------------------------- S (DATA)\n"); printf(" %lu bytes\n", (unsigned long int)len); if(req->inflater) { while(len > 0) { uint8_t out[MAX_OUTLEN]; size_t outlen = MAX_OUTLEN; size_t tlen = len; int rv; rv = spdylay_gzip_inflate(req->inflater, out, &outlen, data, &tlen); if(rv == -1) { spdylay_submit_rst_stream(session, stream_id, SPDYLAY_INTERNAL_ERROR); break; } fwrite(out, 1, outlen, stdout); data += tlen; len -= tlen; } } else { /* TODO add support gzip */ fwrite(data, 1, len, stdout); //check if the data is correct //if(strcmp(RESPONSE_BODY, data) != 0) //killparent(parent, "\nreceived data is not the same"); if(len + rcvbuf_c > strlen(RESPONSE_BODY)) killparent(parent, "\nreceived data is not the same"); strcpy(rcvbuf + rcvbuf_c,(char*)data); rcvbuf_c+=len; } printf("\n"); } }
static void run_spdylay_session_send(void) { spdylay_session *session; spdylay_session_callbacks callbacks; const char *nv[] = { ":host", "example.org", ":scheme", "https", NULL }; spdylay_data_provider data_prd; spdylay_settings_entry iv[2]; my_user_data ud; int rv; memset(&callbacks, 0, sizeof(spdylay_session_callbacks)); callbacks.send_callback = null_send_callback; callbacks.get_credential_ncerts = get_credential_ncerts; callbacks.get_credential_cert = get_credential_cert; callbacks.get_credential_proof = get_credential_proof; data_prd.read_callback = fixed_length_data_source_read_callback; ud.data_source_length = 64*1024; iv[0].settings_id = SPDYLAY_SETTINGS_UPLOAD_BANDWIDTH; iv[0].flags = SPDYLAY_ID_FLAG_SETTINGS_PERSIST_VALUE; iv[0].value = 256; iv[1].settings_id = SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS; iv[1].flags = SPDYLAY_ID_FLAG_SETTINGS_NONE; iv[1].value = 100; rv = spdylay_session_client_new(&session, SPDYLAY_PROTO_SPDY3, &callbacks, &ud); if(rv != 0) { goto client_new_fail; } rv = spdylay_submit_request(session, 3, nv, &data_prd, NULL); if(rv != 0) { goto fail; } rv = spdylay_submit_syn_stream(session, SPDYLAY_CTRL_FLAG_NONE, 0, 3, nv, NULL); if(rv != 0) { goto fail; } rv = spdylay_session_send(session); if(rv != 0) { goto fail; } /* The SYN_STREAM submitted by the previous spdylay_submit_syn_stream will have stream ID 3. Send HEADERS to that stream. */ rv = spdylay_submit_headers(session, SPDYLAY_CTRL_FLAG_NONE, 3, nv); if(rv != 0) { goto fail; } rv = spdylay_submit_data(session, 3, SPDYLAY_DATA_FLAG_FIN, &data_prd); if(rv != 0) { goto fail; } rv = spdylay_session_send(session); if(rv != 0) { goto fail; } rv = spdylay_submit_rst_stream(session, 3, SPDYLAY_CANCEL); if(rv != 0) { goto fail; } rv = spdylay_session_send(session); if(rv != 0) { goto fail; } /* Sending against half-closed stream */ rv = spdylay_submit_headers(session, SPDYLAY_CTRL_FLAG_NONE, 3, nv); if(rv != 0) { goto fail; } rv = spdylay_submit_data(session, 3, SPDYLAY_DATA_FLAG_FIN, &data_prd); if(rv != 0) { goto fail; } rv = spdylay_submit_ping(session); if(rv != 0) { goto fail; } rv = spdylay_submit_settings(session, SPDYLAY_FLAG_SETTINGS_NONE, iv, 2); if(rv != 0) { goto fail; } rv = spdylay_session_send(session); if(rv != 0) { goto fail; } rv = spdylay_submit_goaway(session, SPDYLAY_GOAWAY_OK); if(rv != 0) { goto fail; } rv = spdylay_session_send(session); if(rv != 0) { goto fail; } fail: spdylay_session_del(session); client_new_fail: ; }