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 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;
}