Esempio n. 1
0
void run()
{
	WSADATA wsa;
	if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
	{
		printf("Init failed");
		exit(-1);
	}

	SOCKET server_fd;

	server_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if (server_fd == INVALID_SOCKET)
	{
		printf("Invalid socket");
		exit(-1);
	}

	struct sockaddr_in server_addr;
	int port = 56789;
	memset(&server_addr, 0, sizeof(struct sockaddr_in));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = INADDR_ANY;
	server_addr.sin_port = htons(port);

	if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR)
	{
		printf("Socket bind error");
		exit(-1);
	}

	if (listen(server_fd, SOMAXCONN) == SOCKET_ERROR)
	{
		printf("Socket execute error");
		exit(-1);
	}

	char hostname[255];
	char *ip;
	char *local = "*";
	struct hostent *hostinfo;
	if (gethostname(hostname, sizeof(hostname)) == 0)
	{
		if ((hostinfo = gethostbyname(hostname)) != NULL)
		{
			ip = inet_ntoa(*(struct in_addr *)*hostinfo->h_addr_list);
		}
		else
		{			
			ip = local;
		}
	}
	else
	{
		ip = local;
	}

	printf("Server is listening on %s:%d\n", ip, port);
	char doccmd[BUF_SIZE];
	sprintf_s(doccmd, BUF_SIZE, "start http://%s:%d/", ip, port);
	//system(doccmd);

	while (true)
	{
		SOCKET client;
		struct sockaddr_in client_addr;
		memset(&client_addr, 0, sizeof(struct sockaddr_in));
		client = accept(server_fd, (struct sockaddr*)&client_addr, 0);
		if (client == INVALID_SOCKET)
		{
			printf("Invalid socket");
		}

		char request[BUF_SIZE];
		char htmlfile[255];

		int receive_rs = recv(client, request, sizeof(request), 0);
		struct req_head head = parse_request_head(request);
		printf("Request: %s\n", head.path);

		if (strcmp(head.path, "/next") == 0)
		{
			play_next();
			strcpy_s(htmlfile, "html/index.html");
		}
		else if (strcmp(head.path, "/prev") == 0)
		{
			play_prev();
			strcpy_s(htmlfile, "html/index.html");
		}
		else if (strcmp(head.path, "/play") == 0)
		{
			play();
			strcpy_s(htmlfile, "html/index.html");
		}
		else if (strcmp(head.path, "/up") == 0)
		{
			volume_up();
			strcpy_s(htmlfile, "html/index.html");
		}
		else if (strcmp(head.path, "/down") == 0)
		{
			volume_down();
			strcpy_s(htmlfile, "html/index.html");
		}
		else if (strcmp(head.path, "/mute") == 0)
		{
			mute();
			strcpy_s(htmlfile, "html/index.html");
		}
		else if (strcmp(head.path, "/shutdown") == 0)
		{
			poweroff();
			strcpy_s(htmlfile, "html/index.html");
		}
		else if (strcmp(head.path, "/") == 0)
		{
			strcpy_s(htmlfile, "html/index.html");
		}	
		else
		{
			strcpyn(htmlfile, head.path, 1, sizeof(head) - 1);
		}

		// 加载要显示的页面
		struct fbuf *html = load_file(htmlfile);
		//printf("Loading file: %s\n", htmlfile);

		char *content;
		if (html == NULL)
		{
			content = (char *)calloc(BUF_SIZE, sizeof(char));
			sprintf_s(content, BUF_SIZE, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s", 22, "<h1>404 NOT FOUND</h1>");
			send(client, content, strlen(content), 0);
		}
		else
		{
			size_t total_size = html->buf_size + 67;
			content = (char *)calloc(total_size, sizeof(char));
			sprintf_s(content, total_size, "HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %d\r\n\r\n", html->mime, html->buf_size * sizeof(char));
			// send head
			send(client, content, strlen(content), 0);

			// send body
			send(client, html->buf, html->buf_size, 0);
		}
		
		free(content);
		free(html);

		closesocket(client);
	}

	closesocket(server_fd);
}
Esempio n. 2
0
int Http_handler::push(const char *data, int len){
	const char *sub;
	int len_t;

	switch(state){
	case request_head:
		printf("Http_handler state is request_head\n" );
		request_header_buffer.append(data,len);
		request_header_parsed=parse_request_head();
		if(request_header_parsed){
			state=response_head;
		}
		break;
	case response_head:
		printf("Http_handler state is response_head\n" );
		sub=strstr((const char*)data,"\r\n\r\n");
		if(sub!=NULL){
			sub+=4;
			len_t=sub-data;
			response_header_len+=len_t; // response_header_len 必需先初始化为0 // 现在已经没有用了
			response_header_buffer.append(data,len_t);
			if((response_header_parsed=parse_response_head())==true){
				// state=response_body_have_length; //head结束,应该来body了 //让 parse 去改变状态
				data=sub;
				len-=len_t;
				if(len>0){
					push(data,len);
				}
			}
		}else{ //sub==NULL
			//两种情况,一是请求格式不标准,是以\n\n结尾;二是头部太长,分开几部分传输
			response_header_buffer.append(data,response_header_len); //只考虑第二种情况
			return 0;
		}
		if (len==0){
			return 0;
		}
		break;
	case response_body_have_length:
		printf("Http_handler state is response_body\n" );
		if(body_parsed){
			printf("[!]error state!");
			clear();
			push(data,len);
		}
		if(len>0 && !chunked){  //chunked 在parse_response_head()中分析
			printf("not chunked,data length is %d\n",len);
			body_buffer.append(data, len);
			if(body_buffer.length()==body_len){ //body_len 在parse_response_head()中分析
				decoded_body_buffer=dezip();
				dump_file(decoded_body_buffer,file_extention); //todo remove
				decoded_body_buffer=decode();
				body_parsed=true;
			}
		}
		break;
	case response_body_chuncked_header:
		printf("Http_handler state is response_body_chuncked_header\n" );
		if(len==0){
			printf("data length is 0, end\n"); //两难抉择,浏览器会先加载一部分内容,等之后的数据包到达
			//可是我们的分析程序会面临重复分析,状态不确定的问题
			//dump_file(decoded_body_buffer,file_extention); //
			// decoded_body_buffer=decode();
			// body_parsed=true; //为真,会调用clear
			return 0; //chunk end
		}
		sub=strstr(data,"\r\n");
		if(sub==NULL){
			printf("[!] can not file \\r\\n in chunk body. this is not chunked?\n");
			clear();
			return -1;
		}
		if(1==sscanf(data,"%x",&len_t)){
			printf("chunked data,data length is %d\n",len_t);
			if(len_t==0){
				printf("this chunk length is 0, end\n");
				dump_file(decoded_body_buffer, file_extention);
				if(html_type){
					decoded_body_buffer=decode();
					body_parsed=true;
				}else{
					state=request_head; //
				}
				return 0; //chunk end
			}
			else{
				sub+=2;
				len-=(sub-data);
				body_len=len_t;
				state=response_body_chuncked_body;
				return push(sub,len);
			}
		}
		else{
			printf("[!]chunk parse error!");
			clear();
			return -1;
		} // sscanf if end
		break;
	case response_body_chuncked_body:
		printf("Http_handler state is response_body_chuncked_body, chunk length is %d, data length is %d, buffer already have %d\n", body_len,len,body_buffer.length() );
		if(len+body_buffer.length()<=body_len){ //这个body_len在上面分析
			body_buffer.append(data,len);
			return 0;
		}
		else{
			printf("[*]this chunk full!\n");
			len_t=body_len-body_buffer.length();
			body_buffer.append(data, len_t);
			decoded_body_buffer+=dezip();

			// dump_file(decoded_body_buffer,file_extention); //todo remove
			// decoded_body_buffer=decode();
			// body_parsed=true;

			len_t+=2;
			data+=len_t;
			len-=len_t;
			state=response_body_chuncked_header;
			push(data,len);
		}
		break;
	case unusable:
		printf("Http_handler state is unusable\n" );
		break;

	} //switch end
	return 0;
}