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)method; (void)version; (void)more; struct SPDY_Response *response=NULL; struct SPDY_NameValue *resp_headers; printf("received request for '%s %s %s'\n", method, path, version); 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"); killchild(); } if(SPDY_YES != SPDY_name_value_add(resp_headers,SPDY_HTTP_HEADER_CONTENT_TYPE,"text/plain")) { fprintf(stdout,"SPDY_name_value_add failed\n"); killchild(); } 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); if(NULL==response){ fprintf(stdout,"no response obj\n"); killchild(); } void *clspath = strdup(path); if(SPDY_queue_response(request,response,true,false,&response_done_callback,clspath)!=SPDY_YES) { fprintf(stdout,"queue\n"); killchild(); } }
/* Needed by testcase to be extern -- should this be in the header? */ _MHD_EXTERN int SPDYF_name_value_from_stream(void *stream, size_t size, struct SPDY_NameValue ** container) { int32_t num_pairs; int32_t value_size; int32_t name_size; int i; unsigned int offset = 0; unsigned int value_end_offset; char *name; char *value; if(NULL == (*container = SPDY_name_value_create ())) { return SPDY_NO; } //get number of pairs memcpy(&num_pairs, stream, 4); offset = 4; num_pairs = ntohl(num_pairs); if(num_pairs > 0) { for(i = 0; i < num_pairs; ++i) { //get name size memcpy(&name_size, stream + offset, 4); offset += 4; name_size = ntohl(name_size); //get name if(NULL == (name = strndup(stream + offset, name_size))) { SPDY_name_value_destroy(*container); return SPDY_NO; } offset+=name_size; //get value size memcpy(&value_size, stream + offset, 4); offset += 4; value_size = ntohl(value_size); value_end_offset = offset + value_size; //get value do { if(NULL == (value = strndup(stream + offset, value_size))) { free(name); SPDY_name_value_destroy(*container); return SPDY_NO; } offset += strlen(value); if(offset < value_end_offset) ++offset; //NULL separator //add name/value to the struct if(SPDY_YES != SPDY_name_value_add(*container, name, value)) { free(name); free(value); SPDY_name_value_destroy(*container); return SPDY_NO; } free(value); } while(offset < value_end_offset); free(name); if(offset != value_end_offset) { SPDY_name_value_destroy(*container); return SPDY_INPUT_ERROR; } } } if(offset == size) return SPDY_YES; SPDY_name_value_destroy(*container); return SPDY_INPUT_ERROR; }
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)method; (void)version; (void)more; struct SPDY_Response *response=NULL; struct SPDY_NameValue *resp_headers; char *fname; char *fsize; char *mime=NULL; char *date=NULL; ssize_t filesize = -666; FILE *fd = NULL; int ret = -666; //printf("received request for '%s %s %s'\n", method, path, version); if(strlen(path) > 1 && NULL == strstr(path, "..") && '/' == path[0]) { asprintf(&fname,"%s%s",basedir,path); if(0 == access(fname, R_OK)) { if(NULL == (fd = fopen(fname,"r")) || 0 != (ret = fseek(fd, 0L, SEEK_END)) || -1 == (filesize = ftell(fd)) || 0 != (ret = fseek(fd, 0L, SEEK_SET))) { printf("Error on opening %s\n%p %i %zd\n",fname, fd, ret, filesize); response = SPDY_build_response(SPDY_HTTP_INTERNAL_SERVER_ERROR,NULL,SPDY_HTTP_VERSION_1_1,NULL,NULL,0); } else { if(NULL == (resp_headers = SPDY_name_value_create())) { printf("SPDY_name_value_create failed\n"); abort(); } date = Rfc1123_DateTimeNow(); if(NULL == date || SPDY_YES != SPDY_name_value_add(resp_headers,SPDY_HTTP_HEADER_DATE,date)) { printf("SPDY_name_value_add or Rfc1123_DateTimeNow failed\n"); abort(); } free(date); if(-1 == asprintf(&fsize, "%zd", filesize) || SPDY_YES != SPDY_name_value_add(resp_headers,SPDY_HTTP_HEADER_CONTENT_LENGTH,fsize)) { printf("SPDY_name_value_add or asprintf failed\n"); abort(); } free(fsize); GET_MIME_TYPE(path,mime); if(SPDY_YES != SPDY_name_value_add(resp_headers,SPDY_HTTP_HEADER_CONTENT_TYPE,mime)) { printf("SPDY_name_value_add failed\n"); abort(); } free(mime); if(SPDY_YES != SPDY_name_value_add(resp_headers,SPDY_HTTP_HEADER_SERVER,"libmicrospdy/fileserver")) { printf("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); } if(NULL==response){ printf("no response obj\n"); abort(); } if(SPDY_queue_response(request,response,true,false,&response_done_callback,fd)!=SPDY_YES) { printf("queue\n"); abort(); } free(fname); return; } free(fname); } if(strcmp(path,"/close")==0) { run = 0; } response = SPDY_build_response(SPDY_HTTP_NOT_FOUND,NULL,SPDY_HTTP_VERSION_1_1,NULL,NULL,0); printf("Not found %s\n",path); if(NULL==response){ printf("no response obj\n"); abort(); } if(SPDY_queue_response(request,response,true,false,&response_done_callback,NULL)!=SPDY_YES) { printf("queue\n"); abort(); } }
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(); } }
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) { (void)cls; (void)priority; (void)host; (void)scheme; struct Proxy *proxy; int ret; struct URI *uri; struct SPDY_Session *session; PRINT_VERBOSE2("received request for '%s %s %s'\n", method, path, version); if(NULL == (proxy = malloc(sizeof(struct Proxy)))) DIE("No memory"); memset(proxy, 0, sizeof(struct Proxy)); session = SPDY_get_session_for_request(request); assert(NULL != session); proxy->session_alive = SPDY_get_cls_from_session(session); assert(NULL != proxy->session_alive); proxy->request = request; if(NULL == (proxy->headers = SPDY_name_value_create())) DIE("No memory"); if(glob_opt.transparent) { if(NULL != glob_opt.http_backend) //use always same host ret = asprintf(&(proxy->url),"%s://%s%s", scheme, glob_opt.http_backend, path); else //use host header ret = asprintf(&(proxy->url),"%s://%s%s", scheme, host, path); if(-1 == ret) DIE("No memory"); ret = parse_uri(&uri_preg, proxy->url, &uri); if(ret != 0) DIE("parsing built uri failed"); } else { ret = parse_uri(&uri_preg, path, &uri); PRINT_INFO2("path %s '%s' '%s'", path, uri->scheme, uri->host); if(ret != 0 || !strlen(uri->scheme) || !strlen(uri->host)) DIE("parsing received uri failed"); if(NULL != glob_opt.http_backend) //use backend host { ret = asprintf(&(proxy->url),"%s://%s%s", uri->scheme, glob_opt.http_backend, uri->path_and_more); if(-1 == ret) DIE("No memory"); } else //use request path if(NULL == (proxy->url = strdup(path))) DIE("No memory"); } free_uri(uri); PRINT_VERBOSE2("curl will request '%s'", proxy->url); SPDY_name_value_iterate(headers, &iterate_cb, proxy); if(NULL == (proxy->curl_handle = curl_easy_init())) { PRINT_INFO("curl_easy_init failed"); abort(); } if(glob_opt.curl_verbose) CURL_SETOPT(proxy->curl_handle, CURLOPT_VERBOSE, 1); CURL_SETOPT(proxy->curl_handle, CURLOPT_URL, proxy->url); if(glob_opt.http10) CURL_SETOPT(proxy->curl_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); CURL_SETOPT(proxy->curl_handle, CURLOPT_WRITEFUNCTION, curl_write_cb); CURL_SETOPT(proxy->curl_handle, CURLOPT_WRITEDATA, proxy); CURL_SETOPT(proxy->curl_handle, CURLOPT_HEADERFUNCTION, curl_header_cb); CURL_SETOPT(proxy->curl_handle, CURLOPT_HEADERDATA, proxy); CURL_SETOPT(proxy->curl_handle, CURLOPT_PRIVATE, proxy); CURL_SETOPT(proxy->curl_handle, CURLOPT_HTTPHEADER, proxy->curl_headers); CURL_SETOPT(proxy->curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); CURL_SETOPT(proxy->curl_handle, CURLOPT_SSL_VERIFYHOST, 0L); if(glob_opt.ipv4 && !glob_opt.ipv6) CURL_SETOPT(proxy->curl_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); else if(glob_opt.ipv6 && !glob_opt.ipv4) CURL_SETOPT(proxy->curl_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); if(CURLM_OK != (ret = curl_multi_add_handle(multi_handle, proxy->curl_handle))) { PRINT_INFO2("curl_multi_add_handle failed (%i)", ret); abort(); } //~5ms additional latency for calling this if(CURLM_OK != (ret = curl_multi_perform(multi_handle, &still_running)) && CURLM_CALL_MULTI_PERFORM != ret) { PRINT_INFO2("curl_multi_perform failed (%i)", ret); abort(); } call_curl_run = true; }