diff options
Diffstat (limited to 'src/examples/spdy_response_with_callback.c')
-rw-r--r-- | src/examples/spdy_response_with_callback.c | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/src/examples/spdy_response_with_callback.c b/src/examples/spdy_response_with_callback.c new file mode 100644 index 00000000..5bd452d2 --- /dev/null +++ b/src/examples/spdy_response_with_callback.c @@ -0,0 +1,236 @@ +/* + This file is part of libmicrospdy + Copyright Copyright (C) 2013 Andrey Uzunov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/** + * @file response_with_callback.c + * @brief shows how to create responses with callbacks + * @author Andrey Uzunov + */ + +//for asprintf +#define _GNU_SOURCE + +#include <unistd.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdbool.h> +#include <string.h> +#include <stdio.h> +#include <ctype.h> +#include <errno.h> +#include "microspdy.h" + +static int run = 1; + + +static ssize_t +response_callback (void *cls, + void *buffer, + size_t max, + bool *more) +{ + FILE *fd =(FILE*)cls; + + int ret = fread(buffer,1,max,fd); + *more = feof(fd) == 0; + + if(!(*more)) + fclose(fd); + + return ret; +} + + +static void +response_done_callback(void *cls, + struct SPDY_Response *response, + struct SPDY_Request *request, + enum SPDY_RESPONSE_RESULT status, + bool streamopened) +{ + (void)streamopened; + (void)status; + + printf("answer for %s was sent\n", (char *)cls); + + SPDY_destroy_request(request); + SPDY_destroy_response(response); + free(cls); +} + + +static void +standard_request_handler(void *cls, + struct SPDY_Request * request, + uint8_t priority, + const char *method, + const char *path, + const char *version, + const char *host, + const char *scheme, + struct SPDY_NameValue * headers, + bool more) +{ + (void)cls; + (void)request; + (void)priority; + (void)host; + (void)scheme; + (void)headers; + (void)more; + + char *html; + struct SPDY_Response *response=NULL; + struct SPDY_NameValue *resp_headers; + + printf("received request for '%s %s %s'\n", method, path, version); + if(strcmp(path,"/spdy-draft.txt")==0) + { + FILE *fd = fopen(DATA_DIR "spdy-draft.txt","r"); + + if(NULL == (resp_headers = SPDY_name_value_create())) + { + fprintf(stdout,"SPDY_name_value_create failed\n"); + abort(); + } + if(SPDY_YES != SPDY_name_value_add(resp_headers,SPDY_HTTP_HEADER_CONTENT_TYPE,"text/plain")) + { + fprintf(stdout,"SPDY_name_value_add failed\n"); + abort(); + } + + response = SPDY_build_response_with_callback(200,NULL, + SPDY_HTTP_VERSION_1_1,resp_headers,&response_callback,fd,SPDY_MAX_SUPPORTED_FRAME_SIZE); + SPDY_name_value_destroy(resp_headers); + } + else + { + if(strcmp(path,"/close")==0) + { + asprintf(&html,"<html>" + "<body><b>Closing now!</body></html>"); + run = 0; + } + else + { + asprintf(&html,"<html>" + "<body><a href=\"/spdy-draft.txt\">/spdy-draft.txt</a><br></body></html>"); + } + + response = SPDY_build_response(200,NULL,SPDY_HTTP_VERSION_1_1,NULL,html,strlen(html)); + free(html); + } + + if(NULL==response){ + fprintf(stdout,"no response obj\n"); + abort(); + } + + void *clspath = strdup(path); + + if(SPDY_queue_response(request,response,true,false,&response_done_callback,clspath)!=SPDY_YES) + { + fprintf(stdout,"queue\n"); + abort(); + } +} + + +int +main (int argc, char *const *argv) +{ + unsigned long long timeoutlong=0; + struct timeval timeout; + int ret; + fd_set read_fd_set; + fd_set write_fd_set; + fd_set except_fd_set; + int maxfd = -1; + struct SPDY_Daemon *daemon; + + if(argc != 2) + { + return 1; + } + + SPDY_init(); + + daemon = SPDY_start_daemon(atoi(argv[1]), + DATA_DIR "cert-and-key.pem", + DATA_DIR "cert-and-key.pem", + NULL, + NULL, + &standard_request_handler, + NULL, + NULL, + SPDY_DAEMON_OPTION_SESSION_TIMEOUT, + 1800, + SPDY_DAEMON_OPTION_END); + + if(NULL==daemon){ + printf("no daemon\n"); + return 1; + } + + do + { + FD_ZERO(&read_fd_set); + FD_ZERO(&write_fd_set); + FD_ZERO(&except_fd_set); + + ret = SPDY_get_timeout(daemon, &timeoutlong); + if(SPDY_NO == ret || timeoutlong > 1000) + { + timeout.tv_sec = 1; + timeout.tv_usec = 0; + } + else + { + timeout.tv_sec = timeoutlong / 1000; + timeout.tv_usec = (timeoutlong % 1000) * 1000; + } + + maxfd = SPDY_get_fdset (daemon, + &read_fd_set, + &write_fd_set, + &except_fd_set); + + ret = select(maxfd+1, &read_fd_set, &write_fd_set, &except_fd_set, &timeout); + + switch(ret) { + case -1: + printf("select error: %i\n", errno); + break; + case 0: + + break; + default: + SPDY_run(daemon); + + break; + } + } + while(run); + + SPDY_stop_daemon(daemon); + + SPDY_deinit(); + + return 0; +} + |