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();
	}
}
예제 #2
0
/* 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;
}
예제 #3
0
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();
	}
}
예제 #4
0
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();
    }
}
예제 #5
0
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;
}