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 size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; struct Proxy *proxy = (struct Proxy *)userp; char *line = (char *)ptr; char *name; char *value; char *status; int i; int pos; int ret; int num_values; const char * const * values; bool abort_it; //printf("curl_header_cb %s\n", line); if(!*(proxy->session_alive)) { PRINT_VERBOSE("headers received, but session is dead"); return 0; } //trailer if(NULL != proxy->response) return 0; if('\r' == line[0]) { //all headers were already handled; prepare spdy frames if(NULL == (proxy->response = SPDY_build_response_with_callback(proxy->status, proxy->status_msg, proxy->version, proxy->headers, &response_callback, proxy, 0))) DIE("no response"); SPDY_name_value_destroy(proxy->headers); free(proxy->status_msg); free(proxy->version); if(SPDY_YES != SPDY_queue_response(proxy->request, proxy->response, true, false, &response_done_callback, proxy)) DIE("no queue"); call_spdy_run = true; return realsize; } pos = 0; if(NULL == proxy->version) { //first line from headers //version for(i=pos; i<realsize && ' '!=line[i]; ++i); if(i == realsize) DIE("error on parsing headers"); if(NULL == (proxy->version = strndup(line, i - pos))) DIE("No memory"); pos = i+1; //status (number) for(i=pos; i<realsize && ' '!=line[i] && '\r'!=line[i]; ++i); if(NULL == (status = strndup(&(line[pos]), i - pos))) DIE("No memory"); proxy->status = atoi(status); free(status); if(i<realsize && '\r'!=line[i]) { //status (message) pos = i+1; for(i=pos; i<realsize && '\r'!=line[i]; ++i); if(NULL == (proxy->status_msg = strndup(&(line[pos]), i - pos))) DIE("No memory"); } PRINT_VERBOSE2("Header line received '%s' '%i' '%s' ", proxy->version, proxy->status, proxy->status_msg); return realsize; } //other lines //header name for(i=pos; i<realsize && ':'!=line[i] && '\r'!=line[i]; ++i) line[i] = tolower(line[i]); //spdy requires lower case if(NULL == (name = strndup(line, i - pos))) DIE("No memory"); if(0 == strcmp(SPDY_HTTP_HEADER_CONNECTION, name) || 0 == strcmp(SPDY_HTTP_HEADER_KEEP_ALIVE, name) || 0 == strcmp(SPDY_HTTP_HEADER_TRANSFER_ENCODING, name) ) { //forbidden in spdy, ignore free(name); return realsize; } if(i == realsize || '\r'==line[i]) { //no value. is it possible? if(SPDY_YES != SPDY_name_value_add(proxy->headers, name, "")) DIE("SPDY_name_value_add failed"); return realsize; } //header value pos = i+1; while(pos<realsize && isspace(line[pos])) ++pos; //remove leading space for(i=pos; i<realsize && '\r'!=line[i]; ++i); if(NULL == (value = strndup(&(line[pos]), i - pos))) DIE("No memory"); PRINT_VERBOSE2("Adding header: '%s': '%s'", name, value); if(SPDY_YES != (ret = SPDY_name_value_add(proxy->headers, name, value))) { abort_it=true; if(NULL != (values = SPDY_name_value_lookup(proxy->headers, name, &num_values))) for(i=0; i<num_values; ++i) if(0 == strcasecmp(value, values[i])) { abort_it=false; PRINT_INFO2("header appears more than once with same value '%s: %s'", name, value); break; } if(abort_it) { PRINT_INFO2("SPDY_name_value_add failed (%i) for '%s'", ret, name); abort(); } } free(name); free(value); return realsize; }