[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/lynq/lib/liblynq-protcl/ftp/lynq_ftpclient.c b/src/lynq/lib/liblynq-protcl/ftp/lynq_ftpclient.c
new file mode 100644
index 0000000..87220ee
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/ftp/lynq_ftpclient.c
@@ -0,0 +1,939 @@
+#include "ftp/lynq_ftp.h"
+
+int lynq_ftp_login(lynq_ftp_socker_info *FTP)
+{
+	struct sockaddr_in serv_addr;
+	char recvdate;
+	char sendline[MAXSIZE] = "", recvline[MAXSIZE] = "";
+	struct hostent *host = NULL;
+
+	char name[MAXSIZE] = "", password[MAXSIZE] = "";
+	LYDBGLOG("[%s-%d] ftp,enter the hostname = %s\n", __FUNCTION__, __LINE__, FTP->sevname);
+	
+	host = gethostbyname(FTP->sevname);
+	
+	if(host == NULL)
+	{
+		error = 35;
+		LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+		login_yes = 0;
+	}
+	else
+	{
+		FTP->control_sockfd = socket(AF_INET, SOCK_STREAM, 0);
+		if(FTP->control_sockfd < 0)
+		{
+			error = 50;
+			LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+			LYDBGLOG("[%s-%d]\n", __FUNCTION__, __LINE__);
+			login_yes = 0;
+		}
+
+		bzero(&serv_addr, sizeof(serv_addr));
+
+		memset(&serv_addr, 0, sizeof(struct sockaddr_in));
+		memcpy(&serv_addr.sin_addr.s_addr, host->h_addr, host->h_length);
+		serv_addr.sin_family = AF_INET;
+		serv_addr.sin_port = htons(FTP->portnum);
+
+		if((connect(FTP->control_sockfd, (struct sockaddr*)&serv_addr, sizeof(struct sockaddr))) < 0)
+		{
+			error = 33;
+			LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+			login_yes = 0;
+		}
+
+
+		recvdate = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+		if(recvdate == -1)
+		{
+			error = 33;
+			LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+			login_yes = 0;
+		}
+		else if(strncmp(recvline, "220", 3) == 0)
+		{
+			LYDBGLOG("ftp,connect success\n");
+			login_yes = 1;
+		}
+		else 
+		{
+			error = 33;
+			LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+			login_yes = 0;    
+		}
+		if(login_yes == 1)
+		{
+			int sendbytes, recvbytes;
+
+			zeromery(name, 1024);
+			zeromery(password, 1024);
+			zeromery(recvline, 1024);
+			zeromery(sendline, 1024);
+			strcat(sendline, "USER ");
+			strcat(sendline, FTP->username);
+			strcat(sendline, "\r\n");
+			//printf("[%s %d] --->%s\n",__FUNCTION__ , __LINE__,sendline);
+			sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline), 0);
+			if(sendbytes == -1)
+			{
+				error = 38;
+				LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+				login_yes = 0;
+				//return FTP_USER_ERROR;
+			}
+			recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+			if(strncmp(recvline, "331", 3) == 0)
+			{
+				LYDBGLOG("[%s %d] ftp,331 please specify the password.\n", __FUNCTION__ , __LINE__);
+			}
+			else
+			{
+				error = 38;
+				LYDBGLOG("[%s-%d] ftp,recv date is error.%d\n", __FUNCTION__ , __LINE__, error);
+				LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+				login_yes = 0;
+			}
+			zeromery(sendline, 1024);
+			zeromery(recvline, 1024);
+			//printf("ftp-> ");
+			strcat(sendline, "PASS ");
+			strcat(sendline, FTP->pw);
+			strcat(sendline, "\r\n");
+			//printf("[%s %d]--->%s\n",__FUNCTION__, __LINE__, sendline);
+			sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline), 0);
+			if(sendbytes == -1)
+			{
+				error = 39;
+				LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+				login_yes = 0;
+			}
+			recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+			if(strncmp(recvline, "230", 3) == 0)
+			{
+				LYVERBLOG("+[ftp][login][session%d]: ok!!\n", FTP->session);
+				login_yes = 1;
+			}
+			else 
+			{
+				error = 39;
+				LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+				login_yes = 0;
+			}
+
+#if 1
+			//support rest
+			char str[255];
+			sprintf(str, "%d", FTP->rest);
+			zeromery(sendline, 1024);
+			zeromery(recvline, 1024);
+			strcat(sendline, "REST ");
+			strcat(sendline, str);
+			strcat(sendline, "\r\n");
+			//printf("[%s-%d]--->%s\n", __FUNCTION__,  __LINE__,  sendline);
+			sendbytes = send(FTP->control_sockfd,sendline,strlen(sendline),0);
+			if(sendbytes == -1)
+			{
+				error = 41;
+				LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+				login_yes = 0;
+			}
+			recvbytes = recv(FTP->control_sockfd, recvline,sizeof(recvline),0);
+			if(recvbytes == -1)
+			{
+				error = 41;
+				LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);    
+				login_yes = 0;    
+			}
+			if(strncmp(recvline, "350",3) == 0)
+			{
+				LYDBGLOG("[%s-%d] support rest\n", __FUNCTION__, __LINE__);
+				login_yes = 1;
+			}
+			else
+			{
+				error = 41;
+				LYDBGLOG("[%s-%d] ftp,not support rest%d\n", __FUNCTION__, __LINE__, error);
+				LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+				login_yes = 0;    
+			}   
+#endif  
+		}
+
+	}
+	return login_yes;
+}
+
+void zeromery(char *a,int len)
+{
+	int i;
+	len = sizeof(a);
+	for(i = 0; i < len; i++)
+	{
+		a[i] = 0;
+	}
+}
+
+void lynq_ftp_pwd(int control_sockfd)
+{
+	int recvbytes,sendbytes;
+	char sendline[1024], recvline[1024];
+	zeromery(sendline, 1024);
+	zeromery(recvline, 1024);
+	strcat(sendline, "PWD");
+	strcat(sendline, "\r\n");
+	sendbytes = send(FTP->control_sockfd,sendline,strlen(sendline),0);
+	if(sendbytes < 0)
+	{
+		LYDBGLOG("[%s-%d] ftp,pwd,send is error\n", __FUNCTION__, __LINE__);
+		error = 52;
+		LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+	}
+	recvbytes = recv(FTP->control_sockfd, recvline,sizeof(recvline),0);
+	if(strncmp(recvline, "257",3) == 0)
+	{
+		LYDBGLOG("[%s-%d] ftp,current directory is:%s\n", __FUNCTION__, __LINE__, recvline);
+	}
+	else
+	{
+		error = 51;
+		LYDBGLOG("[%s-%d] ftp,pwd,recv is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][login][session%d]: error num = %d\n", FTP->session, error);
+	}
+}
+
+//rest
+void lynq_ftp_rest(int control_sockfd)
+{
+
+	int recvbytes,sendbytes;
+	char sendline[1024], recvline[1024];
+	zeromery(sendline, 1024);
+	zeromery(recvline, 1024);
+	strcat(sendline, "REST ");
+	strcat(sendline, "500");
+	strcat(sendline, "\r\n");
+	sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline), 0);
+	if(sendbytes < 0)
+	{
+		error = 52;
+		LYDBGLOG("[%s-%d] ftp,stru send is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][reset][session%d]: error num = %d\n", FTP->session, error);
+	}
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+	if(recvbytes < 0)
+	{
+		error = 51;
+		LYVERBLOG("+[ftp][reset][session%d]: error num = %d\n", FTP->session, error);
+	}
+	if(strncmp(recvline, "350",3) == 0)
+	{
+		LYDBGLOG("[%s-%d] ftp,%s\n", __FUNCTION__, __LINE__, recvline);
+	}
+}
+
+int strtosrv(char *str)
+{
+
+	int addr[6];
+	//printf("%s\n",str);
+	sscanf(str, "%*[^(](%d,%d,%d,%d,%d,%d)", &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]);
+
+	LYDBGLOG("[%s-%d] ftp,%d,%d,%d,%d\n", __FUNCTION__, __LINE__, addr[0],addr[1],addr[2],addr[3]);
+	bzero(hoster, strlen(hoster));
+	sprintf(hoster, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
+
+	LYDBGLOG("[%s-%d] ftp,hoster = %s", __FUNCTION__, __LINE__, hoster);
+	int port = addr[4]*256 + addr[5];
+	LYDBGLOG("[%s-%d] ftp,port = %d\n", __FUNCTION__, __LINE__, port);
+	return port;
+}
+
+
+int lynq_ftp_download(lynq_ftp_socker_info* FTP)
+{
+	char catbuf[1024];
+	int data_sock;
+	int recvbytes, sendbytes;
+	char sendline[1024] = "", recvline[1024] = "";
+	char getfilepath[FTP_MAX_ASCII_LEN+5] = "/tmp/";
+
+#if 1
+	//type
+
+	zeromery(recvline, 1024);
+	zeromery(sendline, 1024);
+	strcat(sendline, "TYPE ");
+	strcat(sendline, FTP->file_type);
+	strcat(sendline, "\r\n");
+	sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline),0);
+	if(sendbytes < 0)
+	{
+		error = 52;//FTP_SEND_ERROR
+		LYVERBLOG("+[ftp][get][session%d]: error num = %d\n", FTP->session, error);
+		return FTP_SEND_ERROR;
+	}
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+	LYDBGLOG("[%s-%d] ftp,recvline = %s\n",__FUNCTION__, __LINE__, recvline);
+	if(strncmp(recvline, "200", 3) == 0)
+	{
+		LYDBGLOG("[%s-%d] ftp,binary transmisson\n",__FUNCTION__, __LINE__);
+	}
+	else
+	{
+		error = 46; //FTP_DOWNLOAD_ERROR
+		LYDBGLOG("[%s-%d] ftp,download error\n",__FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][get][session%d]: error num = %d\n", FTP->session, error);
+		return FTP_DOWNLOAD_ERROR;
+	}
+#endif
+
+	zeromery(recvline, 1024);
+	zeromery(sendline, 1024);
+	strcat(sendline, FTP->is_pasv_mode);
+	strcat(sendline, " \r\n");
+	
+	sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline), 0);
+	if(sendbytes < 0)
+	{
+		error  = 52; //FTP_SEND_ERROR
+		LYDBGLOG("[%s-%d] type send is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][get][session%d]: error num = %d\n", FTP->session, error);
+		return FTP_SEND_ERROR;
+	}
+	
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+	if(strncmp(recvline, "227", 3) == 0)
+	{
+		LYDBGLOG("[%s-%d] ftp,binary transmisson\n", __FUNCTION__, __LINE__);
+	}
+	else
+	{
+		error = 43;//FTP_ACTIVE_ERROR
+		LYVERBLOG("+[ftp][get][session%d]: error num = %d\n", FTP->session, error);
+		LYDBGLOG("[%s-%d] type recv is error!\n", __FUNCTION__, __LINE__);
+		return FTP_ACTIVE_ERROR;
+	}
+
+	LYDBGLOG("-------- [%s-%d] recvline = %s\n", __FUNCTION__, __LINE__, recvline);
+	int port1 = strtosrv(recvline);
+	data_sock = cliopen(hoster, port1);
+
+	LYDBGLOG("[%s-%d] ftp,data_sock = %d\n", __FUNCTION__, __LINE__, data_sock);
+	LYDBGLOG("[%s-%d] FTP->getfilename = %s\n", __FUNCTION__, __LINE__, FTP->getfilename);
+	LYDBGLOG("[%s-%d] FTP->getfilename_path = %s\n", __FUNCTION__, __LINE__, FTP->getfilename_path);
+
+	//send the command retr;
+	zeromery(sendline, 1024);
+	zeromery(recvline, 1024);
+	strcat(sendline, "RETR ");
+	strcat(sendline, FTP->getfilename_path);
+	strcat(sendline, "/");
+	strcat(sendline, FTP->getfilename);
+	strcat(sendline, "\r\n");
+	//printf("%s\n", sendline);
+
+	LYDBGLOG("[%s-%d] ftp,%ld\n", __FUNCTION__, __LINE__, write(FTP->control_sockfd,sendline,strlen(sendline)));
+	LYDBGLOG("[%s-%d] getfilename= %s FTP->control_sockfd = %d\n", __FUNCTION__, __LINE__, FTP->getfilename, FTP->control_sockfd);
+#if 1
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+
+	if(recvbytes < 0)
+	{
+		error  = 52;//FTP_SEND_ERROR
+		LYDBGLOG("[%s-%d] retr recv is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][get][session%d]: error num = %d\n", FTP->session, error);
+
+		return FTP_SEND_ERROR;
+	}
+	LYDBGLOG("[%s-%d] recvline = %s\n", __FUNCTION__, __LINE__, recvline);
+	if(strncmp(recvline, "400", 3) > 0)
+	{
+		error = 51;//FTP_RCV_ERROR
+		
+		LYDBGLOG("[%s-%d] return is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][get][session%d]: error num = %d\n", FTP->session, error);
+		return FTP_RCV_ERROR;
+	}
+
+	strcat(getfilepath, FTP->getfilename);
+	lynq_ftp_get(data_sock, getfilepath, FTP->session);
+
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+
+	strcpy(FTP->respond, recvline);
+
+	LYDBGLOG("[%s-%d] FTP->respond = %s\n", __FUNCTION__, __LINE__, FTP->respond);
+
+	if(strncmp(FTP->respond, "550", 3) == 0)
+	{
+		error = 46; //FTP_DOWNLOAD_ERROR
+		LYDBGLOG("[%s-%d] download is error %d \n", __FUNCTION__, __LINE__, error);
+		LYVERBLOG("+[ftp][get][session%d]: error num = %d\n", FTP->session, error);
+
+		return FTP_DOWNLOAD_ERROR;
+	}
+
+	if(strncmp(FTP->respond, "421",3) == 0)
+	{
+		error = 34;//FTP_TIMEROUT
+		LYDBGLOG("[%s-%d] download is error %d \n", __FUNCTION__, __LINE__, error);
+		LYVERBLOG("+[ftp][get][session%d]: error num = %d\n", FTP->session, error);
+
+		return FTP_TIMEROUT;
+	}
+
+	if((strncmp(FTP->respond, "226", 3) == 0) || (strncmp(FTP->respond, "125",3) == 0))
+	{
+		LYVERBLOG("+[ftp][get][session%d]: ok!!\n", FTP->session);
+	}
+#endif
+	return 0;
+
+}
+
+int lynq_ftp_put(int sck, char *pUploadFileName_s)
+{
+	int handle = open(pUploadFileName_s, O_RDWR);
+	int nread;
+	if(handle == -1)
+		return -1;
+	
+	while(1)
+	{
+		if((nread = read(handle, rbuf1, 1024)) < 0)
+		{
+			error = 54;//FTP_READ_ERROR
+			LYDBGLOG("[%s-%d] read error!", __FUNCTION__, __LINE__);
+			LYVERBLOG("+[ftp][up][session%d]: error num = %d\n", FTP->session, error);
+		}
+		else if(nread == 0)
+			break;
+		LYDBGLOG("[%s-%d] rbuf1 = %s \n", __FUNCTION__, __LINE__, rbuf1);
+
+		if(write(sck, rbuf1, nread) != nread){
+			error = 54;
+			LYDBGLOG("[%s-%d] send error!", __FUNCTION__, __LINE__);
+			LYVERBLOG("+[ftp][up][session%d]: error num = %d\n", FTP->session, error);
+		}
+		memset(rbuf1,0,1024);
+	}
+	if(close(sck) < 0)
+		LYVERBLOG("+[ftp][up][session%d]: error num = %d\n", FTP->session, FTP_CLOSE_ERROR);
+
+	return 0;
+}
+
+
+int lynq_ftp_up(lynq_ftp_socker_info* FTP)
+{
+	char catbuf[1024];
+	int data_sock;
+	int recvbytes,sendbytes;
+	char sendline[1024], recvline[1024];
+	int put_ret = -1;
+
+	if((access(FTP->putfilename, F_OK)) == -1)   
+	{	
+		//FTP_SOCK_ERROR
+		LYVERBLOG("+[ftp][up][session%d]: error num = %d\n", FTP->session, FTP_SOCK_ERROR);
+		LYDBGLOG("[%s-%d] %s file does not exist\n", __FUNCTION__, __LINE__, FTP->putfilename);
+		return FTP_SOCK_ERROR;
+	}	
+	
+#if 1
+	zeromery(recvline, 1024);
+	zeromery(sendline, 1024);
+	strcat(sendline, "TYPE ");
+	strcat(sendline, FTP->file_type);
+	strcat(sendline, "\r\n");
+	sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline), 0);
+	if(sendbytes < 0)
+	{
+		LYDBGLOG("[%s-%d] ftp type send is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][up][session%d]: error num = %d\n", FTP->session, FTP_SEND_ERROR);
+		return FTP_SEND_ERROR;
+	}
+	recvbytes = recv(FTP->control_sockfd, recvline,sizeof(recvline),0);
+	if(strncmp(recvline, "200",3) == 0)
+	{
+		LYDBGLOG("[%s-%d] initalize\n", __FUNCTION__, __LINE__);
+	}
+	else
+	{
+		LYDBGLOG("[%s-%d] type recv is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][up][session%d]: error num = %d\n", FTP->session, FTP_RCV_ERROR);
+		return FTP_RCV_ERROR;
+	}
+#endif
+
+	//PASV   
+	zeromery(recvline, 1024);
+	zeromery(sendline, 1024);
+	strcat(sendline, FTP->is_pasv_mode);
+	strcat(sendline, " \r\n");
+	sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline), 0);
+	if(sendbytes < 0)
+	{
+		LYDBGLOG("[%s-%d] type send is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][up][session%d]: error num = %d\n", FTP->session, FTP_SEND_ERROR);
+	}
+	recvbytes = recv(FTP->control_sockfd, recvline,sizeof(recvline), 0);
+	if(strncmp(recvline, "227", 3) == 0)
+	{
+		LYDBGLOG("[%s-%d] binary transmisson\n", __FUNCTION__, __LINE__);
+	}
+	else
+	{
+		error = 43;//FTP_ACTIVE_ERROR
+		LYDBGLOG("[%s-%d] type recv is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][up][session%d]: error num = %d\n", FTP->session, error);
+		return FTP_ACTIVE_ERROR;
+	}
+
+	//init datelink  server port information
+	int port1 = strtosrv(recvline);
+	LYDBGLOG("[%s-%d] ftp,hoster =%s,port1 = %d\n", __FUNCTION__, __LINE__, hoster,port1);
+	data_sock = cliopen(hoster, port1);
+
+	LYDBGLOG("[%s-%d] ftp,data_sock = %d\n", __FUNCTION__, __LINE__, data_sock);
+	zeromery(sendline, 1024);
+	zeromery(recvline, 1024);
+	strcat(sendline, FTP->put_opt);
+	strcat(sendline, " ");
+	strcat(sendline, FTP->putfilename_path);
+	strcat(sendline, "/");
+	strcat(sendline, FTP->putfilename);
+	strcat(sendline, "\r\n");
+
+	LYDBGLOG("[%s-%d] ftp,%s\n", __FUNCTION__, __LINE__, sendline);
+	LYDBGLOG("%ld\n", write(FTP->control_sockfd, sendline, strlen(sendline)));
+	LYDBGLOG("[%s-%d] ftp,filename = %s\n", __FUNCTION__, __LINE__, FTP->putfilename);
+	
+
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+
+	LYDBGLOG("RETR RECVLINE = %s\n", recvline);
+	if(recvbytes < 0)
+	{
+		LYVERBLOG("+[ftp][up][session%d]: error num = %d\n", FTP->session, FTP_RCV_ERROR);
+		LYDBGLOG("[%s-%d] retr recv is error!\n", __FUNCTION__, __LINE__);
+		return FTP_RCV_ERROR;
+	}
+	if(strncmp(recvline, "400", 3) > 0)
+	{
+		error = 400;
+		LYVERBLOG("+[ftp][up][session%d]: error num = %d\n", FTP->session, error);
+	}
+
+	lynq_ftp_put(data_sock, FTP->putfilename);
+	
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+
+	strcpy(FTP->respond, recvline);
+
+	if(strncmp(FTP->respond, "226",3) == 0)
+	{
+		LYDBGLOG("[%s-%d] FTP->respond = %s\n", __FUNCTION__, __LINE__, FTP->respond);
+		LYVERBLOG("+[ftp][up][session%d]: ok!!\n", FTP->session);
+	}
+	else
+	{
+		error = 45;//FTP_UPLOAD_ERROR
+		LYVERBLOG("+[ftp][up][session%d]: error num = %d\n", FTP->session, error);
+		return FTP_UPLOAD_ERROR;
+	}
+	return 0;
+
+}
+
+
+int lynq_ftp_ls(lynq_ftp_socker_info* FTP)
+{
+	char catbuf[1024];
+	int data_sock;
+	int recvbytes, sendbytes;
+	char sendline[1024], recvline[1024];  
+
+	
+	//PASV   
+	zeromery(recvline, 1024);
+	zeromery(sendline, 1024);
+	strcat(sendline, FTP->is_pasv_mode);
+	strcat(sendline, " \r\n");
+	sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline), 0);
+	if(sendbytes < 0)
+	{
+		LYDBGLOG("[%s-%d] type send is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][ls][session%d]: error num = %d\n", FTP->session, FTP_SEND_ERROR);
+		return FTP_SEND_ERROR;
+	}
+	recvbytes = recv(FTP->control_sockfd, recvline,sizeof(recvline), 0);
+	if(strncmp(recvline, "227",3) == 0)
+	{
+		LYDBGLOG("[%s-%d] binary transmit\n", __FUNCTION__, __LINE__);
+	}
+	else
+	{
+		error = 43;
+		LYDBGLOG("[%s-%d] type recv is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][ls][session%d]: error num = %d\n", FTP->session, error);
+		return error;
+	}
+
+	//init datelink  server port information
+	int port1 = strtosrv(recvline);
+	LYDBGLOG("[%s-%d] ftp,hoster =%s,port1 = %d\n", __FUNCTION__, __LINE__, hoster,port1);
+	data_sock = cliopen(hoster, port1);
+
+	//printf("data_sock = %d\n",data_sock);
+
+	zeromery(sendline, 1024);
+	zeromery(recvline, 1024);
+	strcat(sendline, "LIST -al ");
+	strcat(sendline, FTP->dir);
+	strcat(sendline, "\r\n");
+
+	LYDBGLOG("%ld\n", write(FTP->control_sockfd, sendline, strlen(sendline)));
+
+	LYDBGLOG("[%s-%d] ftp,%s\n", __FUNCTION__, __LINE__,sendline);
+
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+
+	//printf("RETR RECVLINE = %s\n",recvline);
+	LYDBGLOG("[%s-%d] recvline = %s\n", __FUNCTION__, __LINE__, recvline);
+
+	if(recvbytes < 0)
+	{
+		LYVERBLOG("+[ftp][ls][session%d]: error num = %d\n", FTP->session, FTP_SEND_ERROR);
+	}
+	if(strncmp(recvline, "400", 3)>0)
+	{
+		error = 400;
+		LYDBGLOG("[%s-%d] type recv is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][ls][session%d]: error num = %d\n", FTP->session, error);
+		return error;
+	}
+
+	ftp_list(data_sock, FTP->session); 
+
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+
+	LYDBGLOG("[%s-%d] recvline = %s\n", __FUNCTION__, __LINE__, recvline);
+
+	strcpy(FTP->respond, recvline);
+
+	if((strncmp(FTP->respond, "226", 3) == 0) || (strncmp(FTP->respond, "150",3) == 0) || strncmp(FTP->respond, "125", 3) == 0)
+	{	
+		if(strstr(FTP->respond, ". 0 bytes")){//rita add @2021.07.19 for ls
+			LYDBGLOG("[%s-%d] FTP->respond = %s\n", __FUNCTION__, __LINE__, FTP->respond);
+			LYVERBLOG("+[ftp][ls][session%d]: error num = %d\n", FTP->session, FTP_LS_ERROR);
+			return FTP_LS_ERROR;
+		}
+		else
+			LYVERBLOG("+[ftp][ls][session%d]: ok!!\n", FTP->session);
+	}
+	else{
+		error = 44;
+		LYDBGLOG("[%s-%d] ls error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][ls][session%d]: error num = %d\n", FTP->session, error);
+		return error;
+	}
+
+	return 0;
+}
+
+
+void lynq_ftp_get(int sck, char *pDownloadFileName, int session)
+{
+	int handle = open(pDownloadFileName, O_WRONLY | O_CREAT | O_TRUNC, S_IREAD| S_IWRITE);
+	int nread;
+	
+	while(1)
+	{
+		//printf("%d\n",sck);
+		//printf("%d\n",handle);
+		if((nread = recv(sck, rbuf1, 1024, 0)) < 0)
+		{
+			error = 51;
+			//LYDBGLOG("[%s-%d] ftp,rbuf1 = %s\n", __FUNCTION__, __LINE__, rbuf1);
+			LYDBGLOG("[%s-%d] receive error\n", __FUNCTION__, __LINE__);
+			LYVERBLOG("+[ftp][get][session%d]: error num = %d\n", session, error);
+			return;
+		}
+		else if(nread == 0)
+		{
+			LYDBGLOG("[%s-%d] over\n", __FUNCTION__, __LINE__);
+			break;
+		}
+		if(write(handle, rbuf1, nread) != nread)
+		{
+			LYDBGLOG("[%s-%d] receive error from server!\n", __FUNCTION__, __LINE__);
+			LYVERBLOG("+[ftp][get][session%d]: error num = %d\n", session, FTP_WRITE_ERROR);
+		}
+		
+		//LYDBGLOG("[%s-%d] rbuf1 = %s \n", __FUNCTION__, __LINE__, rbuf1);
+		
+		memset(rbuf1,0,1024);
+	}
+	if(close(sck) < 0){
+		LYDBGLOG("[%s-%d] close error\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][get][session%d]: error num = %d\n", session, FTP_CLOSE_ERROR);
+	}
+}
+
+
+
+int cliopen(char *hoster, int port)
+{
+
+	int control_sockfd;
+
+	struct sockaddr_in serv_addr;
+	struct hostent *host = NULL;
+
+	//get hostent argument
+	char name[MAXSIZE];
+	//printf("please enter the hostname\n");
+	//printf("ftp-> ");
+
+	strcpy(name, hoster);
+	host = gethostbyname(name);
+	if(host == NULL)
+	{
+		LYDBGLOG("[%s-%d] ftp,get host by name is error!\n", __FUNCTION__, __LINE__);
+		login_yes = 0;
+	}
+	else
+	{
+		//creact socket
+		control_sockfd = socket(AF_INET, SOCK_STREAM, 0);
+		if(control_sockfd < 0)
+		{
+			//printf("socket is error\n");
+			LYDBGLOG("[%s-%d] ftp,socket is error\n", __FUNCTION__, __LINE__);
+			login_yes = 0;
+		}
+
+		//set sockaddr_in
+		bzero(&serv_addr, sizeof(serv_addr));
+
+		memset(&serv_addr, 0, sizeof(struct sockaddr_in));
+		memcpy(&serv_addr.sin_addr.s_addr, host->h_addr, host->h_length);
+		serv_addr.sin_family = AF_INET;
+		serv_addr.sin_port = htons(port);
+
+		//printf("line port = %d\n",port);
+		if((connect(control_sockfd, (struct sockaddr*)&serv_addr, sizeof(struct sockaddr))) < 0)
+		{
+			//printf("connect is error\n");
+			LYDBGLOG("[%s-%d] ftp,connect is error\n", __FUNCTION__, __LINE__);
+			login_yes = 0;
+		} 
+	}
+	return control_sockfd;
+}
+
+void ftp_list(int sockfd, int session)
+{
+	int nread;
+
+	for(;;)
+	{
+		if((nread = recv(sockfd, rbuf1, 1024, 0)) < 0)
+		{
+			LYDBGLOG("[%s-%d] recv error\n", __FUNCTION__, __LINE__);
+		}
+		else if(nread == 0)
+		{
+			LYDBGLOG("[%s-%d] disconnect \n", __FUNCTION__, __LINE__);
+			break;
+		}
+		LYVERBLOG("+[ftp][ls][session%d]: data = %s\n", session, rbuf1);
+		LYVERBLOG("+[ftp][ls][session%d]: ok!! \n", session);
+		memset(rbuf1, 0, 1024);
+	}
+	if(close(sockfd) < 0){
+		LYDBGLOG("[%s-%d] close error\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][ls][session%d]: error num = %d\n", session, FTP_CLOSE_ERROR);
+	}
+}
+
+void lynq_ftp_cd(lynq_ftp_socker_info* FTP)
+{
+	char catbuf[1024];
+	char sendline[1024];
+	char recvline[1024];
+	
+	zeromery(sendline, 1024);
+	zeromery(recvline, 1024);
+	int recvbytes, sendbytes;
+	int issuccess;
+
+	if(strcmp(FTP->del_mkr_filename, "..") == 0)
+	{
+		sprintf(sendline, "CDUP %s\n", FTP->del_mkr_filename);
+	}
+	else
+	{
+		sprintf(sendline, "CWD %s\n", FTP->del_mkr_filename);
+	}
+	strcat(sendline, "\r\n");
+
+	LYDBGLOG("[%s-%d] %s\n", __FUNCTION__, __LINE__, sendline);
+	sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline), 0);
+	if(sendbytes < 0)
+	{
+		LYDBGLOG("cd send is error!");
+		exit(1);
+	}
+
+
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+	if(strncmp(recvline, "257", 3) == 0)
+	{
+		issuccess = 1;
+	}
+	else
+	{
+		error = 44;
+		issuccess = 0;
+	}
+}
+
+void lynq_ftp_creat_mkd(lynq_ftp_socker_info* FTP)
+{
+	char catbuf[1024];
+	char sendline[1024];
+	char recvline[1024];
+	
+	zeromery(sendline, 1024);
+	zeromery(recvline, 1024);
+	int recvbytes, sendbytes;
+	int issuccess;
+	strcat(sendline, "MKD ");
+	strcat(sendline, FTP->del_mkr_filename);
+	strcat(sendline, "\r\n");
+	LYDBGLOG("[%s-%d] %s\n", __FUNCTION__, __LINE__, sendline);
+	sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline), 0);
+	if(sendbytes < 0)
+	{
+		LYDBGLOG("[%s-%d] mkd send is error!", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][mkdir][session%d]: error num = %s\n", FTP->session, FTP_SEND_ERROR);
+		exit(1);
+	}
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+	if(strncmp(recvline, "257", 3) == 0)
+	{
+		issuccess = 1;
+		LYVERBLOG("+[ftp][mkdir][session%d]: ok!!\n", FTP->session);
+	}
+	else
+	{
+		error = 44;
+		LYVERBLOG("+[ftp][mkdir][session%d]: error num = %d\n", FTP->session, error);
+		issuccess = 0;
+	}
+}
+
+
+void lynq_ftp_delete_mkd(lynq_ftp_socker_info* FTP)
+{
+	char sendline[1024];
+	char recvline[1024];
+	zeromery(sendline, 1024);
+	zeromery(recvline, 1024);
+	int recvbytes, sendbytes;
+	int issuccess;
+	char catbuf[1024];
+	
+	strcat(sendline, "RMD ");
+	strcat(sendline, FTP->del_mkr_filename);
+	strcat(sendline, "\r\n");
+	LYDBGLOG("[%s-%d] %s\n", __FUNCTION__, __LINE__,sendline);
+	sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline), 0);
+	if(sendbytes < 0)
+	{
+		LYDBGLOG("[%s-%d] rmd send is error!", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][rmd][session%d]: error num = %s\n", FTP->session, FTP_SEND_ERROR);
+		exit(1);
+	}
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+	if(strncmp(recvline, "250", 3) == 0)
+	{
+		issuccess = 1;
+		LYVERBLOG("+[ftp][rmd][session%d]: ok!!\n", FTP->session);
+	}
+	else
+	{
+		error = 44;
+		issuccess = 0;
+		LYVERBLOG("+[ftp][rmd][session%d]: error num = %s\n", FTP->session, error);
+	}
+}
+
+void lynq_ftp_quit(lynq_ftp_socker_info* FTP)
+{
+
+	int recvbytes, sendbytes;
+	char sendline[1024], recvline[1024];
+	zeromery(sendline, 1024);
+	zeromery(recvline, 1024);
+
+	
+	strcat(sendline, "bye ");
+	strcat(sendline, "\n");
+	sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline), 0);
+	if(sendbytes < 0)
+	{
+		LYDBGLOG("[%s-%d] stru send is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][quit][session%d]: error num = %s\n", FTP->session, FTP_SEND_ERROR);
+	}
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+
+	LYDBGLOG("[%s-%d] quit = %s\n", __FUNCTION__, __LINE__, recvline);
+	if(recvbytes < 0)
+	{
+		LYDBGLOG("[%s-%d] stru recv is error!\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[ftp][quit][session%d]: error num = %s\n", FTP->session, FTP_RCV_ERROR);
+	}
+	if(strncmp(recvline, "221", 3) == 0)
+	{
+		LYVERBLOG("+[ftp][quit][session%d]: ok!!\n", FTP->session);
+	}
+}
+
+void lynq_ftp_deletefile_mkd(lynq_ftp_socker_info* FTP)
+{
+	char sendline[1024];
+	char recvline[1024];
+	
+	zeromery(sendline, 1024);
+	zeromery(recvline, 1024);
+	int recvbytes, sendbytes;
+	int issuccess;
+	char catbuf[1024];
+	strcat(sendline, "DELE ");
+	strcat(sendline, FTP->del_mkr_filename);
+	strcat(sendline, "\r\n");
+	LYDBGLOG("[%s-%d] %s\n", __FUNCTION__, __LINE__,sendline);
+	sendbytes = send(FTP->control_sockfd, sendline, strlen(sendline), 0);
+	if(sendbytes < 0)
+	{
+		LYVERBLOG("+[ftp][delfile][session%d]: error num = %d\n", FTP->session, FTP_SEND_ERROR);
+		exit(1);
+	}
+	recvbytes = recv(FTP->control_sockfd, recvline, sizeof(recvline), 0);
+	if(strncmp(recvline, "250", 3) == 0)
+	{
+		issuccess = 1;
+		LYVERBLOG("+[ftp][delfile][session%d]: ok!!\n", FTP->session);
+	}
+	else
+	{
+		error = 44;
+		issuccess = 0;
+		LYVERBLOG("+[ftp][delfile][session%d]: error num = %d\n", FTP->session, error);
+	}
+}
+
diff --git a/src/lynq/lib/liblynq-protcl/ftp/lynq_ftpshm.c b/src/lynq/lib/liblynq-protcl/ftp/lynq_ftpshm.c
new file mode 100644
index 0000000..e4d4bed
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/ftp/lynq_ftpshm.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include "ftp/lynq_ftp.h"
+
+int lynq_ftpshm_create( void )
+{
+  key_t key;
+  int shm_id;
+  
+  key = ftok(FTPSHMPATH,FTPSHMID);
+  shm_id = shmget(key,sizeof(struct ftp_socket_info),0664 | IPC_CREAT | IPC_EXCL); 
+  
+ 	if(shm_id < 0)
+	{
+		if(errno == EEXIST)
+		shm_id = shmget(key,sizeof(struct ftp_socket_info),0664 | IPC_CREAT );
+	
+		else 
+		{
+			LYDBGLOG("[%s-%d] ftp,shm_create_fail", __FUNCTION__, __LINE__);
+			return -1;
+		}
+	}
+	return shm_id;
+}
+
+lynq_ftp_socker_info *ftpshm_act(int shmid)
+{
+	lynq_ftp_socker_info *p = NULL;
+
+	p = shmat(shmid,NULL,0);
+
+	if(p == NULL)
+	{
+		LYDBGLOG("[%s-%d] ftp,shm_act_fail", __FUNCTION__, __LINE__);
+		return NULL;
+	}
+
+	return p;
+}
+
+void lynq_ftpshm_deact(lynq_ftp_socker_info *shm)
+{
+	int ret;
+	
+	ret = shmdt(shm);
+
+	if(ret < 0)
+	{
+		LYDBGLOG("[%s-%d] ftp,shm_deact_fail", __FUNCTION__, __LINE__);
+		return ;
+	}
+
+	return;
+}
+
+void lynq_ftpshm_del(int shmid)
+{
+	int ret;
+
+	ret = shmctl(shmid, IPC_RMID, 0);
+
+	if(ret == -1)
+	{
+		LYDBGLOG("[%s-%d] ftp,shm_del_fail", __FUNCTION__, __LINE__);
+		return ;
+	}
+
+	return;
+}
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/ca.crt b/src/lynq/lib/liblynq-protcl/http/cert/ca.crt
new file mode 100644
index 0000000..a9007d2
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/ca.crt
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDfzCCAmegAwIBAgIJAODN6ztlacOjMA0GCSqGSIb3DQEBCwUAMFUxCzAJBgNV
+BAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQHDAdCZWlqaW5nMRAwDgYD
+VQQKDAdUZWFtc3VuMRAwDgYDVQQLDAdUZWFtc3VuMCAXDTIwMDkyODEwMTUwNVoY
+DzIxMjAwOTA0MTAxNTA1WjBVMQswCQYDVQQGEwJDTjEQMA4GA1UECAwHQmVpamlu
+ZzEQMA4GA1UEBwwHQmVpamluZzEQMA4GA1UECgwHVGVhbXN1bjEQMA4GA1UECwwH
+VGVhbXN1bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqVvba2fnHk
+gayq5P0kLQIV+xu1yND/LPOuuCTwnVHHqp0VHxtIP8TvYhxXT7oaqsMNQlPKm+SH
+1wDVpe+mrbrv3G9vVsfjPdHf772fP3gLb/+MbnADfD9cq9rIFWKfXNw5F9GYetA2
+gEo/oA0jD2t6Z69hJqsnmhw4LAJhVJxTefyAcOLm59PHB3FRLPOfWOZIX4m16yXn
+C+Pgi3t7fAZDt2ty3VGxg63rLGEoCh0J1AlQhU4QfF7wu1eqxWbMIukkpOzex88k
+C3chj4aWYOscUNCoiPtV2EtR1gqyoyqMIGUtMPtw703oY8A8fNcAjLtqUsObr1JD
+vay+VBVG7V0CAwEAAaNQME4wHQYDVR0OBBYEFOHWjOIKOO7OKH1/+0PjMs8eYK2t
+MB8GA1UdIwQYMBaAFOHWjOIKOO7OKH1/+0PjMs8eYK2tMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADggEBAFUK/09WXsFVHhOzfFYquHqNcDyYeld9XVQ7NrZp
+vzI/+rxeHswvQ8+iQF9pV0aOMo27ccE7AjuHwdFwQQHal9y892tzFXSUxfhATT/I
+ZAySC3Gvsf8AQYkcu+fWDLB0FZmRbxvO3+tSTnL+4jkI+IJbSsDvDB6VG9ugWTwd
+O14X+gOalwO1TcsZuMV1d4a1nB8X6pkG78KcQfMwkrb/KPWhZKaxcksBLxBkKHt8
+sZY+FERnWZf3sNaCpm0Uwvd3Ua+IU+f/FpiShBZnSk5mqXB/C6sx2PbXyXNh6fv/
+5rTIpv3nlxAVHNVJo0LFAE5wPpCMCNj082WuT25OkVxKIyY=
+-----END CERTIFICATE-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/ca.key b/src/lynq/lib/liblynq-protcl/http/cert/ca.key
new file mode 100644
index 0000000..4758736
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/ca.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAupW9trZ+ceSBrKrk/SQtAhX7G7XI0P8s8664JPCdUceqnRUf
+G0g/xO9iHFdPuhqqww1CU8qb5IfXANWl76atuu/cb29Wx+M90d/vvZ8/eAtv/4xu
+cAN8P1yr2sgVYp9c3DkX0Zh60DaASj+gDSMPa3pnr2EmqyeaHDgsAmFUnFN5/IBw
+4ubn08cHcVEs859Y5khfibXrJecL4+CLe3t8BkO3a3LdUbGDressYSgKHQnUCVCF
+ThB8XvC7V6rFZswi6SSk7N7HzyQLdyGPhpZg6xxQ0KiI+1XYS1HWCrKjKowgZS0w
++3DvTehjwDx81wCMu2pSw5uvUkO9rL5UFUbtXQIDAQABAoIBAH/D+/X6v1kkHTvs
+hgNl20AbZykRcOLUaaawFL6O2Vtfu0/3X6ah8bDcLzWzABAzJI2OLcYM7nUuI6cZ
+pZgWbc6dYzgXaLhVvkZR7uvM+XwtcNLwCcvARztoLPISoro24DKZEdtfa3HacDzn
+lqSIRo3VctygTQdUhe4e9NvoZDTqtOvjdu2NDYPTKawBe0KHWNFTsp8eUS+5rwcb
+IWWnfjcq9Z6HHobY5wf274izlloG1wNtxgqX4PTVRKlK6gAnZVaFFaRBLypBj4IC
+XmqmWrxtitGnIXTaSZjlkRo6SkFGiz+ovnjs0qbfBKu+0C83qZVS93aK9lVLvoum
+JKsLUe0CgYEA5T7s16uow0AG6UBmvjjlEtb6F0mXCqaGij9cO1ClZ4tBBzVxohRW
+ZCo4mGOSBToUnPTby3B/ZiN0+Pwz7nmOploIv9X65V6798MA6v5juWwThI7lQmu+
+S7rxpxkolDqTdyochqseqcIHv8ZuxRI0JtapjXNDQ1H+rd7iozm7btcCgYEA0FxB
+gxaIilQkQdw4byDv41tlGbbgeVCOKp86VxxkpDTz6MMs0yIRp+F9p58rostkPcIh
+ToWtoneeaT6P4WwuA2ETvI6g03H4nN1X1MTdx+M0FniYNMe20Ye0N1GhCILLXsTb
+XKNB0/u7nBIbjNkZ/0mCFGjGd71JjVQ5KaSpgusCgYEAiveKO3Mj6rh1eBBCOC3l
+L3aCRHunxB0Okd+22X4Zxprz4JrVN5t8g1vU0wwJCIIc3MjSNJENqaz0y7qXAIlP
+oCgUBbaBUWoMKDVd6RYs/co2SrUU5R7LTL0WoGTv5Gtd2W79u+UfwWiNqgNwQqa2
+VpTqU4T70WNzL5Ndb/UfWiECgYEAguNBYCi6kzLyJ9FAPkcRiuAx7WpdLrg05n9p
+9ajna+O7yN86fFMthil3duHdVoGwMb+OjrYY8jN0dqaPWctMSGEmNc/fJZS12UyO
+TSFyNIv8f5U4AAfpR0yZIBsOLruDJ8BAELyZsKG1JACX/+2tkBnMNifvbO6ikr5y
+vj8rIQsCgYEAhO/0Ky4A3jOvMK4f1NAVWBcuOt3UzmF06cRU6rCF6Roi1WNoDHsd
+XR2qZfVgozhqj0YzXQ4J83HuyeCLWynKLptJkgqEdZDoBJ6vGVg9GZmyYoQD0wRH
+l8q/xQvrdMhlJvZX7zKDv2h7QS/i2DODFAeYtnYN/aBzGfPSgpV1N+o=
+-----END RSA PRIVATE KEY-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/ca.p12 b/src/lynq/lib/liblynq-protcl/http/cert/ca.p12
new file mode 100644
index 0000000..85eafa4
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/ca.p12
Binary files differ
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/client.crt b/src/lynq/lib/liblynq-protcl/http/cert/client.crt
new file mode 100644
index 0000000..7eb321f
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/client.crt
@@ -0,0 +1,81 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 2 (0x2)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=CN, ST=Beijing, L=Beijing, O=Teamsun, OU=Teamsun
+        Validity
+            Not Before: Sep 28 10:16:35 2020 GMT
+            Not After : Sep 28 10:16:35 2021 GMT
+        Subject: C=CN, ST=Beijing, O=Teamsun, OU=guog, CN=guog
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:99:5f:72:71:bc:e4:08:76:43:77:32:9d:17:61:
+                    74:f7:44:49:33:ef:3c:7f:89:0e:97:0e:ce:d9:39:
+                    32:ca:10:34:af:6c:8c:39:19:58:38:16:9f:11:1e:
+                    55:9f:95:89:ac:fb:e2:cb:5f:ee:1a:bd:3d:25:79:
+                    cd:18:20:36:83:ef:df:93:2e:7a:9e:1f:2f:98:05:
+                    b0:65:c9:4f:93:c2:00:0b:70:84:2b:fb:44:01:d1:
+                    36:22:a6:5a:43:f7:c6:54:f4:81:cc:a6:26:47:e4:
+                    92:f5:e6:97:41:34:3e:c5:37:89:13:64:c6:cc:93:
+                    6c:a2:b0:0e:64:e0:3b:7d:a2:2e:b1:e4:42:79:cf:
+                    a7:06:5e:89:53:4b:56:46:f5:07:54:99:5e:0f:80:
+                    1b:28:2f:19:63:c2:cd:e9:97:8f:09:cd:38:f4:05:
+                    d4:83:00:4a:3b:14:00:51:d9:fe:b9:d4:82:52:c3:
+                    a3:2f:2a:2d:f4:98:b1:44:0f:8c:ca:ee:0c:94:7e:
+                    af:8b:b8:ab:8c:21:9d:16:1e:72:ee:9b:3d:04:70:
+                    1c:c6:46:06:d3:df:12:59:97:b6:af:3c:97:8d:b9:
+                    2e:88:d0:c9:c5:42:14:bb:c2:dd:ac:a3:3a:80:8a:
+                    af:34:d2:e4:85:26:92:da:0e:99:20:3b:e8:78:11:
+                    ba:e3
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                27:96:0E:38:74:AA:00:98:D8:8C:54:5F:09:98:D9:03:C8:3D:D7:9C
+            X509v3 Authority Key Identifier: 
+                keyid:E1:D6:8C:E2:0A:38:EE:CE:28:7D:7F:FB:43:E3:32:CF:1E:60:AD:AD
+
+    Signature Algorithm: sha256WithRSAEncryption
+         a8:89:a9:9c:48:86:04:10:bf:5a:83:60:78:44:eb:42:59:af:
+         9b:58:33:2c:68:33:f5:e1:c0:a9:d2:07:87:55:07:dc:95:68:
+         18:20:9d:d2:3a:ad:3c:fc:d7:03:ec:f1:d4:91:26:09:d5:dd:
+         cd:90:74:0a:2a:c6:5a:98:6a:f7:e8:4f:04:e7:35:23:70:5e:
+         ea:20:83:b6:b7:6f:8b:2c:80:3e:0e:c5:f0:a1:30:4a:5e:df:
+         6a:bc:60:43:2f:91:c8:e2:14:ca:47:af:9c:6b:ad:8d:c5:a6:
+         cd:1f:f8:1a:82:d8:02:b0:e7:d4:06:a2:47:bc:f7:b7:0e:dc:
+         89:8d:3e:c9:50:55:8a:a1:04:5e:e6:a6:23:d8:54:37:57:c5:
+         1e:57:0d:ed:1b:45:2a:1a:e3:10:ba:17:95:cf:c3:7d:a3:ec:
+         08:d2:57:db:24:32:a0:9f:8e:30:95:81:20:00:fb:97:eb:c9:
+         0c:e9:82:0f:62:a5:16:fa:ed:ae:7c:59:2c:f1:f2:b5:fd:8d:
+         c0:fe:20:ba:d2:f8:40:ef:2f:2e:ec:98:c3:55:b1:dd:83:4d:
+         2a:9a:a3:f2:fc:4a:29:71:70:5f:3f:44:47:07:af:8f:ad:57:
+         2c:1a:d9:68:19:c4:e8:c0:6b:2e:50:f9:d6:5c:97:ec:5a:8a:
+         cd:ac:8c:0f
+-----BEGIN CERTIFICATE-----
+MIIDmjCCAoKgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJDTjEQ
+MA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEQMA4GA1UECgwHVGVh
+bXN1bjEQMA4GA1UECwwHVGVhbXN1bjAeFw0yMDA5MjgxMDE2MzVaFw0yMTA5Mjgx
+MDE2MzVaME8xCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQK
+DAdUZWFtc3VuMQ0wCwYDVQQLDARndW9nMQ0wCwYDVQQDDARndW9nMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmV9ycbzkCHZDdzKdF2F090RJM+88f4kO
+lw7O2TkyyhA0r2yMORlYOBafER5Vn5WJrPviy1/uGr09JXnNGCA2g+/fky56nh8v
+mAWwZclPk8IAC3CEK/tEAdE2IqZaQ/fGVPSBzKYmR+SS9eaXQTQ+xTeJE2TGzJNs
+orAOZOA7faIuseRCec+nBl6JU0tWRvUHVJleD4AbKC8ZY8LN6ZePCc049AXUgwBK
+OxQAUdn+udSCUsOjLyot9JixRA+Myu4MlH6vi7irjCGdFh5y7ps9BHAcxkYG098S
+WZe2rzyXjbkuiNDJxUIUu8LdrKM6gIqvNNLkhSaS2g6ZIDvoeBG64wIDAQABo3sw
+eTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD
+ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUJ5YOOHSqAJjYjFRfCZjZA8g915wwHwYDVR0j
+BBgwFoAU4daM4go47s4ofX/7Q+Myzx5gra0wDQYJKoZIhvcNAQELBQADggEBAKiJ
+qZxIhgQQv1qDYHhE60JZr5tYMyxoM/XhwKnSB4dVB9yVaBggndI6rTz81wPs8dSR
+JgnV3c2QdAoqxlqYavfoTwTnNSNwXuogg7a3b4ssgD4OxfChMEpe32q8YEMvkcji
+FMpHr5xrrY3Fps0f+BqC2AKw59QGoke897cO3ImNPslQVYqhBF7mpiPYVDdXxR5X
+De0bRSoa4xC6F5XPw32j7AjSV9skMqCfjjCVgSAA+5fryQzpgg9ipRb67a58WSzx
+8rX9jcD+ILrS+EDvLy7smMNVsd2DTSqao/L8SilxcF8/REcHr4+tVywa2WgZxOjA
+ay5Q+dZcl+xais2sjA8=
+-----END CERTIFICATE-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/client.csr b/src/lynq/lib/liblynq-protcl/http/cert/client.csr
new file mode 100644
index 0000000..f6b6207
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/client.csr
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICpjCCAY4CAQAwYTELMAkGA1UEBhMCQ04xEDAOBgNVBAgMB0JlaWppbmcxEDAO
+BgNVBAcMB0JlaWppbmcxEDAOBgNVBAoMB1RlYW1zdW4xDTALBgNVBAsMBGd1b2cx
+DTALBgNVBAMMBGd1b2cwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCZ
+X3JxvOQIdkN3Mp0XYXT3REkz7zx/iQ6XDs7ZOTLKEDSvbIw5GVg4Fp8RHlWflYms
+++LLX+4avT0lec0YIDaD79+TLnqeHy+YBbBlyU+TwgALcIQr+0QB0TYiplpD98ZU
+9IHMpiZH5JL15pdBND7FN4kTZMbMk2yisA5k4Dt9oi6x5EJ5z6cGXolTS1ZG9QdU
+mV4PgBsoLxljws3pl48JzTj0BdSDAEo7FABR2f651IJSw6MvKi30mLFED4zK7gyU
+fq+LuKuMIZ0WHnLumz0EcBzGRgbT3xJZl7avPJeNuS6I0MnFQhS7wt2sozqAiq80
+0uSFJpLaDpkgO+h4EbrjAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAdntI2cu7
+H+N3BURFIfq+Zjzd2djO6SthHJ3h5KaUkxvGfuL3gVau+7w/RO6hgkPeQ0/E7dSy
+ZHxURkLNlbVgZz/zVH/rxPPlkwDP+HqOLMRrSkckvNjuuinxWizM1wKASOS4Yefp
+CS/1AtAKBePdmxqTmgFO3yciIs0I/IEf6Gw1XuW8iVfCcR2aTRLI/SQfPgXOp/FK
+YSpIs0WbVDp8SZd8994rVOyujqbfjcjc+zHEqyb24pUoEMstXK51QWZOjixoLHH3
+CdmxKwNk6GlAEXELhC1FjvwZLJR5emEoqsu4NdEPopfsZ0kLRDbJo0KdeErbh1e9
+6ixDUYO5TkWU5w==
+-----END CERTIFICATE REQUEST-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/client.key b/src/lynq/lib/liblynq-protcl/http/cert/client.key
new file mode 100644
index 0000000..3d63cca
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/client.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAmV9ycbzkCHZDdzKdF2F090RJM+88f4kOlw7O2TkyyhA0r2yM
+ORlYOBafER5Vn5WJrPviy1/uGr09JXnNGCA2g+/fky56nh8vmAWwZclPk8IAC3CE
+K/tEAdE2IqZaQ/fGVPSBzKYmR+SS9eaXQTQ+xTeJE2TGzJNsorAOZOA7faIuseRC
+ec+nBl6JU0tWRvUHVJleD4AbKC8ZY8LN6ZePCc049AXUgwBKOxQAUdn+udSCUsOj
+Lyot9JixRA+Myu4MlH6vi7irjCGdFh5y7ps9BHAcxkYG098SWZe2rzyXjbkuiNDJ
+xUIUu8LdrKM6gIqvNNLkhSaS2g6ZIDvoeBG64wIDAQABAoIBAGQ7moF2Xtig4Wpu
+63cyO8y1FdoZCUKYAa77AHe6B9VCTgwvNlzCkYLmVcJMPszyX21rmEYtRWC4N9Pc
+DAsuUjJbe5Omln/sBaCmZye+LoF0Ea9oMxjDNyiw3145tVgh/73ZpVJnazEk0l5d
++o+kYzlkF/NSsxFTb3XK9T07xeVOK3dpher/YKJIFTicGIp+PUenIuVBMVWjiUM3
+ku/xHedoCCjURMMaoBXolA7L5YNw6dapV4BYBTFZ5H/eTdtEmIRpBypStHSuxrKC
+qsEPLPD0/vFgRoD6fzGoYsa/is4kX56vB/LISslaazY1D57c6hC1o/OwBt7/MzAk
+0rMeoiECgYEAy/lr72yHpeG2+6LXxSRixKd20x1Z4mZbtAKy+9XHyjof8I45QqDp
+sIAdj1VbVacGibb71BjYxrkSDQXpK94padlfpGcyxnRtg+wZaIne5HVJShqUjcRH
+G/aKXxjnGkyRmP7eJgvEkKrgLXoC8n/86PFPehP6QgjAgNh+XYq/qBkCgYEAwH37
+5ZJlWrTUjVzDjszqIB4ELPu2UId1wMnoTIocQ89XsWwk7RLmrknV8y8DfnwF8fbp
+nVLVTBB11bX5cbwu8iw8J5XvBAu3zs0UTHE6c4DUsqq92KO2a7qSVJeHB8IZErei
+DWCSv8qcfVc3ZVOMg4N1VGoYqNq8jQd8fqBgClsCgYEAsF4jeOtTwxgPGzfr7/eN
+O1M9yD+Zx8wPwO+QiXaJARAPK/YeBsGSLt4oMRZyGfaJDazdxMATOIkv1Xjl69t1
+3aNqMoJVAgoL48TTF3QW+V18mImxJ3+uqLwdWyryMOhCAJNnzGfid+B4ZHoacEpA
+ib6VpQ3/FvfwU7heU020eIkCgYBKBCeH7vLqHf5dHP5VOpYMI36XjXJdJLkymHCq
+fbDAokml/19ziYEKI3oROFKvoCDpGXha9i7uQKYOtxpjkWi71iaLUivF8nuLGXBk
+tGU1ZKRkzyKQ2uKaKfN6c4mIgioB+HpnimrjNJVX3OGAJNAzAalr/B/fTbySvf4w
+8pn7YQKBgE4c1e2Xr67DqvGbpJx42fKlYYT0eW5ZxbzHkGj0Q5CZet61/S3lF9g8
+Bjm9TVhDBR2UJJbaaMuWed4Xp1UXZ9qWTeHtn3bX2BHr5HDY4ba+0sebVkdOmvre
+/p+sfKCBGkkIBgGjNld/UFErkbat/FfG0AWJZtX+5ulSEo7CodD4
+-----END RSA PRIVATE KEY-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/client.p12 b/src/lynq/lib/liblynq-protcl/http/cert/client.p12
new file mode 100644
index 0000000..4de6ab8
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/client.p12
Binary files differ
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/index.txt b/src/lynq/lib/liblynq-protcl/http/cert/index.txt
new file mode 100644
index 0000000..4c34e96
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/index.txt
@@ -0,0 +1,2 @@
+V	210928101551Z		01	unknown	/C=CN/ST=Beijing/O=Teamsun/OU=guoxu/CN=guoxu
+V	210928101635Z		02	unknown	/C=CN/ST=Beijing/O=Teamsun/OU=guog/CN=guog
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/index.txt.attr b/src/lynq/lib/liblynq-protcl/http/cert/index.txt.attr
new file mode 100644
index 0000000..8f7e63a
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/index.txt.attr
@@ -0,0 +1 @@
+unique_subject = yes
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/index.txt.attr.old b/src/lynq/lib/liblynq-protcl/http/cert/index.txt.attr.old
new file mode 100644
index 0000000..8f7e63a
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/index.txt.attr.old
@@ -0,0 +1 @@
+unique_subject = yes
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/index.txt.old b/src/lynq/lib/liblynq-protcl/http/cert/index.txt.old
new file mode 100644
index 0000000..2037566
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/index.txt.old
@@ -0,0 +1 @@
+V	210928101551Z		01	unknown	/C=CN/ST=Beijing/O=Teamsun/OU=guoxu/CN=guoxu
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/newcerts/01.pem b/src/lynq/lib/liblynq-protcl/http/cert/newcerts/01.pem
new file mode 100644
index 0000000..e92b642
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/newcerts/01.pem
@@ -0,0 +1,81 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=CN, ST=Beijing, L=Beijing, O=Teamsun, OU=Teamsun
+        Validity
+            Not Before: Sep 28 10:15:51 2020 GMT
+            Not After : Sep 28 10:15:51 2021 GMT
+        Subject: C=CN, ST=Beijing, O=Teamsun, OU=guoxu, CN=guoxu
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:a5:10:f2:43:40:a8:83:25:07:17:61:3e:8e:90:
+                    88:d1:b2:3d:5a:51:55:5e:fb:5f:c8:ee:3b:57:8a:
+                    13:64:4e:af:d9:74:0a:e5:db:42:1f:a8:3c:04:4f:
+                    2b:ed:08:fd:47:98:1c:4f:10:d3:2b:48:7a:3e:6a:
+                    ec:4d:bf:9d:6a:a6:5b:78:b6:22:28:12:1c:36:b6:
+                    84:de:b9:d4:60:dd:f3:b2:9d:c2:07:db:1c:f5:e8:
+                    02:6a:64:99:44:fe:4f:86:a4:d9:14:6a:cd:d2:9d:
+                    4f:e3:01:54:f8:06:d5:7a:0c:14:f0:61:93:a7:1f:
+                    f0:8b:44:f2:16:37:81:9d:3a:9b:f2:75:d0:fb:68:
+                    36:5d:59:23:38:bd:75:4e:e8:4d:6a:56:6c:a3:95:
+                    c4:71:1e:3b:2a:29:e4:d6:01:83:c9:a2:75:82:c6:
+                    42:d3:cd:3b:0f:2e:2f:09:57:9b:ed:b8:76:84:85:
+                    5d:49:95:d0:9e:de:cb:8a:2a:bc:d0:7d:29:b1:fe:
+                    92:02:65:a9:24:28:b8:24:8b:68:69:e0:2b:14:f3:
+                    62:e1:91:12:2d:89:5f:02:10:78:48:76:49:9e:82:
+                    8a:94:ff:f0:bb:6f:0d:82:10:e0:7f:78:58:f3:53:
+                    4a:dc:54:ee:f3:7d:fc:15:40:8d:48:c3:bc:a3:5d:
+                    df:6f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                5C:7C:6F:02:4F:B5:EB:F7:74:88:2F:2A:05:4C:D9:6A:4C:17:A2:ED
+            X509v3 Authority Key Identifier: 
+                keyid:E1:D6:8C:E2:0A:38:EE:CE:28:7D:7F:FB:43:E3:32:CF:1E:60:AD:AD
+
+    Signature Algorithm: sha256WithRSAEncryption
+         61:1d:fb:07:16:a2:33:7b:bd:d0:fe:3f:f8:73:06:ea:26:1b:
+         28:2e:de:f9:90:8d:ee:62:a4:97:f6:d4:04:05:a1:8e:11:93:
+         af:3b:3e:de:24:eb:68:ff:32:9a:d3:16:86:61:68:27:9e:2b:
+         d3:ff:50:e7:f7:f6:c4:81:e4:c3:87:41:f7:bb:3b:85:00:ee:
+         f7:5f:86:7c:b9:2a:d6:4f:1a:60:f6:55:77:cc:e7:84:2b:6c:
+         f4:d3:58:8f:ed:df:af:d3:f8:b6:f5:46:de:1b:19:91:a5:93:
+         31:db:5b:14:07:0f:8e:d9:db:ab:00:ea:6c:58:2c:67:24:bf:
+         b2:f7:a5:5c:d2:e1:cd:8b:42:0c:a5:b1:a3:03:aa:79:bc:10:
+         4f:79:4f:9b:7e:8b:28:09:3e:70:68:fa:a3:c5:ec:3b:33:80:
+         91:5b:1d:65:86:a3:9f:f4:25:48:d4:cf:9f:31:ce:54:a9:ce:
+         3e:7b:bb:00:21:27:b7:5c:44:bf:67:63:23:1b:c8:8d:b5:f4:
+         bd:5b:fa:ae:7d:fa:21:a0:0d:6e:8d:23:af:23:aa:e9:69:ef:
+         d7:64:37:5b:13:be:ea:c7:40:dd:8e:7d:e6:e2:1f:e2:7c:08:
+         57:27:0f:16:05:a1:e3:d0:ea:99:6b:d8:41:60:80:58:29:72:
+         80:d5:22:91
+-----BEGIN CERTIFICATE-----
+MIIDnDCCAoSgAwIBAgIBATANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJDTjEQ
+MA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEQMA4GA1UECgwHVGVh
+bXN1bjEQMA4GA1UECwwHVGVhbXN1bjAeFw0yMDA5MjgxMDE1NTFaFw0yMTA5Mjgx
+MDE1NTFaMFExCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQK
+DAdUZWFtc3VuMQ4wDAYDVQQLDAVndW94dTEOMAwGA1UEAwwFZ3VveHUwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQClEPJDQKiDJQcXYT6OkIjRsj1aUVVe
++1/I7jtXihNkTq/ZdArl20IfqDwETyvtCP1HmBxPENMrSHo+auxNv51qplt4tiIo
+Ehw2toTeudRg3fOyncIH2xz16AJqZJlE/k+GpNkUas3SnU/jAVT4BtV6DBTwYZOn
+H/CLRPIWN4GdOpvyddD7aDZdWSM4vXVO6E1qVmyjlcRxHjsqKeTWAYPJonWCxkLT
+zTsPLi8JV5vtuHaEhV1JldCe3suKKrzQfSmx/pICZakkKLgki2hp4CsU82LhkRIt
+iV8CEHhIdkmegoqU//C7bw2CEOB/eFjzU0rcVO7zffwVQI1Iw7yjXd9vAgMBAAGj
+ezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVk
+IENlcnRpZmljYXRlMB0GA1UdDgQWBBRcfG8CT7Xr93SILyoFTNlqTBei7TAfBgNV
+HSMEGDAWgBTh1oziCjjuzih9f/tD4zLPHmCtrTANBgkqhkiG9w0BAQsFAAOCAQEA
+YR37BxaiM3u90P4/+HMG6iYbKC7e+ZCN7mKkl/bUBAWhjhGTrzs+3iTraP8ymtMW
+hmFoJ54r0/9Q5/f2xIHkw4dB97s7hQDu91+GfLkq1k8aYPZVd8znhCts9NNYj+3f
+r9P4tvVG3hsZkaWTMdtbFAcPjtnbqwDqbFgsZyS/svelXNLhzYtCDKWxowOqebwQ
+T3lPm36LKAk+cGj6o8XsOzOAkVsdZYajn/QlSNTPnzHOVKnOPnu7ACEnt1xEv2dj
+IxvIjbX0vVv6rn36IaANbo0jryOq6Wnv12Q3WxO+6sdA3Y595uIf4nwIVycPFgWh
+49DqmWvYQWCAWClygNUikQ==
+-----END CERTIFICATE-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/newcerts/02.pem b/src/lynq/lib/liblynq-protcl/http/cert/newcerts/02.pem
new file mode 100644
index 0000000..7eb321f
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/newcerts/02.pem
@@ -0,0 +1,81 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 2 (0x2)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=CN, ST=Beijing, L=Beijing, O=Teamsun, OU=Teamsun
+        Validity
+            Not Before: Sep 28 10:16:35 2020 GMT
+            Not After : Sep 28 10:16:35 2021 GMT
+        Subject: C=CN, ST=Beijing, O=Teamsun, OU=guog, CN=guog
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:99:5f:72:71:bc:e4:08:76:43:77:32:9d:17:61:
+                    74:f7:44:49:33:ef:3c:7f:89:0e:97:0e:ce:d9:39:
+                    32:ca:10:34:af:6c:8c:39:19:58:38:16:9f:11:1e:
+                    55:9f:95:89:ac:fb:e2:cb:5f:ee:1a:bd:3d:25:79:
+                    cd:18:20:36:83:ef:df:93:2e:7a:9e:1f:2f:98:05:
+                    b0:65:c9:4f:93:c2:00:0b:70:84:2b:fb:44:01:d1:
+                    36:22:a6:5a:43:f7:c6:54:f4:81:cc:a6:26:47:e4:
+                    92:f5:e6:97:41:34:3e:c5:37:89:13:64:c6:cc:93:
+                    6c:a2:b0:0e:64:e0:3b:7d:a2:2e:b1:e4:42:79:cf:
+                    a7:06:5e:89:53:4b:56:46:f5:07:54:99:5e:0f:80:
+                    1b:28:2f:19:63:c2:cd:e9:97:8f:09:cd:38:f4:05:
+                    d4:83:00:4a:3b:14:00:51:d9:fe:b9:d4:82:52:c3:
+                    a3:2f:2a:2d:f4:98:b1:44:0f:8c:ca:ee:0c:94:7e:
+                    af:8b:b8:ab:8c:21:9d:16:1e:72:ee:9b:3d:04:70:
+                    1c:c6:46:06:d3:df:12:59:97:b6:af:3c:97:8d:b9:
+                    2e:88:d0:c9:c5:42:14:bb:c2:dd:ac:a3:3a:80:8a:
+                    af:34:d2:e4:85:26:92:da:0e:99:20:3b:e8:78:11:
+                    ba:e3
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                27:96:0E:38:74:AA:00:98:D8:8C:54:5F:09:98:D9:03:C8:3D:D7:9C
+            X509v3 Authority Key Identifier: 
+                keyid:E1:D6:8C:E2:0A:38:EE:CE:28:7D:7F:FB:43:E3:32:CF:1E:60:AD:AD
+
+    Signature Algorithm: sha256WithRSAEncryption
+         a8:89:a9:9c:48:86:04:10:bf:5a:83:60:78:44:eb:42:59:af:
+         9b:58:33:2c:68:33:f5:e1:c0:a9:d2:07:87:55:07:dc:95:68:
+         18:20:9d:d2:3a:ad:3c:fc:d7:03:ec:f1:d4:91:26:09:d5:dd:
+         cd:90:74:0a:2a:c6:5a:98:6a:f7:e8:4f:04:e7:35:23:70:5e:
+         ea:20:83:b6:b7:6f:8b:2c:80:3e:0e:c5:f0:a1:30:4a:5e:df:
+         6a:bc:60:43:2f:91:c8:e2:14:ca:47:af:9c:6b:ad:8d:c5:a6:
+         cd:1f:f8:1a:82:d8:02:b0:e7:d4:06:a2:47:bc:f7:b7:0e:dc:
+         89:8d:3e:c9:50:55:8a:a1:04:5e:e6:a6:23:d8:54:37:57:c5:
+         1e:57:0d:ed:1b:45:2a:1a:e3:10:ba:17:95:cf:c3:7d:a3:ec:
+         08:d2:57:db:24:32:a0:9f:8e:30:95:81:20:00:fb:97:eb:c9:
+         0c:e9:82:0f:62:a5:16:fa:ed:ae:7c:59:2c:f1:f2:b5:fd:8d:
+         c0:fe:20:ba:d2:f8:40:ef:2f:2e:ec:98:c3:55:b1:dd:83:4d:
+         2a:9a:a3:f2:fc:4a:29:71:70:5f:3f:44:47:07:af:8f:ad:57:
+         2c:1a:d9:68:19:c4:e8:c0:6b:2e:50:f9:d6:5c:97:ec:5a:8a:
+         cd:ac:8c:0f
+-----BEGIN CERTIFICATE-----
+MIIDmjCCAoKgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJDTjEQ
+MA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEQMA4GA1UECgwHVGVh
+bXN1bjEQMA4GA1UECwwHVGVhbXN1bjAeFw0yMDA5MjgxMDE2MzVaFw0yMTA5Mjgx
+MDE2MzVaME8xCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQK
+DAdUZWFtc3VuMQ0wCwYDVQQLDARndW9nMQ0wCwYDVQQDDARndW9nMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmV9ycbzkCHZDdzKdF2F090RJM+88f4kO
+lw7O2TkyyhA0r2yMORlYOBafER5Vn5WJrPviy1/uGr09JXnNGCA2g+/fky56nh8v
+mAWwZclPk8IAC3CEK/tEAdE2IqZaQ/fGVPSBzKYmR+SS9eaXQTQ+xTeJE2TGzJNs
+orAOZOA7faIuseRCec+nBl6JU0tWRvUHVJleD4AbKC8ZY8LN6ZePCc049AXUgwBK
+OxQAUdn+udSCUsOjLyot9JixRA+Myu4MlH6vi7irjCGdFh5y7ps9BHAcxkYG098S
+WZe2rzyXjbkuiNDJxUIUu8LdrKM6gIqvNNLkhSaS2g6ZIDvoeBG64wIDAQABo3sw
+eTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD
+ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUJ5YOOHSqAJjYjFRfCZjZA8g915wwHwYDVR0j
+BBgwFoAU4daM4go47s4ofX/7Q+Myzx5gra0wDQYJKoZIhvcNAQELBQADggEBAKiJ
+qZxIhgQQv1qDYHhE60JZr5tYMyxoM/XhwKnSB4dVB9yVaBggndI6rTz81wPs8dSR
+JgnV3c2QdAoqxlqYavfoTwTnNSNwXuogg7a3b4ssgD4OxfChMEpe32q8YEMvkcji
+FMpHr5xrrY3Fps0f+BqC2AKw59QGoke897cO3ImNPslQVYqhBF7mpiPYVDdXxR5X
+De0bRSoa4xC6F5XPw32j7AjSV9skMqCfjjCVgSAA+5fryQzpgg9ipRb67a58WSzx
+8rX9jcD+ILrS+EDvLy7smMNVsd2DTSqao/L8SilxcF8/REcHr4+tVywa2WgZxOjA
+ay5Q+dZcl+xais2sjA8=
+-----END CERTIFICATE-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/serial b/src/lynq/lib/liblynq-protcl/http/cert/serial
new file mode 100644
index 0000000..75016ea
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/serial
@@ -0,0 +1 @@
+03
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/serial.old b/src/lynq/lib/liblynq-protcl/http/cert/serial.old
new file mode 100644
index 0000000..9e22bcb
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/serial.old
@@ -0,0 +1 @@
+02
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/server.crt b/src/lynq/lib/liblynq-protcl/http/cert/server.crt
new file mode 100644
index 0000000..e92b642
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/server.crt
@@ -0,0 +1,81 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=CN, ST=Beijing, L=Beijing, O=Teamsun, OU=Teamsun
+        Validity
+            Not Before: Sep 28 10:15:51 2020 GMT
+            Not After : Sep 28 10:15:51 2021 GMT
+        Subject: C=CN, ST=Beijing, O=Teamsun, OU=guoxu, CN=guoxu
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:a5:10:f2:43:40:a8:83:25:07:17:61:3e:8e:90:
+                    88:d1:b2:3d:5a:51:55:5e:fb:5f:c8:ee:3b:57:8a:
+                    13:64:4e:af:d9:74:0a:e5:db:42:1f:a8:3c:04:4f:
+                    2b:ed:08:fd:47:98:1c:4f:10:d3:2b:48:7a:3e:6a:
+                    ec:4d:bf:9d:6a:a6:5b:78:b6:22:28:12:1c:36:b6:
+                    84:de:b9:d4:60:dd:f3:b2:9d:c2:07:db:1c:f5:e8:
+                    02:6a:64:99:44:fe:4f:86:a4:d9:14:6a:cd:d2:9d:
+                    4f:e3:01:54:f8:06:d5:7a:0c:14:f0:61:93:a7:1f:
+                    f0:8b:44:f2:16:37:81:9d:3a:9b:f2:75:d0:fb:68:
+                    36:5d:59:23:38:bd:75:4e:e8:4d:6a:56:6c:a3:95:
+                    c4:71:1e:3b:2a:29:e4:d6:01:83:c9:a2:75:82:c6:
+                    42:d3:cd:3b:0f:2e:2f:09:57:9b:ed:b8:76:84:85:
+                    5d:49:95:d0:9e:de:cb:8a:2a:bc:d0:7d:29:b1:fe:
+                    92:02:65:a9:24:28:b8:24:8b:68:69:e0:2b:14:f3:
+                    62:e1:91:12:2d:89:5f:02:10:78:48:76:49:9e:82:
+                    8a:94:ff:f0:bb:6f:0d:82:10:e0:7f:78:58:f3:53:
+                    4a:dc:54:ee:f3:7d:fc:15:40:8d:48:c3:bc:a3:5d:
+                    df:6f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                5C:7C:6F:02:4F:B5:EB:F7:74:88:2F:2A:05:4C:D9:6A:4C:17:A2:ED
+            X509v3 Authority Key Identifier: 
+                keyid:E1:D6:8C:E2:0A:38:EE:CE:28:7D:7F:FB:43:E3:32:CF:1E:60:AD:AD
+
+    Signature Algorithm: sha256WithRSAEncryption
+         61:1d:fb:07:16:a2:33:7b:bd:d0:fe:3f:f8:73:06:ea:26:1b:
+         28:2e:de:f9:90:8d:ee:62:a4:97:f6:d4:04:05:a1:8e:11:93:
+         af:3b:3e:de:24:eb:68:ff:32:9a:d3:16:86:61:68:27:9e:2b:
+         d3:ff:50:e7:f7:f6:c4:81:e4:c3:87:41:f7:bb:3b:85:00:ee:
+         f7:5f:86:7c:b9:2a:d6:4f:1a:60:f6:55:77:cc:e7:84:2b:6c:
+         f4:d3:58:8f:ed:df:af:d3:f8:b6:f5:46:de:1b:19:91:a5:93:
+         31:db:5b:14:07:0f:8e:d9:db:ab:00:ea:6c:58:2c:67:24:bf:
+         b2:f7:a5:5c:d2:e1:cd:8b:42:0c:a5:b1:a3:03:aa:79:bc:10:
+         4f:79:4f:9b:7e:8b:28:09:3e:70:68:fa:a3:c5:ec:3b:33:80:
+         91:5b:1d:65:86:a3:9f:f4:25:48:d4:cf:9f:31:ce:54:a9:ce:
+         3e:7b:bb:00:21:27:b7:5c:44:bf:67:63:23:1b:c8:8d:b5:f4:
+         bd:5b:fa:ae:7d:fa:21:a0:0d:6e:8d:23:af:23:aa:e9:69:ef:
+         d7:64:37:5b:13:be:ea:c7:40:dd:8e:7d:e6:e2:1f:e2:7c:08:
+         57:27:0f:16:05:a1:e3:d0:ea:99:6b:d8:41:60:80:58:29:72:
+         80:d5:22:91
+-----BEGIN CERTIFICATE-----
+MIIDnDCCAoSgAwIBAgIBATANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJDTjEQ
+MA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEQMA4GA1UECgwHVGVh
+bXN1bjEQMA4GA1UECwwHVGVhbXN1bjAeFw0yMDA5MjgxMDE1NTFaFw0yMTA5Mjgx
+MDE1NTFaMFExCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQK
+DAdUZWFtc3VuMQ4wDAYDVQQLDAVndW94dTEOMAwGA1UEAwwFZ3VveHUwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQClEPJDQKiDJQcXYT6OkIjRsj1aUVVe
++1/I7jtXihNkTq/ZdArl20IfqDwETyvtCP1HmBxPENMrSHo+auxNv51qplt4tiIo
+Ehw2toTeudRg3fOyncIH2xz16AJqZJlE/k+GpNkUas3SnU/jAVT4BtV6DBTwYZOn
+H/CLRPIWN4GdOpvyddD7aDZdWSM4vXVO6E1qVmyjlcRxHjsqKeTWAYPJonWCxkLT
+zTsPLi8JV5vtuHaEhV1JldCe3suKKrzQfSmx/pICZakkKLgki2hp4CsU82LhkRIt
+iV8CEHhIdkmegoqU//C7bw2CEOB/eFjzU0rcVO7zffwVQI1Iw7yjXd9vAgMBAAGj
+ezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVk
+IENlcnRpZmljYXRlMB0GA1UdDgQWBBRcfG8CT7Xr93SILyoFTNlqTBei7TAfBgNV
+HSMEGDAWgBTh1oziCjjuzih9f/tD4zLPHmCtrTANBgkqhkiG9w0BAQsFAAOCAQEA
+YR37BxaiM3u90P4/+HMG6iYbKC7e+ZCN7mKkl/bUBAWhjhGTrzs+3iTraP8ymtMW
+hmFoJ54r0/9Q5/f2xIHkw4dB97s7hQDu91+GfLkq1k8aYPZVd8znhCts9NNYj+3f
+r9P4tvVG3hsZkaWTMdtbFAcPjtnbqwDqbFgsZyS/svelXNLhzYtCDKWxowOqebwQ
+T3lPm36LKAk+cGj6o8XsOzOAkVsdZYajn/QlSNTPnzHOVKnOPnu7ACEnt1xEv2dj
+IxvIjbX0vVv6rn36IaANbo0jryOq6Wnv12Q3WxO+6sdA3Y595uIf4nwIVycPFgWh
+49DqmWvYQWCAWClygNUikQ==
+-----END CERTIFICATE-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/server.csr b/src/lynq/lib/liblynq-protcl/http/cert/server.csr
new file mode 100644
index 0000000..853b893
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/server.csr
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICqDCCAZACAQAwYzELMAkGA1UEBhMCQ04xEDAOBgNVBAgMB0JlaWppbmcxEDAO
+BgNVBAcMB0JlaWppbmcxEDAOBgNVBAoMB1RlYW1zdW4xDjAMBgNVBAsMBWd1b3h1
+MQ4wDAYDVQQDDAVndW94dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AKUQ8kNAqIMlBxdhPo6QiNGyPVpRVV77X8juO1eKE2ROr9l0CuXbQh+oPARPK+0I
+/UeYHE8Q0ytIej5q7E2/nWqmW3i2IigSHDa2hN651GDd87KdwgfbHPXoAmpkmUT+
+T4ak2RRqzdKdT+MBVPgG1XoMFPBhk6cf8ItE8hY3gZ06m/J10PtoNl1ZIzi9dU7o
+TWpWbKOVxHEeOyop5NYBg8midYLGQtPNOw8uLwlXm+24doSFXUmV0J7ey4oqvNB9
+KbH+kgJlqSQouCSLaGngKxTzYuGREi2JXwIQeEh2SZ6CipT/8LtvDYIQ4H94WPNT
+StxU7vN9/BVAjUjDvKNd328CAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQApPn/s
+nVyEdO6QOK/c1ThZ8t8A+CVdllgsJrP2qZsnWnwKyAHcYSC2nuv4qvw20MNFdprd
+z/kIQz79o4lOCO9OHkpP5h6WaQ0z2u3kqCkIdkntkfkIKo1xq9MCO2ETKIkKEJcI
+HL9zLLiqL7tyHhv87celbqdiyvKfDKtH1/n7zT3nuU/PNzzUK6rLrlMASO5DQ5TI
+u/B+gfSem4aVyfgk4FqtpMnVhGlkdst+ajMJiFRNrB9nK8VhQZ7zdydt1TIT5E2H
+GSVFBi7TrC7lN1WHTPCRJXWlP4gaXO7imJ26IydSUaLi/X7DhDMXVAlOw38yvlUE
+MSJfg2BZDDSn7jVH
+-----END CERTIFICATE REQUEST-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/server.key b/src/lynq/lib/liblynq-protcl/http/cert/server.key
new file mode 100644
index 0000000..995401a
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/server.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEApRDyQ0CogyUHF2E+jpCI0bI9WlFVXvtfyO47V4oTZE6v2XQK
+5dtCH6g8BE8r7Qj9R5gcTxDTK0h6PmrsTb+daqZbeLYiKBIcNraE3rnUYN3zsp3C
+B9sc9egCamSZRP5PhqTZFGrN0p1P4wFU+AbVegwU8GGTpx/wi0TyFjeBnTqb8nXQ
++2g2XVkjOL11TuhNalZso5XEcR47Kink1gGDyaJ1gsZC0807Dy4vCVeb7bh2hIVd
+SZXQnt7Liiq80H0psf6SAmWpJCi4JItoaeArFPNi4ZESLYlfAhB4SHZJnoKKlP/w
+u28NghDgf3hY81NK3FTu8338FUCNSMO8o13fbwIDAQABAoIBAC5t39bu3vdUePQo
+lDIBkZp6Kiu3aO34gu6/o81xtxal02y06UPSMn05EvibVF2uA6AZtwy+TMeF8WyR
+IrqTxTF0bZI8mMrwnSL+n80ONCCzDZMWMLeI+FJq2hMXDM2NQs06nRzTFeXB/fB6
+NW42beGQeGtM5v1BTKW/1OBO6JRSrkODUwKluuTDZOwErfGZyuaJsZdghQ1Fh6jw
+WEpb9OzyqzRu5BQjk0xRyPSSDDNWi2jRCTYlk3hDCqeBvzqMHXMLh2biSIdUsEEG
+88STOFHGXR57Szpj+zl3P3AnH/c5ZLIHwq6b8gwC02TUb9cPK7setmXHrliWvVYT
+WXxsFuECgYEA1cPxmEqsZ9QW1j7rm1zMop+R0ft23zuKD93nskNreKinaPyOKyDG
+7+WQjCrdglIuuMnMmPJyhLx1taDMvOpzN1LbFWjxTwG1S6dp0tkTHAVaoKH58rxq
+XwDgWe3o9Txtt4dk9NuvJztxblT7qU7wIFXr3w5z13Y9GnqQvvfpTykCgYEAxa3X
+e6DAurK5A6+44eKrQXcvesjBJknYphVnQoFq+YjrYb/vCa/AgOFi5xQ1Co/q+F7r
+gtTAj/2KEbzdzxED+akIn0/pSsCxz8mbK85O8vBlaymrmMtRFVDIrDxMKxrgMT7Q
+4oKyB+JJy/6Muwlq/NTeMel0aFUP3WTI0GZpxNcCgYEArEajIVolAfSChx3kYaxz
+WyiAq5senR/tz4XGIfuF1JMPgGPx674ZteLsEJrHNC0pbFFuK2FRe7oqnzs9ZY8J
+Ve/XkrSlrUeyJYuBlKTPasjB1i1UNBU3IOOi67b6BRIzVjKu4UtfKJ4Wd5XT0ApH
+Kbg1ROnv4BhxfDKFDvLbO6kCgYBQyRW5+V0qL2X7ArI85iR00Z9+v1JoMl+uqCqV
+/EvahMElJooq3D+ArBt+Mjzm/x/YtvnqcsXrUoM9coD3YY3NVu4mJUNDAHLqZwra
+ISsUj3fzDomJHPYbDvOjp9S8/PPITFKTbzQQksLz8ihTO6sUfm372dtv0+ty4ABN
+Yr0w6wKBgGwfvkITtbYU0gFOC8G7XX8liT23HOegvTXraBm38IWXHMVqOwk0lCEQ
+crk54pXDzJd3yXqwFIq5g1w/enjeGq+ly6C/XWuSAepkQjecHxzkYTcrCdyWWifx
+zZD9xKOvXNqU26ZdoZQHNaAktCoXYEC3BA6jSJtfinLzzwS4olV1
+-----END RSA PRIVATE KEY-----
diff --git a/src/lynq/lib/liblynq-protcl/http/cert/server.p12 b/src/lynq/lib/liblynq-protcl/http/cert/server.p12
new file mode 100644
index 0000000..eb0ceea
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/cert/server.p12
Binary files differ
diff --git a/src/lynq/lib/liblynq-protcl/http/src/lynq_http.c b/src/lynq/lib/liblynq-protcl/http/src/lynq_http.c
new file mode 100644
index 0000000..94b8ef1
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/src/lynq_http.c
@@ -0,0 +1,1289 @@
+#include "http/lynq_http.h"
+
+
+
+#define _stricmp strcasecmp
+#define _strnicmp strncasecmp
+
+
+const int kSelectRead	= 1 << 0;
+const int kSelectWrite	= 1 << 1;
+const int kSelectError	= 1 << 2;
+
+#define DEFAULT_USER_AGENT_STR "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0\r\n"
+#define CONNECT_KEEP_STR "Connection: keep-alive\r\n"
+#define CONNECT_CLOSE_STR "Connection: close\r\n"
+#define ACCEPT_STR "Accept: */*\r\n"
+#define CONTENT_LENGTH_STR "Content-Length"
+#define CONTENT_TYPE_STR "Content-Type:application/x-www-form-urlencoded\r\n"
+#define CONTENT_DISPOSITION_STR "Content-Disposition"
+#define CRLF "\r\n"
+
+#define CA_ROOT "cert/ca.crt"
+#define CA_CLICRT "cert/client.crt"
+#define CA_CLIKEY "cert/client.key"
+
+
+static char* _strdup(const char* src)
+{
+	char* dst = NULL;
+	int len = 0;
+	if(src == NULL)
+	{
+		return NULL;
+	}
+	len = strlen(src);
+	dst = (char*)malloc(len + 1);
+	if(dst == NULL)
+	{
+		return NULL;
+	}
+	strcpy(dst, src);
+	return dst;
+}
+
+static void http_ssl_free(lynq_http_client_t* http)
+{
+	if(http->ssl != NULL)
+	{
+		SSL_shutdown(http->ssl);
+		SSL_free(http->ssl);
+		http->ssl = NULL;
+	}
+	if(http->ctx != NULL) 
+	{
+		SSL_CTX_free(http->ctx); 
+		http->ctx = NULL; 
+	}
+}
+
+int lynq_http_init()
+{
+	OpenSSL_add_all_algorithms();
+	ERR_load_BIO_strings();
+	ERR_load_crypto_strings();
+	SSL_load_error_strings();
+
+	if(SSL_library_init() < 0)
+	{
+		LYVERBLOG("+[http][init]: error num = %d\n", ERR_SSL_CREATE_SSL);
+		return ERR_SSL_CREATE_SSL;
+	}
+	return 0;
+}
+
+lynq_http_client_t* lynq_http_new()
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)calloc(1, sizeof(lynq_http_client_t));
+
+	return http;
+}
+
+void lynq_http_destroy(lynq_http_client_t* http)
+{
+	if(http == NULL) return;
+
+	free_member(http->body);
+	free_member(http->header_field);
+	free_member(http->header_value);
+	free_member(http->redirect_url);
+	free_member(http->filename);
+	close_socket(http->fd);
+	close_file(http->pf);
+
+	http_ssl_free(http);
+
+	free(http);
+}
+
+int lynq_http_get_error_code(lynq_http_client_t* http)
+{
+	if(http == NULL)
+	{
+		return -1;
+	}
+	return http->error_code;
+}
+
+static int socket_noblocking(socket_t fd, int noblocking)
+{
+
+	int flags;
+	if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
+	{
+		return -1;
+	}
+	if(noblocking)
+	{
+		return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+	}
+	else
+	{
+		return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+	}
+
+	return 0;
+}
+
+static int last_error()
+{
+	return errno;
+}
+
+static int socket_select(lynq_http_client_t* http, int mode, int timeout)
+{
+	fd_set rfd, wfd, efd;
+	int r = 0;
+	int error = 0;
+	int remaind = timeout;
+	socklen_t len = sizeof(error);
+
+	struct timeval tv, start, elapsed;
+
+	gettimeofday(&start, 0);
+
+	while(remaind > 0)
+	{
+		if(mode & kSelectRead)	{ FD_ZERO(&rfd); FD_SET(http->fd, &rfd); }
+		if(mode & kSelectWrite){ FD_ZERO(&wfd); FD_SET(http->fd, &wfd); }
+		if(mode & kSelectError){ FD_ZERO(&efd); FD_SET(http->fd, &efd); }
+
+		tv.tv_sec = remaind / 1000;
+		tv.tv_usec = remaind % 1000 * 1000;
+
+		r = select(http->fd+1,
+				(mode & kSelectRead)	? &rfd : NULL,
+				(mode & kSelectWrite)	? &wfd : NULL,
+				(mode & kSelectError)	? &efd : NULL,
+				&tv);
+
+		if( r == 0)
+		{
+			return -1;
+		}
+
+		if( r > 0) 
+		{
+			if(getsockopt(http->fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len) == 0 && error == 0)
+			{
+				return 0;
+			}
+			else
+			{
+				return -1;
+			}
+		}
+
+		if( r < 0 )
+		{
+			if(last_error() == HTTP_EINTR)
+			{
+				gettimeofday(&elapsed, 0);
+				remaind = timeout - ((int)(elapsed.tv_sec - start.tv_sec) * 1000 + (int)(elapsed.tv_usec - start.tv_usec) / 1000);
+
+				continue;
+			}
+			else
+			{
+				return -1;
+			}
+		}
+	};
+
+	return -1;
+}
+
+static int _field_value_malloc(char** str, unsigned short* cur_size, unsigned short* size, const char* at, size_t length)
+{
+	if(*str == NULL)
+	{
+#define DEFAULT_HEADER_SIZE 128
+		*size = length > DEFAULT_HEADER_SIZE ? length: DEFAULT_HEADER_SIZE;
+		*str = (char*)calloc(1, *size + 1);
+		if(*str == NULL)
+		{
+			return -1;
+		}
+		*cur_size = 0;
+	}
+	else if(*cur_size + length > *size)
+	{
+		*size = *cur_size + length;
+		*str = (char*)realloc(*str, *size + 1);
+		if(*str == NULL)
+		{
+			return -1;
+		}
+	}
+	memcpy(*str + *cur_size, at, length);
+	*cur_size += length;
+	(*str)[*cur_size] = '\0';
+	return 0;
+}
+
+static int parser_field_value(lynq_http_client_t* http)
+{
+	if(http->cur_value_size > 0 && 
+			http->cur_field_size > 0 &&
+			http->header_field && http->header_value)
+	{
+		if(_stricmp(http->header_field, "Location") == 0)
+		{
+			free_member(http->redirect_url);
+			http->redirect_url = _strdup(http->header_value);
+
+			http->redirect = 1; 
+			return -1;
+		}
+		else if(_stricmp(http->header_field, CONTENT_LENGTH_STR) == 0)
+		{
+			http->content_length = atol(http->header_value);
+		}
+		else
+		{
+			/* extract other header field value */
+		}
+		http->cur_field_size = 0;
+		http->cur_value_size = 0;
+	}
+
+	return 0;
+}
+
+static int on_header_field_cb(http_parser* parser, const char *at, size_t length)
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)parser->data;
+
+	if(http->parser_statue == PARSERD_VALUE)
+	{
+		if( parser_field_value(http) != 0)
+		{
+			return -1;
+		}
+	}
+	http->parser_statue = PARSERD_FIELD;
+	return _field_value_malloc(&http->header_field, &http->cur_field_size, &http->field_size, at, length);
+}
+
+static int on_header_value_cb(http_parser* parser, const char *at, size_t length)
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)parser->data;
+
+	if(http->parser_statue == PARSERD_FIELD || http->parser_statue == PARSERD_VALUE)
+	{
+		http->parser_statue = PARSERD_VALUE;
+		return _field_value_malloc(&http->header_value, &http->cur_value_size, &http->value_size, at, length);
+	}
+	return 0;
+}
+
+static int on_status_cb(http_parser* parser, const char *at, size_t length)
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)parser->data;
+	http->status_code = parser->status_code;
+	return 0;
+}
+
+static int on_headers_complete_cb(http_parser* parser)
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)parser->data;
+	if(parser_field_value(http) != 0)
+	{
+		return -1;
+	}
+	free_member(http->header_field);
+	free_member(http->header_value);
+	http->parser_statue = PARSERD_BODY;
+	http->cur_field_size = http->cur_value_size = 0;
+	return 0;
+}
+
+static int on_download_file_cb(http_parser* parser, const char *at, size_t length)
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)parser->data;
+
+	if(http->status_code >= 200 && http->status_code <= 299)
+	{
+		if(http->pf == NULL)
+		{
+			if(http->filename != NULL)
+			{
+				http->pf = fopen(http->filename, "wb");
+			}
+		}
+
+		if(http->pf == NULL)
+		{
+			return -1;
+		}
+		if( http->recv_cb && (http->recv_cb)(http, at, length, http->content_length, http->user) != 0)
+		{
+			return -1;
+		}
+
+		fwrite(at, 1, length, http->pf);
+	}
+
+	return 0;
+}
+
+static int on_body_cb(http_parser* parser, const char *at, size_t length)
+{
+	lynq_http_client_t* http = (lynq_http_client_t*)parser->data;
+
+	if(http->body == NULL)
+	{
+
+		if(http->content_length > 0)
+		{
+			http->body = (char*)calloc(1, http->content_length + 1);
+		}
+		else
+		{
+			http->body = (char*)calloc(1, length + 1);
+		}
+	}
+	else
+	{
+		if(http->content_length <= 0)
+		{
+			http->body = (char*)realloc(http->body, http->body_len + length + 1);
+		}
+	}
+	if(http->body == NULL)
+	{
+		return -1;
+	}
+	memcpy(http->body + http->body_len, at, length);
+	http->body_len += length;
+
+	return 0;
+}
+
+static int on_message_complete_cb(http_parser* parser)
+{
+	return 0;
+}
+
+static int http_check_error(lynq_http_client_t* http, int mode, int ret)
+{
+	int error_code;
+	if(http->proto_type == PROTO_HTTPS)
+	{
+		int error =  SSL_get_error(http->ssl, ret);
+		if(SSL_ERROR_ZERO_RETURN == error)
+		{
+			return -1;
+		}
+		else if(error == SSL_ERROR_WANT_WRITE || 
+				error == SSL_ERROR_WANT_READ)
+		{
+			return 0;
+		}
+		else if(SSL_ERROR_SYSCALL == error)
+		{
+			goto check_select;
+		}
+		else
+		{
+			return -1;
+		}
+	}
+check_select:
+	error_code = last_error();
+	if(error_code == HTTP_EINTR)
+	{
+		return 0;
+	}
+	else if(error_code == HTTP_EINPROGRESS || error_code == HTTP_EWOULDBLOCK)
+	{
+		if(socket_select(http, mode, http->timeout) == 0)
+		{
+			return 0;
+		}
+	}
+	return -1;
+}
+
+static int http_read_write(lynq_http_client_t* http, const char* data, int len, int read)
+{
+	int n = 0, r = 0;
+
+	do
+	{
+		if(http->exit == 1)
+		{
+			return -1;
+		}
+
+		if(http->proto_type == PROTO_HTTPS)
+		{
+
+			r = read ? SSL_read(http->ssl, (char*)data + n, len - n) : SSL_write(http->ssl, data + n, len - n);
+		}
+		else
+		{
+			r = read ? recv(http->fd, (char*)data + n, len - n, 0) : send(http->fd, data + n, len - n, 0);
+		}
+
+		if(r > 0)
+		{
+			n += r;
+		}
+		else if(r == 0)
+		{
+			return n;
+		}
+		else
+		{
+			if(http_check_error(http, read ? kSelectRead : kSelectWrite, r) == 0)
+			{
+				continue;
+			}
+			return -1;
+		}
+		
+		http->data = data;
+		LYDBGLOG("[%s-%d] +http%s, session = %d, data = %s \n", __FUNCTION__, __LINE__, http->action, http->session, data);
+		LYVERBLOG("+[http][%s][session%d]: data = %s\n", http->action, http->session, data);
+		LYVERBLOG("+[http][%s][session%d]: ok!!\n", http->action, http->session);
+	}while(n < len);
+	http->data = NULL;
+
+	return n;
+}
+
+#define HTTP_KEY "self.key"
+#define HTTP_CERTIFICATE "self.crt"
+
+static int sslSetCertFile(SSL_CTX *sslctx, char *certFile)
+{
+	if (sslctx == NULL)
+	{
+		return -1;
+	}
+
+	if (SSL_CTX_use_certificate_file(sslctx, certFile, SSL_FILETYPE_PEM) <= 0) {
+		if (SSL_CTX_use_certificate_file(sslctx, certFile, SSL_FILETYPE_ASN1) <= 0) {
+			return -1;
+		}
+	}
+
+	if(!SSL_CTX_check_private_key(sslctx)){
+		return -1;
+	}
+	return 0;
+}
+
+
+static int sslSetKeyFile(SSL_CTX *sslctx, char *keyFile)
+{
+	if (sslctx == NULL)
+	{
+		return -1;
+	}
+
+	if (SSL_CTX_use_PrivateKey_file(sslctx, keyFile, SSL_FILETYPE_PEM) <= 0) {
+		if (SSL_CTX_use_PrivateKey_file(sslctx, keyFile, SSL_FILETYPE_ASN1) <= 0) {
+			return -1;
+		}
+		return -1;
+	}
+
+	return 0;
+}
+
+#define VERIFY_DEPTH 10
+static int verify_X509Certificate(int ok, X509_STORE_CTX *xContext)
+{
+	X509 *cert;
+	char subject[260], issuer[260], peer[260];
+	int error, depth;
+	subject[0] = issuer[0] = '\0';
+	cert = X509_STORE_CTX_get_current_cert(xContext);
+	error = X509_STORE_CTX_get_error(xContext);
+	depth = X509_STORE_CTX_get_error_depth(xContext);
+	ok = 1;
+
+	if (X509_NAME_oneline(X509_get_subject_name(cert), subject, sizeof(subject) - 1) < 0) {
+		ok = 0;
+	}
+
+	if (X509_NAME_oneline(X509_get_issuer_name(cert), issuer, sizeof(issuer) - 1) < 0) {
+		ok = 0;
+	}
+
+	if (ok && VERIFY_DEPTH < depth) { 
+		if (error == 0) {
+			error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+		}
+	} 
+	switch (error) {
+		case X509_V_OK:
+			break ;
+		case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNABLE_TO_GET_CRL:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CRL_SIGNATURE_FAILURE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_NOT_YET_VALID:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_HAS_EXPIRED:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CRL_NOT_YET_VALID:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CRL_HAS_EXPIRED:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_OUT_OF_MEM:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_CHAIN_TOO_LONG:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_REVOKED:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_INVALID_CA:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_INVALID_PURPOSE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_UNTRUSTED:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CERT_REJECTED:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_AKID_SKID_MISMATCH:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_INVALID_EXTENSION:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_INVALID_POLICY_EXTENSION:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_NO_EXPLICIT_POLICY:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_DIFFERENT_CRL_SCOPE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_PERMITTED_VIOLATION:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_EXCLUDED_VIOLATION:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_SUBTREE_MINMAX:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
+			ok = 0;
+			break;
+
+		case X509_V_ERR_APPLICATION_VERIFICATION:
+			ok = 0;
+			break;
+
+		default:
+			ok = 0;
+			break;
+	}
+
+	return ok;
+}
+
+void https_certificate_validation(SSL * ssl)
+{
+	X509 *cert;
+	char *line;
+
+	cert = SSL_get_peer_certificate(ssl);
+	if(SSL_get_verify_result(ssl) == X509_V_OK){
+		LYDBGLOG("Certificate verification passed\n");
+	}
+	if (cert != NULL) {
+		line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
+		free(line);
+		line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
+		free(line);
+		X509_free(cert);
+	} else
+		LYDBGLOG("[%s %d] No certificate information\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[http]: error num = %d\n", ERR_NOCERT);
+}
+
+static int http_ssl_connect(lynq_http_client_t* http)
+{
+	int ssl_ret = 0;
+	int remaind = http->timeout;
+	struct timeval start, elapsed;
+
+	http->ctx = SSL_CTX_new(SSLv23_client_method());
+	if(http->ctx == NULL)
+	{
+		return -1;
+	}
+	SSL_CTX_set_verify(http->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_X509Certificate);
+	SSL_CTX_set_verify_depth(http->ctx, VERIFY_DEPTH);
+
+	if (SSL_CTX_load_verify_locations(http->ctx, CA_ROOT, NULL) <= 0){
+		LYVERBLOG("+[http][%s][session%d]: error num = %d\n", http->action, http->session, ERR_SSL_CREATE_CTX);
+		return ERR_SSL_CREATE_CTX;
+	}
+
+	sslSetCertFile(http->ctx, CA_CLICRT);
+
+	sslSetKeyFile(http->ctx, CA_CLIKEY);
+
+	http->ssl = SSL_new(http->ctx);
+	if(http->ssl == NULL)
+	{
+		return -1;
+	}
+	if(SSL_set_fd(http->ssl, http->fd) == 0)
+	{
+		return -1;
+	}
+
+	gettimeofday(&start, 0);
+
+	do
+	{
+		ssl_ret = SSL_connect(http->ssl);
+
+		if (ssl_ret == -1) {
+			ERR_print_errors_fp(stderr);
+		} 
+
+		else {
+			LYDBGLOG("[%s %d] Connected with %s encryption\n", __FUNCTION__, __LINE__, SSL_get_cipher(http->ssl));
+			//Show certificate information
+			//https_certificate_validation(http->ssl);
+		}
+
+		gettimeofday(&elapsed, 0);
+		remaind = http->timeout - ((int)(elapsed.tv_sec - start.tv_sec) * 1000 + (int)(elapsed.tv_usec - start.tv_usec) / 1000);
+
+		if(ssl_ret > 0)
+		{
+			return 0;
+		}
+		else
+		{
+			if(remaind <= 0)
+			{
+				return -1;
+			}
+			else if(http_check_error(http, kSelectRead+kSelectWrite, ssl_ret) == 0)
+			{
+				continue;
+			}
+			return -1;
+		}
+	}while(1);
+
+	return -1;
+}
+
+static int http_connect_host(lynq_http_client_t* http, const char* url, struct http_parser_url* u)
+{
+	struct sockaddr_in sin;
+	char host[256] = {0};
+	int r;
+	unsigned short port = 80;
+
+	if(u->field_set & (1 << UF_SCHEMA))
+	{
+		if(_strnicmp("http://", url + u->field_data[UF_SCHEMA].off, 7) == 0)
+		{
+			port = 80; http->proto_type = PROTO_HTTP;
+		}
+
+		else if(_strnicmp("https://", url + u->field_data[UF_SCHEMA].off, 8) == 0)
+		{
+			port = 443; http->proto_type = PROTO_HTTPS;
+		}
+
+		else
+		{
+			return ERR_URL_INVALID_PROTO;
+		}
+	}
+
+	if(!(u->field_set & (1 << UF_HOST)))
+	{
+		return ERR_URL_INVALID_HOST;
+	}
+
+	if(u->field_set & (1 << UF_PORT))
+	{
+		port = (unsigned short)atoi(url + u->field_data[UF_PORT].off);
+	}
+
+	memset(&sin, 0, sizeof(struct sockaddr_in));
+	memcpy(host, url + u->field_data[UF_HOST].off, u->field_data[UF_HOST].len);
+	if(host[0] >= '0' && host[0] <= '9')
+	{
+		sin.sin_addr.s_addr = (unsigned long)inet_addr(host);
+	}
+	else
+	{
+		struct hostent* he = gethostbyname(host);
+		if(he == NULL || he->h_addrtype != AF_INET)
+		{
+			return ERR_URL_RESOLVED_HOST;
+		}
+		sin.sin_addr = *((struct in_addr *)he->h_addr_list[0]);
+	}
+
+	if(sin.sin_addr.s_addr == INADDR_NONE)
+	{
+		return ERR_URL_RESOLVED_HOST;
+	}
+
+	sin.sin_port = htons(port);
+	sin.sin_family = AF_INET;
+
+
+	http->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+	if(http->fd == HTTP_INVALID_SOCKET)
+	{
+		return ERR_SOCKET_CREATE;
+	}
+
+	{
+		struct linger linger;
+		linger.l_onoff = 1;
+		linger.l_linger = 0;
+
+		if(setsockopt(http->fd,SOL_SOCKET, SO_LINGER,(const char *) &linger,sizeof(linger)) != 0)
+		{
+			return ERR_SOCKET_SET_OPT;
+		}
+		if(socket_noblocking(http->fd, 1) != 0)
+		{
+			return ERR_SOCKET_NOBLOCKING;
+		}
+	}
+
+	do
+	{
+		r = connect(http->fd, (struct sockaddr*)&sin, sizeof(sin));
+		if(r < 0)
+		{
+			int error = last_error();
+			if(error == HTTP_EINTR)
+			{
+				continue;
+			}
+			else if( error == HTTP_EINPROGRESS || error == HTTP_EWOULDBLOCK ||  error == HTTP_EALREADY)
+			{
+				if(socket_select(http, kSelectWrite, http->timeout) == 0)
+				{
+					break;
+				}
+				else
+				{
+					return ERR_SOCKET_CONNECT_TIMEOUT;
+				}
+			}
+			return ERR_SOCKET_CONNECT;
+		}
+	}while(1);
+
+	if(http->proto_type == PROTO_HTTPS)
+	{
+		if(http_ssl_connect(http) != 0)
+		{
+			return ERR_SSL_CONNECT;
+		}
+	}
+
+	return ERR_OK;
+}
+
+void http_init(lynq_http_client_t* http)
+{
+
+	http->redirect = 0;
+	http->body_len = 0;
+	http->content_length = 0;
+	http->cur_field_size = 0;
+	http->cur_value_size = 0;
+	http->field_size = 0;
+	http->value_size = 0;
+	http->parser_statue = 0;
+	http->error_code = 0;
+	http->user_header = 0;
+	http->user_header_len = 0;
+
+	if(http->timeout == 0) http->timeout = 1500000;
+}
+
+int http_connect(lynq_http_client_t* http)
+{
+	int r = 0;
+	if( http_parser_parse_url(http->url, strlen(http->url), 0, &http->u) != 0 )
+	{
+		LYDBGLOG("[%s-%d] ==============\n", __FUNCTION__, __LINE__);
+		return (http->error_code = ERR_URL_INVALID);
+	}
+
+	r = http_connect_host(http, http->url, &http->u);
+	if(r != ERR_OK)
+	{
+		LYDBGLOG("[%s-%d] ==============\n", __FUNCTION__, __LINE__);
+		return (http->error_code = r);
+	}
+
+	return 0;
+}
+
+int CHECK(int ret, lynq_http_client_t* http)
+{
+	if(ret <= 0)
+		return (http->error_code = ERR_SOCKET_WRITE);
+
+	return 0;
+}
+
+void http_write_headers(lynq_http_client_t* http)
+{
+	char *url = NULL;
+	if(http->redirect == 1)
+		url = http->redirect_url;
+	else 
+		url = http->url;
+
+	if(http->method == M_GET)
+	{
+		CHECK(http_read_write(http, "GET ", 4, 0), http);
+	}
+	else if(http->method == M_POST)
+	{
+		CHECK(http_read_write(http, "POST ", 5, 0), http);
+	}
+
+	if(http->u.field_set & (1 << UF_PATH))
+	{
+		CHECK(http_read_write(http, url + http->u.field_data[UF_PATH].off, http->u.field_data[UF_PATH].len, 0), http);
+	}
+	else
+	{
+		CHECK(http_read_write(http, "/", 1, 0), http);
+	}
+
+	if(http->u.field_set & (1 << UF_QUERY))
+	{
+		CHECK(http_read_write(http, "?", 1, 0), http);
+		CHECK(http_read_write(http, url + http->u.field_data[UF_QUERY].off, http->u.field_data[UF_QUERY].len, 0), http);
+	}
+
+	CHECK(http_read_write(http, " HTTP/1.1\r\nHost:", 16, 0), http);
+	CHECK(http_read_write(http, url + http->u.field_data[UF_HOST].off, http->u.field_data[UF_HOST].len, 0), http);
+
+	if(http->conn_method == M_KEEP) {
+		CHECK(http_read_write(http, CRLF CONNECT_KEEP_STR ACCEPT_STR DEFAULT_USER_AGENT_STR  ,
+					2 + strlen(CONNECT_KEEP_STR) + strlen(ACCEPT_STR) + strlen(DEFAULT_USER_AGENT_STR), 0), http);
+	}
+	else {
+		CHECK(http_read_write(http, CRLF CONNECT_CLOSE_STR ACCEPT_STR DEFAULT_USER_AGENT_STR  ,
+					2 + strlen(CONNECT_CLOSE_STR) + strlen(ACCEPT_STR) + strlen(DEFAULT_USER_AGENT_STR), 0), http);
+	}
+
+	if(http->user_header != NULL)
+	{
+		CHECK(http_read_write(http, http->user_header, http->user_header_len, 0), http);
+	}
+
+	if(http->post_data && http->post_data_len > 0)
+	{
+		char len_data[256] = {0};
+		int n = sprintf(len_data, "%s:%d\r\n", CONTENT_TYPE_STR CONTENT_LENGTH_STR, http->post_data_len);
+		CHECK(http_read_write(http, len_data, n, 0), http);
+	}
+
+	CHECK(http_read_write(http, CRLF, 2, 0), http);
+
+
+}
+
+void http_write_data(lynq_http_client_t* http)
+{
+	CHECK(http_read_write(http, http->post_data, http->post_data_len, 0), http);
+}
+
+int lynq_http_data_send(char *data)
+{
+	struct mymesg ckxmsg;
+	ckxmsg.mtype = 1;
+	strcpy(ckxmsg.mtext, data);
+	int id = lynq_msgq_init("/tmp", 0666);
+	lynq_msgq_send(id, &ckxmsg);
+}
+
+void *lynq_http_write_head_data(lynq_http_client_t* http)
+{
+
+	http_write_headers(http);
+
+	if(http->post_data && http->post_data_len > 0)
+	{
+		http_write_data(http);
+	}
+	http->post_data = "";
+}
+
+void *http_write_head_data_thread(void* arg)
+{
+	int id = 0;
+	int runing = 1 ;
+	struct mymesg ckxmsg;
+
+	lynq_http_client_t* http = (lynq_http_client_t*)arg;
+
+	id = lynq_msgq_init("/tmp", 0666);
+
+	while(runing)
+	{
+#if 1	
+		if(!strcmp(http->post_data, "") && http->conn_method == M_KEEP)
+		{
+			if(msgrcv(id, (void *)&ckxmsg, 512, 1, 0) < 0)
+			{
+				LYDBGLOG("[%s-%d] receive msg error \n", __FUNCTION__, __LINE__);
+				LYVERBLOG("+[http]: error num = %d\n", ERR_MSG);
+				return ERR_MSG;
+			}
+			LYDBGLOG("[%s-%d] mtext :%s\n", __FUNCTION__, __LINE__, ckxmsg.mtext);
+
+			if (!strcmp(ckxmsg.mtext,"close"))
+				return NULL;
+
+			http->post_data = ckxmsg.mtext;
+		}
+#endif
+		lynq_http_write_head_data(http);
+
+	}
+}
+
+
+void *http_read_data_thread(void* arg)
+{
+	int parsed = 0;
+	lynq_http_client_t* http = (lynq_http_client_t*)arg;
+	do
+	{
+		int nread = 0;
+
+		if(http->download == 0 && http->parser_statue == PARSERD_BODY && http->body && http->content_length > 0)
+		{
+			nread = http_read_write(http, http->body+http->body_len, http->content_length - http->body_len, 1);
+			if(nread > 0)
+			{
+				http->body_len += nread; 
+				break;
+			}
+		}
+		else
+		{
+			char buf[RECV_BUF_SIZE + 1] = {0};
+
+			nread = http_read_write(http, buf, RECV_BUF_SIZE, 1);
+
+			if(nread > 0)
+			{
+				parsed = http_parser_execute(&http->parser, &http->parser_setting, buf, nread);
+
+				if(http->redirect)
+				{
+					break;
+				}
+
+				if(parsed != nread)
+				{
+					return NULL;
+				}
+			}
+		}
+
+		if(nread == 0)
+		{
+			break;
+		}
+		else if(nread < 0)
+		{
+			return NULL;
+		}
+
+	} while (1);
+
+	return NULL;
+}
+
+
+
+static int http_internal_sync_request(lynq_http_client_t* http)
+{
+	int ret = 0;
+	http_init(http);
+
+	ret = http_connect(http);
+	if(ret != ERR_OK)
+	{
+		LYDBGLOG("[%s %d] return error\n", __FUNCTION__, __LINE__);
+		LYVERBLOG("+[http][%s][session%d]: error num = %d\n", http->action, http->session, http->error_code);
+		return (http->error_code);
+	}
+
+	if(http->conn_method == M_CLOSE)
+		lynq_http_write_head_data(http);
+	else {
+		pthread_t tid;
+		pthread_create(&tid, NULL, http_write_head_data_thread, http);
+	}
+	memset(&http->parser_setting, 0, sizeof(http->parser_setting));
+	http->parser_setting.on_body = http->download ? on_download_file_cb : on_body_cb;
+	http->parser_setting.on_message_complete = on_message_complete_cb;
+	http->parser_setting.on_header_field = on_header_field_cb;
+	http->parser_setting.on_header_value = on_header_value_cb;
+	http->parser_setting.on_headers_complete = on_headers_complete_cb;
+	http->parser_setting.on_status = on_status_cb;
+
+	http_parser_init(&http->parser, HTTP_RESPONSE);
+	http->parser.data = http;
+
+	if(http->conn_method == M_CLOSE)
+		http_read_data_thread(http);
+	else {
+		pthread_t read_tid;
+		pthread_create(&read_tid, NULL, http_read_data_thread, http);
+	}
+
+	if(http->redirect == 1)
+	{
+		return http_internal_sync_request(http);
+	}
+	else
+	{
+		if(http->download)
+		{
+			if(http->pf) 
+			{
+				fclose(http->pf);
+				http->pf = NULL;
+			}
+		}
+		if(http->body && http->body_len > 0)
+		{
+			http->body[http->body_len] = '\0';
+		}
+	}
+	return http->error_code;
+}
+
+const char* lynq_http_sync_request(lynq_http_client_t* http, const char* url, http_request_method_e m, http_connent_method_e c_m)
+{
+	if(http == NULL)
+	{
+		return NULL;
+	}
+
+	http->method = m;
+	http->conn_method = c_m;
+	http->download = 0;
+	http->url = (char *)url;
+	http->error_code = http_internal_sync_request(http);
+
+	return http->body;
+}
+
+const char* lynq_http_sync_post_request(lynq_http_client_t* http, char* url, char* post_data, http_request_method_e m, http_connent_method_e c_m)
+{
+	if(http == NULL)
+	{
+		return NULL;
+	}
+
+	http->method = m;
+	http->conn_method = c_m;
+	http->download = 0;
+	free_member(http->post_data);
+	http->post_data = post_data;
+	http->url = url;
+	http->post_data_len = strlen(http->post_data);
+
+	http->error_code = http_internal_sync_request(http);
+
+	return http->body;
+}
+
+ int lynq_http_sync_download_file(lynq_http_client_t* http, char* url, char* filepath, http_request_method_e m, http_connent_method_e c_m)
+{
+	if(http == NULL)
+	{
+		return -1;
+	}
+
+	http->method = m;
+	http->conn_method = c_m;
+	http->download = 1;
+
+	http->post_data = "";
+
+	free_member(http->url);
+
+	http->url = url;
+
+	free_member(http->filename);
+
+	if(filepath == NULL || !strcmp(filepath, ""))
+	{
+		filepath = strrchr(http->url, '/') + 1 ;
+	}
+
+	if(filepath != NULL)
+	{
+		http->filename = _strdup(filepath);
+
+		if(http->filename == NULL)
+		{
+			return http->error_code = ERR_OUT_MEMORY;
+		}
+	}
+
+	if(http_internal_sync_request(http) == ERR_OK)
+	{
+		return ERR_OK;
+	}
+
+	return http->error_code;
+}
+
+int lynq_http_exit(lynq_http_client_t* http)
+{
+	if(http) http->exit = 1;
+
+	return 0;
+}
+
+int ft_http_set_data_recv_cb(lynq_http_client_t* http, data_recv_cb_t cb, void* user)
+{
+	if(http)
+	{
+		http->user = user;
+		http->recv_cb = cb;
+	}
+	return 0;
+}
diff --git a/src/lynq/lib/liblynq-protcl/http/src/lynq_http_parser.c b/src/lynq/lib/liblynq-protcl/http/src/lynq_http_parser.c
new file mode 100644
index 0000000..306e6db
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/src/lynq_http_parser.c
@@ -0,0 +1,2267 @@
+#include "http/lynq_http_parser.h"
+#include <assert.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#ifndef ULLONG_MAX
+# define ULLONG_MAX ((uint64_t) -1)
+#endif
+
+#ifndef MIN
+# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#endif
+
+#ifndef BIT_AT
+# define BIT_AT(a, i)                                                \
+	(!!((unsigned int) (a)[(unsigned int) (i) >> 3] &                  \
+	    (1 << ((unsigned int) (i) & 7))))
+#endif
+
+#ifndef ELEM_AT
+# define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v))
+#endif
+
+#define SET_ERRNO(e)                                                 \
+	do {                                                                 \
+		parser->http_errno = (e);                                          \
+	} while(0)
+
+#define CURRENT_STATE() p_state
+#define UPDATE_STATE(V) p_state = (enum state) (V);
+#define RETURN(V)                                                    \
+	do {                                                                 \
+		parser->state = CURRENT_STATE();                                   \
+		return (V);                                                        \
+	} while (0);
+#define REEXECUTE()                                                  \
+	goto reexecute;                                                    \
+
+# define LIKELY(X) __builtin_expect(!!(X), 1)
+# define UNLIKELY(X) __builtin_expect(!!(X), 0)
+
+
+
+/* Run the notify callback FOR, returning ER if it fails */
+#define CALLBACK_NOTIFY_(FOR, ER)                                    \
+	do {                                                                 \
+		assert(HTTP_PARSER_ERRNO(parser) == HPE_OK);                       \
+		\
+		if (LIKELY(settings->on_##FOR)) {                                  \
+			parser->state = CURRENT_STATE();                                 \
+			if (UNLIKELY(0 != settings->on_##FOR(parser))) {                 \
+				SET_ERRNO(HPE_CB_##FOR);                                       \
+			}                                                                \
+			UPDATE_STATE(parser->state);                                     \
+			\
+			/* We either errored above or got paused; get out */             \
+			if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) {             \
+				return (ER);                                                   \
+			}                                                                \
+		}                                                                  \
+	} while (0)
+
+#define CALLBACK_NOTIFY(FOR)            CALLBACK_NOTIFY_(FOR, p - data + 1)
+#define CALLBACK_NOTIFY_NOADVANCE(FOR)  CALLBACK_NOTIFY_(FOR, p - data)
+#define CALLBACK_DATA_(FOR, LEN, ER)                                 \
+	do {                                                                 \
+		assert(HTTP_PARSER_ERRNO(parser) == HPE_OK);                       \
+		\
+		if (FOR##_mark) {                                                  \
+			if (LIKELY(settings->on_##FOR)) {                                \
+				parser->state = CURRENT_STATE();                               \
+				if (UNLIKELY(0 !=                                              \
+							settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \
+					SET_ERRNO(HPE_CB_##FOR);                                     \
+				}                                                              \
+				UPDATE_STATE(parser->state);                                   \
+				\
+				/* We either errored above or got paused; get out */           \
+				if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) {           \
+					return (ER);                                                 \
+				}                                                              \
+			}                                                                \
+			FOR##_mark = NULL;                                               \
+		}                                                                  \
+	} while (0)
+
+#define CALLBACK_DATA(FOR)                                           \
+	CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)
+
+#define CALLBACK_DATA_NOADVANCE(FOR)                                 \
+	CALLBACK_DATA_(FOR, p - FOR##_mark, p - data)
+
+#define MARK(FOR)                                                    \
+	do {                                                                 \
+		if (!FOR##_mark) {                                                 \
+			FOR##_mark = p;                                                  \
+		}                                                                  \
+	} while (0)
+
+#define COUNT_HEADER_SIZE(V)                                         \
+	do {                                                                 \
+		parser->nread += (V);                                              \
+		if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) {            \
+			SET_ERRNO(HPE_HEADER_OVERFLOW);                                  \
+			goto error;                                                      \
+		}                                                                  \
+	} while (0)
+
+
+#define PROXY_CONNECTION "proxy-connection"
+#define CONNECTION "connection"
+#define CONTENT_LENGTH "content-length"
+#define TRANSFER_ENCODING "transfer-encoding"
+#define UPGRADE "upgrade"
+#define CHUNKED "chunked"
+#define KEEP_ALIVE "keep-alive"
+#define CLOSE "close"
+
+
+static const char *method_strings[] =
+{
+#define XX(num, name, string) #string,
+	HTTP_METHOD_MAP(XX)
+#undef XX
+};
+
+static const char tokens[256] = {
+	/*   0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel  */
+	0,       0,       0,       0,       0,       0,       0,       0,
+	/*   8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si   */
+	0,       0,       0,       0,       0,       0,       0,       0,
+	/*  16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb */
+	0,       0,       0,       0,       0,       0,       0,       0,
+	/*  24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us  */
+	0,       0,       0,       0,       0,       0,       0,       0,
+	/*  32 sp    33  !    34  "    35  #    36  $    37  %    38  &    39  '  */
+	0,      '!',      0,      '#',     '$',     '%',     '&',    '\'',
+	/*  40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /  */
+	0,       0,      '*',     '+',      0,      '-',     '.',      0,
+	/*  48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7  */
+	'0',     '1',     '2',     '3',     '4',     '5',     '6',     '7',
+	/*  56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?  */
+	'8',     '9',      0,       0,       0,       0,       0,       0,
+	/*  64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G  */
+	0,      'a',     'b',     'c',     'd',     'e',     'f',     'g',
+	/*  72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O  */
+	'h',     'i',     'j',     'k',     'l',     'm',     'n',     'o',
+	/*  80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W  */
+	'p',     'q',     'r',     's',     't',     'u',     'v',     'w',
+	/*  88  X    89  Y    90  Z    91  [    92  \    93  ]    94  ^    95  _  */
+	'x',     'y',     'z',      0,       0,       0,      '^',     '_',
+	/*  96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g  */
+	'`',     'a',     'b',     'c',     'd',     'e',     'f',     'g',
+	/* 104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o  */
+	'h',     'i',     'j',     'k',     'l',     'm',     'n',     'o',
+	/* 112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w  */
+	'p',     'q',     'r',     's',     't',     'u',     'v',     'w',
+	/* 120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del */
+	'x',     'y',     'z',      0,      '|',      0,      '~',       0 };
+
+
+static const int8_t unhex[256] =
+{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+	,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+		,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+		, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1
+		,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
+		,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+		,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
+		,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+};
+
+
+#if HTTP_PARSER_STRICT
+# define T(v) 0
+#else
+# define T(v) v
+#endif
+
+
+static const uint8_t normal_url_char[32] = {
+	/*   0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel  */
+	0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
+	/*   8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si   */
+	0    | T(2)   |   0    |   0    | T(16)  |   0    |   0    |   0,
+	/*  16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb */
+	0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
+	/*  24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us  */
+	0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
+	/*  32 sp    33  !    34  "    35  #    36  $    37  %    38  &    39  '  */
+	0    |   2    |   4    |   0    |   16   |   32   |   64   |  128,
+	/*  40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/*  48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/*  56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |   0,
+	/*  64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/*  72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/*  80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/*  88  X    89  Y    90  Z    91  [    92  \    93  ]    94  ^    95  _  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/*  96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/* 104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/* 112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w  */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
+	/* 120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del */
+	1    |   2    |   4    |   8    |   16   |   32   |   64   |   0, };
+
+#undef T
+
+enum state
+{ 
+	s_dead = 1,
+	s_start_req_or_res,
+	s_res_or_resp_H,
+	s_start_res,
+	s_res_H,
+	s_res_HT,
+	s_res_HTT,
+	s_res_HTTP,
+	s_res_first_http_major,
+	s_res_http_major,
+	s_res_first_http_minor,
+	s_res_http_minor,
+	s_res_first_status_code,
+	s_res_status_code,
+	s_res_status_start,
+	s_res_status,
+	s_res_line_almost_done,
+	s_start_req,
+	s_req_method,
+	s_req_spaces_before_url,
+	s_req_schema,
+	s_req_schema_slash,
+	s_req_schema_slash_slash,
+	s_req_server_start,
+	s_req_server,
+	s_req_server_with_at,
+	s_req_path,
+	s_req_query_string_start,
+	s_req_query_string,
+	s_req_fragment_start,
+	s_req_fragment,
+	s_req_http_start,
+	s_req_http_H,
+	s_req_http_HT,
+	s_req_http_HTT,
+	s_req_http_HTTP,
+	s_req_first_http_major,
+	s_req_http_major,
+	s_req_first_http_minor,
+	s_req_http_minor,
+	s_req_line_almost_done,
+	s_header_field_start,
+	s_header_field,
+	s_header_value_discard_ws,
+	s_header_value_discard_ws_almost_done,
+	s_header_value_discard_lws,
+	s_header_value_start,
+	s_header_value,
+	s_header_value_lws,
+	s_header_almost_done,
+	s_chunk_size_start,
+	s_chunk_size,
+	s_chunk_parameters,
+	s_chunk_size_almost_done,
+	s_headers_almost_done,
+	s_headers_done,
+	s_chunk_data,
+	s_chunk_data_almost_done,
+	s_chunk_data_done,
+	s_body_identity,
+	s_body_identity_eof,
+	s_message_done,
+};
+
+
+#define PARSING_HEADER(state) (state <= s_headers_done)
+
+
+enum header_states
+{ 
+	h_general = 0,
+	h_C, 
+	h_CO,
+	h_CON,
+	h_matching_connection,
+	h_matching_proxy_connection,
+	h_matching_content_length,
+	h_matching_transfer_encoding,
+	h_matching_upgrade,
+
+	h_connection,
+	h_content_length,
+	h_transfer_encoding,
+	h_upgrade,
+
+	h_matching_transfer_encoding_chunked,
+	h_matching_connection_token_start,
+	h_matching_connection_keep_alive,
+	h_matching_connection_close,
+	h_matching_connection_upgrade,
+	h_matching_connection_token,
+
+	h_transfer_encoding_chunked,
+	h_connection_keep_alive,
+	h_connection_close,
+	h_connection_upgrade,
+};
+
+enum http_host_state
+{
+	s_http_host_dead = 1,
+	s_http_userinfo_start,
+	s_http_userinfo,
+	s_http_host_start,
+	s_http_host_v6_start,
+	s_http_host,
+	s_http_host_v6,
+	s_http_host_v6_end,
+	s_http_host_v6_zone_start,
+	s_http_host_v6_zone,
+	s_http_host_port_start,
+	s_http_host_port,
+};
+
+/* Macros for character classes; depends on strict-mode  */
+#define CR                  '\r'
+#define LF                  '\n'
+#define LOWER(c)            (unsigned char)(c | 0x20)
+#define IS_ALPHA(c)         (LOWER(c) >= 'a' && LOWER(c) <= 'z')
+#define IS_NUM(c)           ((c) >= '0' && (c) <= '9')
+#define IS_ALPHANUM(c)      (IS_ALPHA(c) || IS_NUM(c))
+#define IS_HEX(c)           (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f'))
+#define IS_MARK(c)          ((c) == '-' || (c) == '_' || (c) == '.' || \
+		(c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \
+		(c) == ')')
+#define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \
+		(c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \
+		(c) == '$' || (c) == ',')
+
+#define STRICT_TOKEN(c)     (tokens[(unsigned char)c])
+
+#if HTTP_PARSER_STRICT
+#define TOKEN(c)            (tokens[(unsigned char)c])
+#define IS_URL_CHAR(c)      (BIT_AT(normal_url_char, (unsigned char)c))
+#define IS_HOST_CHAR(c)     (IS_ALPHANUM(c) || (c) == '.' || (c) == '-')
+#else
+#define TOKEN(c)            ((c == ' ') ? ' ' : tokens[(unsigned char)c])
+#define IS_URL_CHAR(c)                                                         \
+	(BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80))
+#define IS_HOST_CHAR(c)                                                        \
+	(IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_')
+#endif
+
+
+#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res)
+
+
+#if HTTP_PARSER_STRICT
+# define STRICT_CHECK(cond)                                          \
+	do {                                                                 \
+		if (cond) {                                                        \
+			SET_ERRNO(HPE_STRICT);                                           \
+			goto error;                                                      \
+		}                                                                  \
+	} while (0)
+# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead)
+#else
+# define STRICT_CHECK(cond)
+# define NEW_MESSAGE() start_state
+#endif
+
+
+/* Map errno values to strings for human-readable output */
+#define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s },
+static struct {
+	const char *name;
+	const char *description;
+} http_strerror_tab[] = {
+	HTTP_ERRNO_MAP(HTTP_STRERROR_GEN)
+};
+#undef HTTP_STRERROR_GEN
+
+int http_message_needs_eof(const http_parser *parser);
+
+static enum state
+parse_url_char(enum state s, const char ch)
+{
+	if (ch == ' ' || ch == '\r' || ch == '\n') {
+		return s_dead;
+	}
+
+#if HTTP_PARSER_STRICT
+	if (ch == '\t' || ch == '\f') {
+		return s_dead;
+	}
+#endif
+
+	switch (s) {
+		case s_req_spaces_before_url:
+			if (ch == '/' || ch == '*') {
+				return s_req_path;
+			}
+
+			if (IS_ALPHA(ch)) {
+				return s_req_schema;
+			}
+
+			break;
+
+		case s_req_schema:
+			if (IS_ALPHA(ch)) {
+				return s;
+			}
+
+			if (ch == ':') {
+				return s_req_schema_slash;
+			}
+
+			break;
+
+		case s_req_schema_slash:
+			if (ch == '/') {
+				return s_req_schema_slash_slash;
+			}
+
+			break;
+
+		case s_req_schema_slash_slash:
+			if (ch == '/') {
+				return s_req_server_start;
+			}
+
+			break;
+
+		case s_req_server_with_at:
+			if (ch == '@') {
+				return s_dead;
+			}
+		case s_req_server_start:
+		case s_req_server:
+			if (ch == '/') {
+				return s_req_path;
+			}
+
+			if (ch == '?') {
+				return s_req_query_string_start;
+			}
+
+			if (ch == '@') {
+				return s_req_server_with_at;
+			}
+
+			if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') {
+				return s_req_server;
+			}
+
+			break;
+
+		case s_req_path:
+			if (IS_URL_CHAR(ch)) {
+				return s;
+			}
+
+			switch (ch) {
+				case '?':
+					return s_req_query_string_start;
+
+				case '#':
+					return s_req_fragment_start;
+			}
+
+			break;
+
+		case s_req_query_string_start:
+		case s_req_query_string:
+			if (IS_URL_CHAR(ch)) {
+				return s_req_query_string;
+			}
+
+			switch (ch) {
+				case '?':
+					/* allow extra '?' in query string */
+					return s_req_query_string;
+
+				case '#':
+					return s_req_fragment_start;
+			}
+
+			break;
+
+		case s_req_fragment_start:
+			if (IS_URL_CHAR(ch)) {
+				return s_req_fragment;
+			}
+
+			switch (ch) {
+				case '?':
+					return s_req_fragment;
+
+				case '#':
+					return s;
+			}
+
+			break;
+
+		case s_req_fragment:
+			if (IS_URL_CHAR(ch)) {
+				return s;
+			}
+
+			switch (ch) {
+				case '?':
+				case '#':
+					return s;
+			}
+
+			break;
+
+		default:
+			break;
+	}
+
+	return s_dead;
+}
+
+size_t http_parser_execute (http_parser *parser,
+		const http_parser_settings *settings,
+		const char *data,
+		size_t len)
+{
+	char c, ch;
+	int8_t unhex_val;
+	const char *p = data;
+	const char *header_field_mark = 0;
+	const char *header_value_mark = 0;
+	const char *url_mark = 0;
+	const char *body_mark = 0;
+	const char *status_mark = 0;
+	enum state p_state = (enum state) parser->state;
+
+	if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
+		return 0;
+	}
+
+	if (len == 0) {
+		switch (CURRENT_STATE()) {
+			case s_body_identity_eof:
+				CALLBACK_NOTIFY_NOADVANCE(message_complete);
+				return 0;
+
+			case s_dead:
+			case s_start_req_or_res:
+			case s_start_res:
+			case s_start_req:
+				return 0;
+
+			default:
+				SET_ERRNO(HPE_INVALID_EOF_STATE);
+				return 1;
+		}
+	}
+
+	if (CURRENT_STATE() == s_header_field)
+		header_field_mark = data;
+	if (CURRENT_STATE() == s_header_value)
+		header_value_mark = data;
+	switch (CURRENT_STATE()) {
+		case s_req_path:
+		case s_req_schema:
+		case s_req_schema_slash:
+		case s_req_schema_slash_slash:
+		case s_req_server_start:
+		case s_req_server:
+		case s_req_server_with_at:
+		case s_req_query_string_start:
+		case s_req_query_string:
+		case s_req_fragment_start:
+		case s_req_fragment:
+			url_mark = data;
+			break;
+		case s_res_status:
+			status_mark = data;
+			break;
+		default:
+			break;
+	}
+
+	for (p=data; p != data + len; p++) {
+		ch = *p;
+
+		if (PARSING_HEADER(CURRENT_STATE()))
+			COUNT_HEADER_SIZE(1);
+
+reexecute:
+		switch (CURRENT_STATE()) {
+
+			case s_dead:
+				if (LIKELY(ch == CR || ch == LF))
+					break;
+
+				SET_ERRNO(HPE_CLOSED_CONNECTION);
+				goto error;
+
+			case s_start_req_or_res:
+				{
+					if (ch == CR || ch == LF)
+						break;
+					parser->flags = 0;
+					parser->content_length = ULLONG_MAX;
+
+					if (ch == 'H') {
+						UPDATE_STATE(s_res_or_resp_H);
+
+						CALLBACK_NOTIFY(message_begin);
+					} else {
+						parser->type = HTTP_REQUEST;
+						UPDATE_STATE(s_start_req);
+						REEXECUTE();
+					}
+
+					break;
+				}
+
+			case s_res_or_resp_H:
+				if (ch == 'T') {
+					parser->type = HTTP_RESPONSE;
+					UPDATE_STATE(s_res_HT);
+				} else {
+					if (UNLIKELY(ch != 'E')) {
+						SET_ERRNO(HPE_INVALID_CONSTANT);
+						goto error;
+					}
+
+					parser->type = HTTP_REQUEST;
+					parser->method = HTTP_HEAD;
+					parser->index = 2;
+					UPDATE_STATE(s_req_method);
+				}
+				break;
+
+			case s_start_res:
+				{
+					parser->flags = 0;
+					parser->content_length = ULLONG_MAX;
+
+					switch (ch) {
+						case 'H':
+							UPDATE_STATE(s_res_H);
+							break;
+
+						case CR:
+						case LF:
+							break;
+
+						default:
+							SET_ERRNO(HPE_INVALID_CONSTANT);
+							goto error;
+					}
+
+					CALLBACK_NOTIFY(message_begin);
+					break;
+				}
+
+			case s_res_H:
+				STRICT_CHECK(ch != 'T');
+				UPDATE_STATE(s_res_HT);
+				break;
+
+			case s_res_HT:
+				STRICT_CHECK(ch != 'T');
+				UPDATE_STATE(s_res_HTT);
+				break;
+
+			case s_res_HTT:
+				STRICT_CHECK(ch != 'P');
+				UPDATE_STATE(s_res_HTTP);
+				break;
+
+			case s_res_HTTP:
+				STRICT_CHECK(ch != '/');
+				UPDATE_STATE(s_res_first_http_major);
+				break;
+
+			case s_res_first_http_major:
+				if (UNLIKELY(ch < '0' || ch > '9')) {
+					SET_ERRNO(HPE_INVALID_VERSION);
+					goto error;
+				}
+
+				parser->http_major = ch - '0';
+				UPDATE_STATE(s_res_http_major);
+				break;
+
+			case s_res_http_major:
+				{
+					if (ch == '.') {
+						UPDATE_STATE(s_res_first_http_minor);
+						break;
+					}
+
+					if (!IS_NUM(ch)) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					parser->http_major *= 10;
+					parser->http_major += ch - '0';
+
+					if (UNLIKELY(parser->http_major > 999)) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					break;
+				}
+
+			case s_res_first_http_minor:
+				if (UNLIKELY(!IS_NUM(ch))) {
+					SET_ERRNO(HPE_INVALID_VERSION);
+					goto error;
+				}
+
+				parser->http_minor = ch - '0';
+				UPDATE_STATE(s_res_http_minor);
+				break;
+
+				/* minor HTTP version or end of request line */
+			case s_res_http_minor:
+				{
+					if (ch == ' ') {
+						UPDATE_STATE(s_res_first_status_code);
+						break;
+					}
+
+					if (UNLIKELY(!IS_NUM(ch))) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					parser->http_minor *= 10;
+					parser->http_minor += ch - '0';
+
+					if (UNLIKELY(parser->http_minor > 999)) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					break;
+				}
+
+			case s_res_first_status_code:
+				{
+					if (!IS_NUM(ch)) {
+						if (ch == ' ') {
+							break;
+						}
+
+						SET_ERRNO(HPE_INVALID_STATUS);
+						goto error;
+					}
+					parser->status_code = ch - '0';
+					UPDATE_STATE(s_res_status_code);
+					break;
+				}
+
+			case s_res_status_code:
+				{
+					if (!IS_NUM(ch)) {
+						switch (ch) {
+							case ' ':
+								UPDATE_STATE(s_res_status_start);
+								break;
+							case CR:
+								UPDATE_STATE(s_res_line_almost_done);
+								break;
+							case LF:
+								UPDATE_STATE(s_header_field_start);
+								break;
+							default:
+								SET_ERRNO(HPE_INVALID_STATUS);
+								goto error;
+						}
+						break;
+					}
+
+					parser->status_code *= 10;
+					parser->status_code += ch - '0';
+
+					if (UNLIKELY(parser->status_code > 999)) {
+						SET_ERRNO(HPE_INVALID_STATUS);
+						goto error;
+					}
+
+					break;
+				}
+
+			case s_res_status_start:
+				{
+					if (ch == CR) {
+						UPDATE_STATE(s_res_line_almost_done);
+						break;
+					}
+
+					if (ch == LF) {
+						UPDATE_STATE(s_header_field_start);
+						break;
+					}
+
+					MARK(status);
+					UPDATE_STATE(s_res_status);
+					parser->index = 0;
+					break;
+				}
+
+			case s_res_status:
+				if (ch == CR) {
+					UPDATE_STATE(s_res_line_almost_done);
+					CALLBACK_DATA(status);
+					break;
+				}
+
+				if (ch == LF) {
+					UPDATE_STATE(s_header_field_start);
+					CALLBACK_DATA(status);
+					break;
+				}
+
+				break;
+
+			case s_res_line_almost_done:
+				STRICT_CHECK(ch != LF);
+				UPDATE_STATE(s_header_field_start);
+				break;
+
+			case s_start_req:
+				{
+					if (ch == CR || ch == LF)
+						break;
+					parser->flags = 0;
+					parser->content_length = ULLONG_MAX;
+
+					if (UNLIKELY(!IS_ALPHA(ch))) {
+						SET_ERRNO(HPE_INVALID_METHOD);
+						goto error;
+					}
+
+					parser->method = (enum http_method) 0;
+					parser->index = 1;
+					switch (ch) {
+						case 'A': parser->method = HTTP_ACL; break;
+						case 'B': parser->method = HTTP_BIND; break;
+						case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break;
+						case 'D': parser->method = HTTP_DELETE; break;
+						case 'G': parser->method = HTTP_GET; break;
+						case 'H': parser->method = HTTP_HEAD; break;
+						case 'L': parser->method = HTTP_LOCK; break;
+						case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break;
+						case 'N': parser->method = HTTP_NOTIFY; break;
+						case 'O': parser->method = HTTP_OPTIONS; break;
+						case 'P': parser->method = HTTP_POST;
+							  /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */
+							  break;
+						case 'R': parser->method = HTTP_REPORT; /* or REBIND */ break;
+						case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break;
+						case 'T': parser->method = HTTP_TRACE; break;
+						case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND */ break;
+						default:
+							  SET_ERRNO(HPE_INVALID_METHOD);
+							  goto error;
+					}
+					UPDATE_STATE(s_req_method);
+
+					CALLBACK_NOTIFY(message_begin);
+
+					break;
+				}
+
+			case s_req_method:
+				{
+					const char *matcher;
+					if (UNLIKELY(ch == '\0')) {
+						SET_ERRNO(HPE_INVALID_METHOD);
+						goto error;
+					}
+
+					matcher = method_strings[parser->method];
+					if (ch == ' ' && matcher[parser->index] == '\0') {
+						UPDATE_STATE(s_req_spaces_before_url);
+					} else if (ch == matcher[parser->index]) {
+						; /* nada */
+					} else if (parser->method == HTTP_CONNECT) {
+						if (parser->index == 1 && ch == 'H') {
+							parser->method = HTTP_CHECKOUT;
+						} else if (parser->index == 2  && ch == 'P') {
+							parser->method = HTTP_COPY;
+						} else {
+							SET_ERRNO(HPE_INVALID_METHOD);
+							goto error;
+						}
+					} else if (parser->method == HTTP_MKCOL) {
+						if (parser->index == 1 && ch == 'O') {
+							parser->method = HTTP_MOVE;
+						} else if (parser->index == 1 && ch == 'E') {
+							parser->method = HTTP_MERGE;
+						} else if (parser->index == 1 && ch == '-') {
+							parser->method = HTTP_MSEARCH;
+						} else if (parser->index == 2 && ch == 'A') {
+							parser->method = HTTP_MKACTIVITY;
+						} else if (parser->index == 3 && ch == 'A') {
+							parser->method = HTTP_MKCALENDAR;
+						} else {
+							SET_ERRNO(HPE_INVALID_METHOD);
+							goto error;
+						}
+					} else if (parser->method == HTTP_SUBSCRIBE) {
+						if (parser->index == 1 && ch == 'E') {
+							parser->method = HTTP_SEARCH;
+						} else {
+							SET_ERRNO(HPE_INVALID_METHOD);
+							goto error;
+						}
+					} else if (parser->method == HTTP_REPORT) {
+						if (parser->index == 2 && ch == 'B') {
+							parser->method = HTTP_REBIND;
+						} else {
+							SET_ERRNO(HPE_INVALID_METHOD);
+							goto error;
+						}
+					} else if (parser->index == 1 && parser->method == HTTP_POST) {
+						if (ch == 'R') {
+							parser->method = HTTP_PROPFIND;
+						} else if (ch == 'U') {
+							parser->method = HTTP_PUT;
+						} else if (ch == 'A') {
+							parser->method = HTTP_PATCH;
+						} else {
+							SET_ERRNO(HPE_INVALID_METHOD);
+							goto error;
+						}
+					} else if (parser->index == 2) {
+						if (parser->method == HTTP_PUT) {
+							if (ch == 'R') {
+								parser->method = HTTP_PURGE;
+							} else {
+								SET_ERRNO(HPE_INVALID_METHOD);
+								goto error;
+							}
+						} else if (parser->method == HTTP_UNLOCK) {
+							if (ch == 'S') {
+								parser->method = HTTP_UNSUBSCRIBE;
+							} else if(ch == 'B') {
+								parser->method = HTTP_UNBIND;
+							} else {
+								SET_ERRNO(HPE_INVALID_METHOD);
+								goto error;
+							}
+						} else {
+							SET_ERRNO(HPE_INVALID_METHOD);
+							goto error;
+						}
+					} else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') {
+						parser->method = HTTP_PROPPATCH;
+					} else {
+						SET_ERRNO(HPE_INVALID_METHOD);
+						goto error;
+					}
+
+					++parser->index;
+					break;
+				}
+
+			case s_req_spaces_before_url:
+				{
+					if (ch == ' ') break;
+
+					MARK(url);
+					if (parser->method == HTTP_CONNECT) {
+						UPDATE_STATE(s_req_server_start);
+					}
+
+					UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
+					if (UNLIKELY(CURRENT_STATE() == s_dead)) {
+						SET_ERRNO(HPE_INVALID_URL);
+						goto error;
+					}
+
+					break;
+				}
+
+			case s_req_schema:
+			case s_req_schema_slash:
+			case s_req_schema_slash_slash:
+			case s_req_server_start:
+				{
+					switch (ch) {
+						case ' ':
+						case CR:
+						case LF:
+							SET_ERRNO(HPE_INVALID_URL);
+							goto error;
+						default:
+							UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
+							if (UNLIKELY(CURRENT_STATE() == s_dead)) {
+								SET_ERRNO(HPE_INVALID_URL);
+								goto error;
+							}
+					}
+
+					break;
+				}
+
+			case s_req_server:
+			case s_req_server_with_at:
+			case s_req_path:
+			case s_req_query_string_start:
+			case s_req_query_string:
+			case s_req_fragment_start:
+			case s_req_fragment:
+				{
+					switch (ch) {
+						case ' ':
+							UPDATE_STATE(s_req_http_start);
+							CALLBACK_DATA(url);
+							break;
+						case CR:
+						case LF:
+							parser->http_major = 0;
+							parser->http_minor = 9;
+							UPDATE_STATE((ch == CR) ?
+									s_req_line_almost_done :
+									s_header_field_start);
+							CALLBACK_DATA(url);
+							break;
+						default:
+							UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
+							if (UNLIKELY(CURRENT_STATE() == s_dead)) {
+								SET_ERRNO(HPE_INVALID_URL);
+								goto error;
+							}
+					}
+					break;
+				}
+
+			case s_req_http_start:
+				switch (ch) {
+					case 'H':
+						UPDATE_STATE(s_req_http_H);
+						break;
+					case ' ':
+						break;
+					default:
+						SET_ERRNO(HPE_INVALID_CONSTANT);
+						goto error;
+				}
+				break;
+
+			case s_req_http_H:
+				STRICT_CHECK(ch != 'T');
+				UPDATE_STATE(s_req_http_HT);
+				break;
+
+			case s_req_http_HT:
+				STRICT_CHECK(ch != 'T');
+				UPDATE_STATE(s_req_http_HTT);
+				break;
+
+			case s_req_http_HTT:
+				STRICT_CHECK(ch != 'P');
+				UPDATE_STATE(s_req_http_HTTP);
+				break;
+
+			case s_req_http_HTTP:
+				STRICT_CHECK(ch != '/');
+				UPDATE_STATE(s_req_first_http_major);
+				break;
+
+			case s_req_first_http_major:
+				if (UNLIKELY(ch < '1' || ch > '9')) {
+					SET_ERRNO(HPE_INVALID_VERSION);
+					goto error;
+				}
+
+				parser->http_major = ch - '0';
+				UPDATE_STATE(s_req_http_major);
+				break;
+
+			case s_req_http_major:
+				{
+					if (ch == '.') {
+						UPDATE_STATE(s_req_first_http_minor);
+						break;
+					}
+
+					if (UNLIKELY(!IS_NUM(ch))) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					parser->http_major *= 10;
+					parser->http_major += ch - '0';
+
+					if (UNLIKELY(parser->http_major > 999)) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					break;
+				}
+
+			case s_req_first_http_minor:
+				if (UNLIKELY(!IS_NUM(ch))) {
+					SET_ERRNO(HPE_INVALID_VERSION);
+					goto error;
+				}
+
+				parser->http_minor = ch - '0';
+				UPDATE_STATE(s_req_http_minor);
+				break;
+
+			case s_req_http_minor:
+				{
+					if (ch == CR) {
+						UPDATE_STATE(s_req_line_almost_done);
+						break;
+					}
+
+					if (ch == LF) {
+						UPDATE_STATE(s_header_field_start);
+						break;
+					}
+
+					if (UNLIKELY(!IS_NUM(ch))) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					parser->http_minor *= 10;
+					parser->http_minor += ch - '0';
+
+					if (UNLIKELY(parser->http_minor > 999)) {
+						SET_ERRNO(HPE_INVALID_VERSION);
+						goto error;
+					}
+
+					break;
+				}
+
+			case s_req_line_almost_done:
+				{
+					if (UNLIKELY(ch != LF)) {
+						SET_ERRNO(HPE_LF_EXPECTED);
+						goto error;
+					}
+
+					UPDATE_STATE(s_header_field_start);
+					break;
+				}
+
+			case s_header_field_start:
+				{
+					if (ch == CR) {
+						UPDATE_STATE(s_headers_almost_done);
+						break;
+					}
+
+					if (ch == LF) {
+						UPDATE_STATE(s_headers_almost_done);
+						REEXECUTE();
+					}
+
+					c = TOKEN(ch);
+
+					if (UNLIKELY(!c)) {
+						SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
+						goto error;
+					}
+
+					MARK(header_field);
+
+					parser->index = 0;
+					UPDATE_STATE(s_header_field);
+
+					switch (c) {
+						case 'c':
+							parser->header_state = h_C;
+							break;
+
+						case 'p':
+							parser->header_state = h_matching_proxy_connection;
+							break;
+
+						case 't':
+							parser->header_state = h_matching_transfer_encoding;
+							break;
+
+						case 'u':
+							parser->header_state = h_matching_upgrade;
+							break;
+
+						default:
+							parser->header_state = h_general;
+							break;
+					}
+					break;
+				}
+
+			case s_header_field:
+				{
+					const char* start = p;
+					for (; p != data + len; p++) {
+						ch = *p;
+						c = TOKEN(ch);
+
+						if (!c)
+							break;
+
+						switch (parser->header_state) {
+							case h_general:
+								break;
+
+							case h_C:
+								parser->index++;
+								parser->header_state = (c == 'o' ? h_CO : h_general);
+								break;
+
+							case h_CO:
+								parser->index++;
+								parser->header_state = (c == 'n' ? h_CON : h_general);
+								break;
+
+							case h_CON:
+								parser->index++;
+								switch (c) {
+									case 'n':
+										parser->header_state = h_matching_connection;
+										break;
+									case 't':
+										parser->header_state = h_matching_content_length;
+										break;
+									default:
+										parser->header_state = h_general;
+										break;
+								}
+								break;
+
+							case h_matching_connection:
+								parser->index++;
+								if (parser->index > sizeof(CONNECTION)-1
+										|| c != CONNECTION[parser->index]) {
+									parser->header_state = h_general;
+								} else if (parser->index == sizeof(CONNECTION)-2) {
+									parser->header_state = h_connection;
+								}
+								break;
+
+							case h_matching_proxy_connection:
+								parser->index++;
+								if (parser->index > sizeof(PROXY_CONNECTION)-1
+										|| c != PROXY_CONNECTION[parser->index]) {
+									parser->header_state = h_general;
+								} else if (parser->index == sizeof(PROXY_CONNECTION)-2) {
+									parser->header_state = h_connection;
+								}
+								break;
+
+							case h_matching_content_length:
+								parser->index++;
+								if (parser->index > sizeof(CONTENT_LENGTH)-1
+										|| c != CONTENT_LENGTH[parser->index]) {
+									parser->header_state = h_general;
+								} else if (parser->index == sizeof(CONTENT_LENGTH)-2) {
+									parser->header_state = h_content_length;
+								}
+								break;
+
+							case h_matching_transfer_encoding:
+								parser->index++;
+								if (parser->index > sizeof(TRANSFER_ENCODING)-1
+										|| c != TRANSFER_ENCODING[parser->index]) {
+									parser->header_state = h_general;
+								} else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
+									parser->header_state = h_transfer_encoding;
+								}
+								break;
+
+							case h_matching_upgrade:
+								parser->index++;
+								if (parser->index > sizeof(UPGRADE)-1
+										|| c != UPGRADE[parser->index]) {
+									parser->header_state = h_general;
+								} else if (parser->index == sizeof(UPGRADE)-2) {
+									parser->header_state = h_upgrade;
+								}
+								break;
+
+							case h_connection:
+							case h_content_length:
+							case h_transfer_encoding:
+							case h_upgrade:
+								if (ch != ' ') parser->header_state = h_general;
+								break;
+
+							default:
+								assert(0 && "Unknown header_state");
+								break;
+						}
+					}
+
+					COUNT_HEADER_SIZE(p - start);
+
+					if (p == data + len) {
+						--p;
+						break;
+					}
+
+					if (ch == ':') {
+						UPDATE_STATE(s_header_value_discard_ws);
+						CALLBACK_DATA(header_field);
+						break;
+					}
+
+					SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
+					goto error;
+				}
+
+			case s_header_value_discard_ws:
+				if (ch == ' ' || ch == '\t') break;
+
+				if (ch == CR) {
+					UPDATE_STATE(s_header_value_discard_ws_almost_done);
+					break;
+				}
+
+				if (ch == LF) {
+					UPDATE_STATE(s_header_value_discard_lws);
+					break;
+				}
+
+			case s_header_value_start:
+				{
+					MARK(header_value);
+
+					UPDATE_STATE(s_header_value);
+					parser->index = 0;
+
+					c = LOWER(ch);
+
+					switch (parser->header_state) {
+						case h_upgrade:
+							parser->flags |= F_UPGRADE;
+							parser->header_state = h_general;
+							break;
+
+						case h_transfer_encoding:
+							if ('c' == c) {
+								parser->header_state = h_matching_transfer_encoding_chunked;
+							} else {
+								parser->header_state = h_general;
+							}
+							break;
+
+						case h_content_length:
+							if (UNLIKELY(!IS_NUM(ch))) {
+								SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+								goto error;
+							}
+
+							parser->content_length = ch - '0';
+							break;
+
+						case h_connection:
+							if (c == 'k') {
+								parser->header_state = h_matching_connection_keep_alive;
+							} else if (c == 'c') {
+								parser->header_state = h_matching_connection_close;
+							} else if (c == 'u') {
+								parser->header_state = h_matching_connection_upgrade;
+							} else {
+								parser->header_state = h_matching_connection_token;
+							}
+							break;
+							
+						case h_matching_connection_token_start:
+							break;
+
+						default:
+							parser->header_state = h_general;
+							break;
+					}
+					break;
+				}
+
+			case s_header_value:
+				{
+					const char* start = p;
+					enum header_states h_state = (enum header_states) parser->header_state;
+					for (; p != data + len; p++) {
+						ch = *p;
+						if (ch == CR) {
+							UPDATE_STATE(s_header_almost_done);
+							parser->header_state = h_state;
+							CALLBACK_DATA(header_value);
+							break;
+						}
+
+						if (ch == LF) {
+							UPDATE_STATE(s_header_almost_done);
+							COUNT_HEADER_SIZE(p - start);
+							parser->header_state = h_state;
+							CALLBACK_DATA_NOADVANCE(header_value);
+							REEXECUTE();
+						}
+
+						c = LOWER(ch);
+
+						switch (h_state) {
+							case h_general:
+								{
+									const char* p_cr;
+									const char* p_lf;
+									size_t limit = data + len - p;
+
+									limit = MIN(limit, HTTP_MAX_HEADER_SIZE);
+
+									p_cr = (const char*) memchr(p, CR, limit);
+									p_lf = (const char*) memchr(p, LF, limit);
+									if (p_cr != NULL) {
+										if (p_lf != NULL && p_cr >= p_lf)
+											p = p_lf;
+										else
+											p = p_cr;
+									} else if (UNLIKELY(p_lf != NULL)) {
+										p = p_lf;
+									} else {
+										p = data + len;
+									}
+									--p;
+
+									break;
+								}
+
+							case h_connection:
+							case h_transfer_encoding:
+								assert(0 && "Shouldn't get here.");
+								break;
+
+							case h_content_length:
+								{
+									uint64_t t;
+
+									if (ch == ' ') break;
+
+									if (UNLIKELY(!IS_NUM(ch))) {
+										SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+										parser->header_state = h_state;
+										goto error;
+									}
+
+									t = parser->content_length;
+									t *= 10;
+									t += ch - '0';
+
+									if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) {
+										SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+										parser->header_state = h_state;
+										goto error;
+									}
+
+									parser->content_length = t;
+									break;
+								}
+
+							case h_matching_transfer_encoding_chunked:
+								parser->index++;
+								if (parser->index > sizeof(CHUNKED)-1
+										|| c != CHUNKED[parser->index]) {
+									h_state = h_general;
+								} else if (parser->index == sizeof(CHUNKED)-2) {
+									h_state = h_transfer_encoding_chunked;
+								}
+								break;
+
+							case h_matching_connection_token_start:
+								if (c == 'k') {
+									h_state = h_matching_connection_keep_alive;
+								} else if (c == 'c') {
+									h_state = h_matching_connection_close;
+								} else if (c == 'u') {
+									h_state = h_matching_connection_upgrade;
+								} else if (STRICT_TOKEN(c)) {
+									h_state = h_matching_connection_token;
+								} else if (c == ' ' || c == '\t') {
+									/* Skip lws */
+								} else {
+									h_state = h_general;
+								}
+								break;
+
+							case h_matching_connection_keep_alive:
+								parser->index++;
+								if (parser->index > sizeof(KEEP_ALIVE)-1
+										|| c != KEEP_ALIVE[parser->index]) {
+									h_state = h_matching_connection_token;
+								} else if (parser->index == sizeof(KEEP_ALIVE)-2) {
+									h_state = h_connection_keep_alive;
+								}
+								break;
+
+							case h_matching_connection_close:
+								parser->index++;
+								if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) {
+									h_state = h_matching_connection_token;
+								} else if (parser->index == sizeof(CLOSE)-2) {
+									h_state = h_connection_close;
+								}
+								break;
+
+							case h_matching_connection_upgrade:
+								parser->index++;
+								if (parser->index > sizeof(UPGRADE) - 1 ||
+										c != UPGRADE[parser->index]) {
+									h_state = h_matching_connection_token;
+								} else if (parser->index == sizeof(UPGRADE)-2) {
+									h_state = h_connection_upgrade;
+								}
+								break;
+
+							case h_matching_connection_token:
+								if (ch == ',') {
+									h_state = h_matching_connection_token_start;
+									parser->index = 0;
+								}
+								break;
+
+							case h_transfer_encoding_chunked:
+								if (ch != ' ') h_state = h_general;
+								break;
+
+							case h_connection_keep_alive:
+							case h_connection_close:
+							case h_connection_upgrade:
+								if (ch == ',') {
+									if (h_state == h_connection_keep_alive) {
+										parser->flags |= F_CONNECTION_KEEP_ALIVE;
+									} else if (h_state == h_connection_close) {
+										parser->flags |= F_CONNECTION_CLOSE;
+									} else if (h_state == h_connection_upgrade) {
+										parser->flags |= F_CONNECTION_UPGRADE;
+									}
+									h_state = h_matching_connection_token_start;
+									parser->index = 0;
+								} else if (ch != ' ') {
+									h_state = h_matching_connection_token;
+								}
+								break;
+
+							default:
+								UPDATE_STATE(s_header_value);
+								h_state = h_general;
+								break;
+						}
+					}
+					parser->header_state = h_state;
+
+					COUNT_HEADER_SIZE(p - start);
+
+					if (p == data + len)
+						--p;
+					break;
+				}
+
+			case s_header_almost_done:
+				{
+					STRICT_CHECK(ch != LF);
+
+					UPDATE_STATE(s_header_value_lws);
+					break;
+				}
+
+			case s_header_value_lws:
+				{
+					if (ch == ' ' || ch == '\t') {
+						UPDATE_STATE(s_header_value_start);
+						REEXECUTE();
+					}
+
+					/* finished the header */
+					switch (parser->header_state) {
+						case h_connection_keep_alive:
+							parser->flags |= F_CONNECTION_KEEP_ALIVE;
+							break;
+						case h_connection_close:
+							parser->flags |= F_CONNECTION_CLOSE;
+							break;
+						case h_transfer_encoding_chunked:
+							parser->flags |= F_CHUNKED;
+							break;
+						case h_connection_upgrade:
+							parser->flags |= F_CONNECTION_UPGRADE;
+							break;
+						default:
+							break;
+					}
+
+					UPDATE_STATE(s_header_field_start);
+					REEXECUTE();
+				}
+
+			case s_header_value_discard_ws_almost_done:
+				{
+					STRICT_CHECK(ch != LF);
+					UPDATE_STATE(s_header_value_discard_lws);
+					break;
+				}
+
+			case s_header_value_discard_lws:
+				{
+					if (ch == ' ' || ch == '\t') {
+						UPDATE_STATE(s_header_value_discard_ws);
+						break;
+					} else {
+						switch (parser->header_state) {
+							case h_connection_keep_alive:
+								parser->flags |= F_CONNECTION_KEEP_ALIVE;
+								break;
+							case h_connection_close:
+								parser->flags |= F_CONNECTION_CLOSE;
+								break;
+							case h_connection_upgrade:
+								parser->flags |= F_CONNECTION_UPGRADE;
+								break;
+							case h_transfer_encoding_chunked:
+								parser->flags |= F_CHUNKED;
+								break;
+							default:
+								break;
+						}
+						MARK(header_value);
+						UPDATE_STATE(s_header_field_start);
+						CALLBACK_DATA_NOADVANCE(header_value);
+						REEXECUTE();
+					}
+				}
+
+			case s_headers_almost_done:
+				{
+					STRICT_CHECK(ch != LF);
+
+					if (parser->flags & F_TRAILING) {
+						/* End of a chunked request */
+						UPDATE_STATE(s_message_done);
+						CALLBACK_NOTIFY_NOADVANCE(chunk_complete);
+						REEXECUTE();
+					}
+
+					UPDATE_STATE(s_headers_done);
+
+					parser->upgrade =
+						((parser->flags & (F_UPGRADE | F_CONNECTION_UPGRADE)) ==
+						 (F_UPGRADE | F_CONNECTION_UPGRADE) ||
+						 parser->method == HTTP_CONNECT);
+
+					if (settings->on_headers_complete) {
+						switch (settings->on_headers_complete(parser)) {
+							case 0:
+								break;
+
+							case 1:
+								parser->flags |= F_SKIPBODY;
+								break;
+
+							default:
+								SET_ERRNO(HPE_CB_headers_complete);
+								RETURN(p - data); /* Error */
+						}
+					}
+
+					if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
+						RETURN(p - data);
+					}
+
+					REEXECUTE();
+				}
+
+			case s_headers_done:
+				{
+					int hasBody;
+					STRICT_CHECK(ch != LF);
+
+					parser->nread = 0;
+
+					hasBody = parser->flags & F_CHUNKED ||
+						(parser->content_length > 0 && parser->content_length != ULLONG_MAX);
+					if (parser->upgrade && (parser->method == HTTP_CONNECT ||
+								(parser->flags & F_SKIPBODY) || !hasBody)) {
+						UPDATE_STATE(NEW_MESSAGE());
+						CALLBACK_NOTIFY(message_complete);
+						RETURN((p - data) + 1);
+					}
+
+					if (parser->flags & F_SKIPBODY) {
+						UPDATE_STATE(NEW_MESSAGE());
+						CALLBACK_NOTIFY(message_complete);
+					} else if (parser->flags & F_CHUNKED) {
+						UPDATE_STATE(s_chunk_size_start);
+					} else {
+						if (parser->content_length == 0) {
+							UPDATE_STATE(NEW_MESSAGE());
+							CALLBACK_NOTIFY(message_complete);
+						} else if (parser->content_length != ULLONG_MAX) {
+							UPDATE_STATE(s_body_identity);
+						} else {
+							if (!http_message_needs_eof(parser)) {
+								UPDATE_STATE(NEW_MESSAGE());
+								CALLBACK_NOTIFY(message_complete);
+							} else {
+								UPDATE_STATE(s_body_identity_eof);
+							}
+						}
+					}
+
+					break;
+				}
+
+			case s_body_identity:
+				{
+					uint64_t to_read = MIN(parser->content_length,
+							(uint64_t) ((data + len) - p));
+
+					assert(parser->content_length != 0
+							&& parser->content_length != ULLONG_MAX);
+					MARK(body);
+					parser->content_length -= to_read;
+					p += to_read - 1;
+
+					if (parser->content_length == 0) {
+						UPDATE_STATE(s_message_done);
+						CALLBACK_DATA_(body, p - body_mark + 1, p - data);
+						REEXECUTE();
+					}
+
+					break;
+				}
+			case s_body_identity_eof:
+				MARK(body);
+				p = data + len - 1;
+
+				break;
+
+			case s_message_done:
+				UPDATE_STATE(NEW_MESSAGE());
+				CALLBACK_NOTIFY(message_complete);
+				if (parser->upgrade) {
+					RETURN((p - data) + 1);
+				}
+				break;
+
+			case s_chunk_size_start:
+				{
+					assert(parser->nread == 1);
+					assert(parser->flags & F_CHUNKED);
+
+					unhex_val = unhex[(unsigned char)ch];
+					if (UNLIKELY(unhex_val == -1)) {
+						SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
+						goto error;
+					}
+
+					parser->content_length = unhex_val;
+					UPDATE_STATE(s_chunk_size);
+					break;
+				}
+
+			case s_chunk_size:
+				{
+					uint64_t t;
+
+					assert(parser->flags & F_CHUNKED);
+
+					if (ch == CR) {
+						UPDATE_STATE(s_chunk_size_almost_done);
+						break;
+					}
+
+					unhex_val = unhex[(unsigned char)ch];
+
+					if (unhex_val == -1) {
+						if (ch == ';' || ch == ' ') {
+							UPDATE_STATE(s_chunk_parameters);
+							break;
+						}
+
+						SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
+						goto error;
+					}
+
+					t = parser->content_length;
+					t *= 16;
+					t += unhex_val;
+
+					if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) {
+						SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+						goto error;
+					}
+
+					parser->content_length = t;
+					break;
+				}
+
+			case s_chunk_parameters:
+				{
+					assert(parser->flags & F_CHUNKED);
+					if (ch == CR) {
+						UPDATE_STATE(s_chunk_size_almost_done);
+						break;
+					}
+					break;
+				}
+
+			case s_chunk_size_almost_done:
+				{
+					assert(parser->flags & F_CHUNKED);
+					STRICT_CHECK(ch != LF);
+
+					parser->nread = 0;
+
+					if (parser->content_length == 0) {
+						parser->flags |= F_TRAILING;
+						UPDATE_STATE(s_header_field_start);
+					} else {
+						UPDATE_STATE(s_chunk_data);
+					}
+					CALLBACK_NOTIFY(chunk_header);
+					break;
+				}
+
+			case s_chunk_data:
+				{
+					uint64_t to_read = MIN(parser->content_length,
+							(uint64_t) ((data + len) - p));
+
+					assert(parser->flags & F_CHUNKED);
+					assert(parser->content_length != 0
+							&& parser->content_length != ULLONG_MAX);
+
+					MARK(body);
+					parser->content_length -= to_read;
+					p += to_read - 1;
+
+					if (parser->content_length == 0) {
+						UPDATE_STATE(s_chunk_data_almost_done);
+					}
+
+					break;
+				}
+
+			case s_chunk_data_almost_done:
+				assert(parser->flags & F_CHUNKED);
+				assert(parser->content_length == 0);
+				STRICT_CHECK(ch != CR);
+				UPDATE_STATE(s_chunk_data_done);
+				CALLBACK_DATA(body);
+				break;
+
+			case s_chunk_data_done:
+				assert(parser->flags & F_CHUNKED);
+				STRICT_CHECK(ch != LF);
+				parser->nread = 0;
+				UPDATE_STATE(s_chunk_size_start);
+				CALLBACK_NOTIFY(chunk_complete);
+				break;
+
+			default:
+				assert(0 && "unhandled state");
+				SET_ERRNO(HPE_INVALID_INTERNAL_STATE);
+				goto error;
+		}
+	}
+
+	assert(((header_field_mark ? 1 : 0) +
+				(header_value_mark ? 1 : 0) +
+				(url_mark ? 1 : 0)  +
+				(body_mark ? 1 : 0) +
+				(status_mark ? 1 : 0)) <= 1);
+
+	CALLBACK_DATA_NOADVANCE(header_field);
+	CALLBACK_DATA_NOADVANCE(header_value);
+	CALLBACK_DATA_NOADVANCE(url);
+	CALLBACK_DATA_NOADVANCE(body);
+	CALLBACK_DATA_NOADVANCE(status);
+
+	RETURN(len);
+
+error:
+	if (HTTP_PARSER_ERRNO(parser) == HPE_OK) {
+		SET_ERRNO(HPE_UNKNOWN);
+	}
+
+	RETURN(p - data);
+}
+
+int http_message_needs_eof (const http_parser *parser)
+{
+	if (parser->type == HTTP_REQUEST) {
+		return 0;
+	}
+
+	if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */
+			parser->status_code == 204 ||     /* No Content */
+			parser->status_code == 304 ||     /* Not Modified */
+			parser->flags & F_SKIPBODY) {     /* response to a HEAD request */
+		return 0;
+	}
+
+	if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) {
+		return 0;
+	}
+
+	return 1;
+}
+
+
+int http_should_keep_alive (const http_parser *parser)
+{
+	if (parser->http_major > 0 && parser->http_minor > 0) {
+		if (parser->flags & F_CONNECTION_CLOSE) {
+			return 0;
+		}
+	} else {
+		if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) {
+			return 0;
+		}
+	}
+
+	return !http_message_needs_eof(parser);
+}
+
+
+	const char *
+http_method_str (enum http_method m)
+{
+	return ELEM_AT(method_strings, m, "<unknown>");
+}
+
+
+	void
+http_parser_init (http_parser *parser, enum http_parser_type t)
+{
+	void *data = parser->data; /* preserve application data */
+	memset(parser, 0, sizeof(*parser));
+	parser->data = data;
+	parser->type = t;
+	parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res));
+	parser->http_errno = HPE_OK;
+}
+
+	void
+http_parser_settings_init(http_parser_settings *settings)
+{
+	memset(settings, 0, sizeof(*settings));
+}
+
+const char *
+http_errno_name(enum http_errno err) {
+	assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab));
+	return http_strerror_tab[err].name;
+}
+
+const char *
+http_errno_description(enum http_errno err) {
+	assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab));
+	return http_strerror_tab[err].description;
+}
+
+static enum http_host_state
+http_parse_host_char(enum http_host_state s, const char ch) {
+	switch(s) {
+		case s_http_userinfo:
+		case s_http_userinfo_start:
+			if (ch == '@') {
+				return s_http_host_start;
+			}
+
+			if (IS_USERINFO_CHAR(ch)) {
+				return s_http_userinfo;
+			}
+			break;
+
+		case s_http_host_start:
+			if (ch == '[') {
+				return s_http_host_v6_start;
+			}
+
+			if (IS_HOST_CHAR(ch)) {
+				return s_http_host;
+			}
+
+			break;
+
+		case s_http_host:
+			if (IS_HOST_CHAR(ch)) {
+				return s_http_host;
+			}
+
+			/* FALLTHROUGH */
+		case s_http_host_v6_end:
+			if (ch == ':') {
+				return s_http_host_port_start;
+			}
+
+			break;
+
+		case s_http_host_v6:
+			if (ch == ']') {
+				return s_http_host_v6_end;
+			}
+
+			/* FALLTHROUGH */
+		case s_http_host_v6_start:
+			if (IS_HEX(ch) || ch == ':' || ch == '.') {
+				return s_http_host_v6;
+			}
+
+			if (s == s_http_host_v6 && ch == '%') {
+				return s_http_host_v6_zone_start;
+			}
+			break;
+
+		case s_http_host_v6_zone:
+			if (ch == ']') {
+				return s_http_host_v6_end;
+			}
+
+			/* FALLTHROUGH */
+		case s_http_host_v6_zone_start:
+			if (IS_ALPHANUM(ch) || ch == '%' || ch == '.' || ch == '-' || ch == '_' ||
+					ch == '~') {
+				return s_http_host_v6_zone;
+			}
+			break;
+
+		case s_http_host_port:
+		case s_http_host_port_start:
+			if (IS_NUM(ch)) {
+				return s_http_host_port;
+			}
+
+			break;
+
+		default:
+			break;
+	}
+	return s_http_host_dead;
+}
+
+static int
+http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
+	enum http_host_state s;
+	size_t buflen = 0;
+	const char *p;
+
+	assert(u->field_set & (1 << UF_HOST));
+
+	buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len;
+
+	u->field_data[UF_HOST].len = 0;
+
+	s = found_at ? s_http_userinfo_start : s_http_host_start;
+
+	for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) {
+		enum http_host_state new_s = http_parse_host_char(s, *p);
+
+		if (new_s == s_http_host_dead) {
+			return 1;
+		}
+
+		switch(new_s) {
+			case s_http_host:
+				if (s != s_http_host) {
+					u->field_data[UF_HOST].off = p - buf;
+				}
+				u->field_data[UF_HOST].len++;
+				break;
+
+			case s_http_host_v6:
+				if (s != s_http_host_v6) {
+					u->field_data[UF_HOST].off = p - buf;
+				}
+				u->field_data[UF_HOST].len++;
+				break;
+
+			case s_http_host_v6_zone_start:
+			case s_http_host_v6_zone:
+				u->field_data[UF_HOST].len++;
+				break;
+
+			case s_http_host_port:
+				if (s != s_http_host_port) {
+					u->field_data[UF_PORT].off = p - buf;
+					u->field_data[UF_PORT].len = 0;
+					u->field_set |= (1 << UF_PORT);
+				}
+				u->field_data[UF_PORT].len++;
+				break;
+
+			case s_http_userinfo:
+				if (s != s_http_userinfo) {
+					u->field_data[UF_USERINFO].off = p - buf ;
+					u->field_data[UF_USERINFO].len = 0;
+					u->field_set |= (1 << UF_USERINFO);
+				}
+				u->field_data[UF_USERINFO].len++;
+				break;
+
+			default:
+				break;
+		}
+		s = new_s;
+	}
+
+	switch (s) {
+		case s_http_host_start:
+		case s_http_host_v6_start:
+		case s_http_host_v6:
+		case s_http_host_v6_zone_start:
+		case s_http_host_v6_zone:
+		case s_http_host_port_start:
+		case s_http_userinfo:
+		case s_http_userinfo_start:
+			return 1;
+		default:
+			break;
+	}
+
+	return 0;
+}
+
+int http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
+		struct http_parser_url *u)
+{
+	enum state s;
+	const char *p;
+	enum http_parser_url_fields uf, old_uf;
+	int found_at = 0;
+
+	u->port = u->field_set = 0;
+	s = is_connect ? s_req_server_start : s_req_spaces_before_url;
+	old_uf = UF_MAX;
+
+	for (p = buf; p < buf + buflen; p++) {
+		s = parse_url_char(s, *p);
+
+		/* Figure out the next field that we're operating on */
+		switch (s) {
+			case s_dead:
+				return 1;
+			case s_req_schema_slash:
+			case s_req_schema_slash_slash:
+			case s_req_server_start:
+			case s_req_query_string_start:
+			case s_req_fragment_start:
+				continue;
+
+			case s_req_schema:
+				uf = UF_SCHEMA;
+				break;
+
+			case s_req_server_with_at:
+				found_at = 1;
+				
+			case s_req_server:
+				uf = UF_HOST;
+				break;
+
+			case s_req_path:
+				uf = UF_PATH;
+				break;
+
+			case s_req_query_string:
+				uf = UF_QUERY;
+				break;
+
+			case s_req_fragment:
+				uf = UF_FRAGMENT;
+				break;
+
+			default:
+				assert(!"Unexpected state");
+				return 1;
+		}
+
+		if (uf == old_uf) {
+			u->field_data[uf].len++;
+			continue;
+		}
+
+		u->field_data[uf].off = p - buf;
+		u->field_data[uf].len = 1;
+
+		u->field_set |= (1 << uf);
+		old_uf = uf;
+	}
+
+	if ((u->field_set & (1 << UF_SCHEMA)) &&
+			(u->field_set & (1 << UF_HOST)) == 0) {
+		return 1;
+	}
+
+	if (u->field_set & (1 << UF_HOST)) {
+		if (http_parse_host(buf, u, found_at) != 0) {
+			return 1;
+		}
+	}
+
+	if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) {
+		return 1;
+	}
+
+	if (u->field_set & (1 << UF_PORT)) {
+		unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10);
+
+		if (v > 0xffff) {
+			return 1;
+		}
+
+		u->port = (uint16_t) v;
+	}
+
+	return 0;
+}
+
+void
+http_parser_pause(http_parser *parser, int paused) {
+	if (HTTP_PARSER_ERRNO(parser) == HPE_OK ||
+			HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) {
+		SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK);
+	} else {
+		assert(0 && "Attempting to pause parser in error state");
+	}
+}
+
+int
+http_body_is_final(const struct http_parser *parser) {
+	return parser->state == s_message_done;
+}
+
+unsigned long
+http_parser_version(void) {
+	return HTTP_PARSER_VERSION_MAJOR * 0x10000 |
+		HTTP_PARSER_VERSION_MINOR * 0x00100 |
+		HTTP_PARSER_VERSION_PATCH * 0x00001;
+}
diff --git a/src/lynq/lib/liblynq-protcl/http/src/lynq_msgq.c b/src/lynq/lib/liblynq-protcl/http/src/lynq_msgq.c
new file mode 100644
index 0000000..5005c18
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/http/src/lynq_msgq.c
@@ -0,0 +1,33 @@
+#include <sys/msg.h>

+#include <sys/ipc.h>

+#include <stdlib.h>

+#include <string.h>

+#include <stdio.h>

+#include "http/lynq_msgq.h"

+

+

+int lynq_msgq_init(char *pathname,  int create)

+{

+	key_t key = ftok(pathname, 66);

+	int queueId = msgget(key, IPC_CREAT | create);

+	if(queueId == -1)

+	{

+			//LYDBGLOG("[%s %d] create msg error \n", __FUNCTION__, __LINE__);

+			LYVERBLOG("+[http]: error num = %d\n", ERR_MSG);

+			return ERR_MSG;

+	}

+	

+	return queueId ;

+}

+

+int lynq_msgq_send(int queueId, struct mymesg *ckxmsg)

+{

+        if(msgsnd(queueId, ckxmsg, 512, 0) < 0)

+        {

+                //LYDBGLOG("[%s %d] send msg error \n", __FUNCTION__, __LINE__);

+		  		LYVERBLOG("+[http]: error num = %d\n", ERR_MSG);

+                return ERR_MSG;

+        }

+

+        return 0;

+}

diff --git a/src/lynq/lib/liblynq-protcl/include/ftp/lynq_ftp.h b/src/lynq/lib/liblynq-protcl/include/ftp/lynq_ftp.h
new file mode 100644
index 0000000..12e3f09
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/include/ftp/lynq_ftp.h
@@ -0,0 +1,171 @@
+#include<stdio.h>
+#include<sys/socket.h>
+#include<stdlib.h>
+#include<string.h>
+#include<strings.h>
+#include<unistd.h>
+#include<netinet/in.h>
+#include<netdb.h>
+#include<errno.h>
+#include<sys/types.h>
+#include<sys/stat.h>
+#include<fcntl.h>
+#include "liblog/liblog.h"
+#include "liblog/lynq_deflog.h"
+
+
+#define SERV_PORT 21
+#define MAXSIZE 1024
+//#define MAXBUF 1024
+#define FTP_FILE_TYPE_LEN 4
+#define FTP_MAX_ASCII_LEN 1024
+#define FTPSHMPATH "/"
+#define FTPSHMID  'K'
+
+
+int error;
+char errorbuf[10];
+
+#if 1
+/*log error info */
+
+#define FTP_NET_ERROR                  	31	//network
+#define FTP_DNS_ERROR                 	32	//DNS
+#define FTP_CONNECT_ERROR           	33	//connect
+#define FTP_TIMEROUT                    34	//time out
+#define FTP_SERVER_ERROR             	35	//server
+#define FTP_OPERATION_NOT_ALLOW         36	//operation not allow
+#define FTP_REPLAY_ERROR               	37	//replay
+#define FTP_USER_ERROR                 	38	//user
+#define FTP_PASSWORD_ERROR              39	//pwd
+#define FTP_TYPE_ERROR                 	40	//type
+#define FTP_REST_ERROR                 	41	//rest
+#define FTP_PASSIVE_ERROR              	42	//passive
+#define FTP_ACTIVE_ERROR               	43	//active
+#define FTP_OPERATE_ERROR              	44	//operate
+#define FTP_UPLOAD_ERROR               	45	//upload
+#define FTP_DOWNLOAD_ERROR              46	//download
+#define FTP_FILE_ACTION_ERROR	        47	//action error
+#define FTP_MANUAL_QUIT                	48	//manual quit
+#define FTP_ERROR_FLAG                 	49
+#define FTP_SOCK_ERROR                 	50	//socket error
+#define FTP_RCV_ERROR                 	51	//rcv error
+#define FTP_SEND_ERROR                 	52	//send error 
+#define FTP_CLOSE_ERROR                 53    //close error
+#define FTP_READ_ERROR                 	54    //read error
+#define FTP_WRITE_ERROR                 55    //write error
+#define FTP_LS_ERROR                 55    //ls error
+
+#endif
+
+#if 1
+/***********ftp return vauil******************/
+
+#define FTP_100_INIT_WAIT_LAST_CMD			100
+#define FTP_125_TRANSFER_START				125
+#define FTP_150_OPEN_DATA_CONNECT			150
+
+#define FTP_200_COMMAND_SUCCESSFUL			200
+#define FTP_213_FILE_STATUS				213
+#define FTP_220_SERVER_READY_FOR_NEW_USER		220
+#define FTP_221_CLOSE_CONTROL_CONNECT			221
+#define FTP_226_TRANSFER_COMPLATE			226
+#define FTP_227_ENTRY_PASV_MODE				227
+#define FTP_230_USER_LOGGED_IN				230
+#define FTP_250_REQUEST_FILE_ACTION_OK			250
+#define FTP_257_PATH_NAME				257
+
+
+#define FTP_331_NAMEOK_PASS_REQUIRE			331
+#define FTP_350_FILE_OPER_OK_WAIT_NEXT			350
+
+#define FTP_421_CONTROL_LINK_SHUTDOWN 			421
+#define FTP_425_CANNOT_OPEN_DATA_CONNECT		425
+
+
+#define FTP_500_COMMAND_ERROR				500
+#define FTP_501_PARAMETER_ERROR				501
+#define FTP_502_COMMAND_NOT_IMP				502
+#define FTP_503_BAD_SEQUENCE_OF_CMD			503
+
+#define FTP_530_CANNOT_LOG_IN				530
+#define FTP_532_NEED_ACCOUNT				532
+#define FTP_534_CANNOT_CONN_CAUSE_SSL			534
+#define FTP_550_FILE_CANT_FIND				550
+
+
+#endif
+
+typedef struct ftp_socket_info
+{
+	int id;
+	int index;
+	char protocol[10];
+	int  session;
+	char action[10];
+
+	int control_sockfd;
+	int portnum;//port num 1~65535
+	char is_pasv_mode[225];//0:initiative 1:pasv
+	char file_type[FTP_FILE_TYPE_LEN+1];//type "A" or "I"
+	char put_opt[FTP_FILE_TYPE_LEN+1];// "APPE", "STOU", "STOR"
+	int rest; //xu chuan wei zhi;
+	char sevname[FTP_MAX_ASCII_LEN + 1];//addr :192.168.1.89;
+	char username[FTP_MAX_ASCII_LEN + 1];//user
+	char pw[FTP_MAX_ASCII_LEN + 1];//password
+	char getfilename[FTP_MAX_ASCII_LEN + 1];//get file  name;
+	char getfilename_path[FTP_MAX_ASCII_LEN + 1];//get file path;
+	char putfilename[FTP_MAX_ASCII_LEN + 1];//put file name;
+	char putfilename_path[FTP_MAX_ASCII_LEN + 1];//put file path;
+	//char conmd[255];
+	char dir[1024];
+	char del_mkr_filename[1024];
+	char respond[1024];
+	int flag;
+	int flag1;
+	int modify_thread;
+	int add_thread;
+}lynq_ftp_socker_info;
+
+
+int control_sockfd;
+int login_yes;
+int f;
+char putpathname[225];
+char hoster[255];
+struct sockaddr_in servaddr;
+char rbuf[1024],rbuf1[1024],wbuf[1024],wbuf1[1024];
+int ftpshm_id;
+lynq_ftp_socker_info *FTP;
+
+int uartfd;
+int usbfd;
+//char BUF[1024];
+
+
+
+int  lynq_ftp_put(int sck,char *pUploadFileName_s);
+extern int lynq_ftp_login(lynq_ftp_socker_info *FTP);
+extern void zeromery(char *a,int len);
+extern char *itoa(int value, char *string, int radix);
+extern void lynq_ftp_pwd(int control_sockfd);
+extern int strtosrv(char *str);
+extern void lynq_ftp_get(int sck, char *pDownloadFileName, int session);
+extern void lynq_ftp_rest(int control_sockfd);
+extern int cliopen(char *hoster, int port);
+extern int lynq_ftp_download(lynq_ftp_socker_info* FTP);
+extern int lynq_ftp_up(lynq_ftp_socker_info* FTP);
+int lynq_ftp_ls(lynq_ftp_socker_info* FTP);
+void lynq_ftp_cd(lynq_ftp_socker_info* FTP);
+void lynq_ftp_creat_mkd(lynq_ftp_socker_info* FTP);
+void lynq_ftp_delete_mkd(lynq_ftp_socker_info* FTP);
+void ftp_list(int sockfd, int session);
+void lynq_ftp_quit(lynq_ftp_socker_info* FTP);
+void lynq_ftp_deletefile_mkd(lynq_ftp_socker_info* FTP);
+
+
+extern void init(lynq_ftp_socker_info* FTP);
+extern int lynq_ftpshm_create( void );
+extern lynq_ftp_socker_info *ftpshm_act(int shmid);
+extern void lynq_ftpshm_deact(lynq_ftp_socker_info *shm);
+extern void lynq_ftpshm_del(int shmid);
diff --git a/src/lynq/lib/liblynq-protcl/include/http/lynq_http.h b/src/lynq/lib/liblynq-protcl/include/http/lynq_http.h
new file mode 100644
index 0000000..455abc2
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/include/http/lynq_http.h
@@ -0,0 +1,185 @@
+#ifndef _LYNQ_HTTP_H_
+#define _LYNQ_HTTP_H_
+
+#define HTTP_API
+
+
+#include "lynq_http_parser.h"
+#include "lynq_msgq.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#include <time.h> 
+#include <ctype.h>
+#include <netdb.h>
+#include <strings.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+#define HTTP_INVALID_SOCKET -1
+#define HTTP_EINTR EINTR
+#define HTTP_EINPROGRESS EINPROGRESS
+#define HTTP_EWOULDBLOCK EWOULDBLOCK
+#define HTTP_EALREADY EALREADY
+
+#define free_member(member) if((member)) { free(member); (member) = NULL; }
+#define close_socket(fd) if(fd != HTTP_INVALID_SOCKET) { socket_close(fd); fd = HTTP_INVALID_SOCKET; }
+#define close_file(pf) if(pf != NULL) { fclose(pf); pf = NULL; }
+
+#define RECV_BUF_SIZE 4 * 1024
+
+#define socket_close close
+
+
+enum parser_statue_e { PARSERD_NONE = 0, PARSERD_FIELD, PARSERD_VALUE, PARSERD_BODY };
+
+enum proto_type_e { PROTO_HTTP = 0, PROTO_HTTPS };
+	typedef enum http_request_method_e 
+	{ 
+		M_GET = 0, 
+		M_POST, 
+		M_HEAD 
+	} http_request_method_e;
+
+	typedef enum http_connent_method_e 
+	{ 
+		M_CLOSE = 0, 
+		M_KEEP,
+	} http_connent_method_e;
+
+	enum http_error_e
+	{
+		ERR_OK = 0,
+
+		ERR_INVALID_PARAM,
+		ERR_OUT_MEMORY,
+		ERR_OPEN_FILE,
+		ERR_PARSE_REP,
+		ERR_URL_INVALID,
+		ERR_URL_INVALID_PROTO,
+		ERR_URL_INVALID_HOST,
+		ERR_URL_INVALID_IP,
+		ERR_URL_RESOLVED_HOST,
+		ERR_SOCKET_CREATE = 10,
+		ERR_SOCKET_SET_OPT,
+		ERR_SOCKET_NOBLOCKING,
+		ERR_SOCKET_CONNECT,
+		ERR_SOCKET_CONNECT_TIMEOUT,
+		ERR_SOCKET_SELECT,
+		ERR_SOCKET_WRITE,
+		ERR_SOCKET_READ,
+		ERR_SOCKET_TIMEOUT,
+		ERR_SOCKET_CLOSED,
+		ERR_SOCKET_GET_OPT = 20,
+		ERR_SSL_CREATE_CTX,
+		ERR_SSL_CREATE_SSL,
+		ERR_SSL_SET_FD,
+		ERR_SSL_CONNECT,
+		ERR_SSL_WRITE,
+		ERR_SSL_READ,
+		ERR_NOCERT,
+		ERR_MSG
+	};
+
+	struct lynq_http_client_t;
+	typedef struct lynq_http_client_t lynq_http_client_t;
+	typedef int (*data_recv_cb_t)( lynq_http_client_t* http, const char* data, int size, int total, void* user);
+
+ typedef int socket_t;
+
+ 
+ struct lynq_http_client_t
+ {
+	int index;
+
+	char protocol[10];
+	int  session;
+
+	char action[10];
+	char *data;
+	char *section;
+	int request_method;
+	int connent_method;
+	int sockfd;
+	int modify_thread;
+	int add_thread;
+
+	FILE* pf;
+	char* filename;
+	char* body;
+	char* redirect_url;
+	char* header_field;
+	char* header_value;
+
+	char* post_data;
+	char* url;
+	int post_data_len;
+	struct http_parser_url u;
+	char* user_header;
+	int user_header_len;
+	
+	http_parser_settings parser_setting;
+	struct http_parser parser;
+
+
+	char* user;
+	data_recv_cb_t recv_cb;
+	
+	unsigned long body_len;
+	unsigned long content_length;
+
+	enum http_request_method_e method;
+	enum http_connent_method_e conn_method;
+	enum proto_type_e proto_type;
+
+	unsigned short field_size;
+	unsigned short value_size;
+	unsigned short cur_field_size;
+	unsigned short cur_value_size;
+	SSL_CTX *ctx;
+	SSL *ssl;
+
+	socket_t fd; 
+	int timeout;
+	
+	short status_code;
+	char parser_statue;
+	char error_code;
+	unsigned cancel   : 1;
+	unsigned exit	  : 1;
+	unsigned download : 1;
+	unsigned redirect : 1;
+};
+
+
+int lynq_http_init(void);
+lynq_http_client_t* lynq_http_new();
+void lynq_http_destroy(lynq_http_client_t* http);
+int lynq_http_get_error_code(lynq_http_client_t* http);
+const char* lynq_http_sync_request(lynq_http_client_t* http, const char* url, http_request_method_e m, http_connent_method_e c_m);
+const char* lynq_http_sync_post_request(lynq_http_client_t* http, char* url, char* post_data, http_request_method_e m, http_connent_method_e c_m);
+int lynq_http_sync_download_file(lynq_http_client_t* http, char* url, char* filepath, http_request_method_e m, http_connent_method_e c_m);
+int lynq_http_set_data_recv_cb(lynq_http_client_t* http, data_recv_cb_t cb, void* user);
+int lynq_http_exit(lynq_http_client_t* http);
+int lynq_http_data_send(char *data);
+void *lynq_http_write_head_data(lynq_http_client_t* http);
+#ifdef _cplusplus
+}
+#endif
+#endif
+
diff --git a/src/lynq/lib/liblynq-protcl/include/http/lynq_http_parser.h b/src/lynq/lib/liblynq-protcl/include/http/lynq_http_parser.h
new file mode 100644
index 0000000..99d9f20
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/include/http/lynq_http_parser.h
@@ -0,0 +1,220 @@
+#ifndef _LYNQ_HTTP_PARSER_H_
+#define _LYNQ_HTTP_PARSER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HTTP_PARSER_VERSION_MAJOR 2
+#define HTTP_PARSER_VERSION_MINOR 5
+#define HTTP_PARSER_VERSION_PATCH 0
+#include <stddef.h>
+#include <stdint.h>
+#include "liblog/liblog.h"
+#include "liblog/lynq_deflog.h"
+
+
+
+#ifndef HTTP_PARSER_STRICT
+# define HTTP_PARSER_STRICT 1
+#endif
+
+#ifndef HTTP_MAX_HEADER_SIZE
+# define HTTP_MAX_HEADER_SIZE (80*1024)
+#endif
+
+	typedef struct http_parser http_parser;
+	typedef struct http_parser_settings http_parser_settings;
+
+	typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
+	typedef int (*http_cb) (http_parser*);
+
+
+	/* Request Methods */
+#define HTTP_METHOD_MAP(XX)         \
+	XX(0,  DELETE,      DELETE)       \
+	XX(1,  GET,         GET)          \
+	XX(2,  HEAD,        HEAD)         \
+	XX(3,  POST,        POST)         \
+	XX(4,  PUT,         PUT)          \
+	/* pathological */                \
+	XX(5,  CONNECT,     CONNECT)      \
+	XX(6,  OPTIONS,     OPTIONS)      \
+	XX(7,  TRACE,       TRACE)        \
+	/* WebDAV */                      \
+	XX(8,  COPY,        COPY)         \
+	XX(9,  LOCK,        LOCK)         \
+	XX(10, MKCOL,       MKCOL)        \
+	XX(11, MOVE,        MOVE)         \
+	XX(12, PROPFIND,    PROPFIND)     \
+	XX(13, PROPPATCH,   PROPPATCH)    \
+	XX(14, SEARCH,      SEARCH)       \
+	XX(15, UNLOCK,      UNLOCK)       \
+	XX(16, BIND,        BIND)         \
+	XX(17, REBIND,      REBIND)       \
+	XX(18, UNBIND,      UNBIND)       \
+	XX(19, ACL,         ACL)          \
+	/* subversion */                  \
+	XX(20, REPORT,      REPORT)       \
+	XX(21, MKACTIVITY,  MKACTIVITY)   \
+	XX(22, CHECKOUT,    CHECKOUT)     \
+	XX(23, MERGE,       MERGE)        \
+	/* upnp */                        \
+	XX(24, MSEARCH,     M-SEARCH)     \
+	XX(25, NOTIFY,      NOTIFY)       \
+	XX(26, SUBSCRIBE,   SUBSCRIBE)    \
+	XX(27, UNSUBSCRIBE, UNSUBSCRIBE)  \
+	/* RFC-5789 */                    \
+	XX(28, PATCH,       PATCH)        \
+	XX(29, PURGE,       PURGE)        \
+	/* CalDAV */                      \
+	XX(30, MKCALENDAR,  MKCALENDAR)   \
+
+	enum http_method
+	{
+#define XX(num, name, string) HTTP_##name = num,
+		HTTP_METHOD_MAP(XX)
+#undef XX
+	};
+
+
+	enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
+	enum flags
+	{ F_CHUNKED               = 1 << 0
+		, F_CONNECTION_KEEP_ALIVE = 1 << 1
+			, F_CONNECTION_CLOSE      = 1 << 2
+			, F_CONNECTION_UPGRADE    = 1 << 3
+			, F_TRAILING              = 1 << 4
+			, F_UPGRADE               = 1 << 5
+			, F_SKIPBODY              = 1 << 6
+	};
+
+#define HTTP_ERRNO_MAP(XX)                                           \
+	/* No error */                                                     \
+	XX(OK, "success")                                                  \
+	\
+	/* Callback-related errors */                                      \
+	XX(CB_message_begin, "the on_message_begin callback failed")       \
+	XX(CB_url, "the on_url callback failed")                           \
+	XX(CB_header_field, "the on_header_field callback failed")         \
+	XX(CB_header_value, "the on_header_value callback failed")         \
+	XX(CB_headers_complete, "the on_headers_complete callback failed") \
+	XX(CB_body, "the on_body callback failed")                         \
+	XX(CB_message_complete, "the on_message_complete callback failed") \
+	XX(CB_status, "the on_status callback failed")                     \
+	XX(CB_chunk_header, "the on_chunk_header callback failed")         \
+	XX(CB_chunk_complete, "the on_chunk_complete callback failed")     \
+	\
+	/* Parsing-related errors */                                       \
+	XX(INVALID_EOF_STATE, "stream ended at an unexpected time")        \
+	XX(HEADER_OVERFLOW,                                                \
+			"too many header bytes seen; overflow detected")                \
+	XX(CLOSED_CONNECTION,                                              \
+			"data received after completed connection: close message")      \
+	XX(INVALID_VERSION, "invalid HTTP version")                        \
+	XX(INVALID_STATUS, "invalid HTTP status code")                     \
+	XX(INVALID_METHOD, "invalid HTTP method")                          \
+	XX(INVALID_URL, "invalid URL")                                     \
+	XX(INVALID_HOST, "invalid host")                                   \
+	XX(INVALID_PORT, "invalid port")                                   \
+	XX(INVALID_PATH, "invalid path")                                   \
+	XX(INVALID_QUERY_STRING, "invalid query string")                   \
+	XX(INVALID_FRAGMENT, "invalid fragment")                           \
+	XX(LF_EXPECTED, "LF character expected")                           \
+	XX(INVALID_HEADER_TOKEN, "invalid character in header")            \
+	XX(INVALID_CONTENT_LENGTH,                                         \
+			"invalid character in content-length header")                   \
+	XX(INVALID_CHUNK_SIZE,                                             \
+			"invalid character in chunk size header")                       \
+	XX(INVALID_CONSTANT, "invalid constant string")                    \
+	XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
+	XX(STRICT, "strict mode assertion failed")                         \
+	XX(PAUSED, "parser is paused")                                     \
+	XX(UNKNOWN, "an unknown error occurred")
+
+#define HTTP_ERRNO_GEN(n, s) HPE_##n,
+	enum http_errno {
+		HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
+	};
+#undef HTTP_ERRNO_GEN
+
+#define HTTP_PARSER_ERRNO(p)            ((enum http_errno) (p)->http_errno)
+
+	struct http_parser {
+		unsigned int type : 2;         /* enum http_parser_type */
+		unsigned int flags : 7;        /* F_* values from 'flags' enum; semi-public */
+		unsigned int state : 7;        /* enum state from http_parser.c */
+		unsigned int header_state : 8; /* enum header_state from http_parser.c */
+		unsigned int index : 8;        /* index into current matcher */
+
+		uint32_t nread;          /* # bytes read in various scenarios */
+		uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
+
+		unsigned short http_major;
+		unsigned short http_minor;
+		unsigned int status_code : 16;
+		unsigned int method : 8;
+		unsigned int http_errno : 7;
+		unsigned int upgrade : 1;
+		void *data;
+	};
+
+
+	struct http_parser_settings {
+		http_cb      on_message_begin;
+		http_data_cb on_url;
+		http_data_cb on_status;
+		http_data_cb on_header_field;
+		http_data_cb on_header_value;
+		http_cb      on_headers_complete;
+		http_data_cb on_body;
+		http_cb      on_message_complete;
+		http_cb      on_chunk_header;
+		http_cb      on_chunk_complete;
+	};
+
+
+	enum http_parser_url_fields
+	{ 
+		UF_SCHEMA           = 0,
+		UF_HOST             = 1,
+		UF_PORT             = 2,
+		UF_PATH             = 3,
+		UF_QUERY            = 4,
+		UF_FRAGMENT         = 5,
+		UF_USERINFO         = 6,
+		UF_MAX              = 7,
+	};
+
+	struct http_parser_url {
+		uint16_t field_set;           /* Bitmask of (1 << UF_*) values */
+		uint16_t port;                /* Converted UF_PORT string */
+
+		struct {
+			uint16_t off;               /* Offset into buffer in which field starts */
+			uint16_t len;               /* Length of run in buffer */
+		} field_data[UF_MAX];
+	};
+
+	unsigned long http_parser_version(void);
+	void http_parser_init(http_parser *parser, enum http_parser_type type);
+	void http_parser_settings_init(http_parser_settings *settings);
+	size_t http_parser_execute(http_parser *parser,
+			const http_parser_settings *settings,
+			const char *data,
+			size_t len);
+
+	int http_should_keep_alive(const http_parser *parser);
+	const char *http_method_str(enum http_method m);
+	const char *http_errno_name(enum http_errno err);
+	const char *http_errno_description(enum http_errno err);
+	int http_parser_parse_url(const char *buf, size_t buflen,
+			int is_connect,
+			struct http_parser_url *u);
+	void http_parser_pause(http_parser *parser, int paused);
+	int http_body_is_final(const http_parser *parser);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/lynq/lib/liblynq-protcl/include/http/lynq_msgq.h b/src/lynq/lib/liblynq-protcl/include/http/lynq_msgq.h
new file mode 100644
index 0000000..784e077
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/include/http/lynq_msgq.h
@@ -0,0 +1,19 @@
+#ifndef _LYNQ_MSGQ_H_

+#define _LYNQ_MSGQ_H_

+

+#include <sys/msg.h>

+#include <sys/ipc.h>

+#include "liblog/liblog.h"

+#include "liblog/lynq_deflog.h"

+#include "http/lynq_http.h"

+

+struct mymesg{

+	long int mtype;

+	char mtext[512];

+};

+

+int lynq_msgq_init(char *pathname,  int create);

+int lynq_msgq_send(int queueId, struct mymesg *ckxmsg);

+

+#endif

+

diff --git a/src/lynq/lib/liblynq-protcl/include/lynq_mqtt/lynq_mqtt.h b/src/lynq/lib/liblynq-protcl/include/lynq_mqtt/lynq_mqtt.h
new file mode 100644
index 0000000..0422faa
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/include/lynq_mqtt/lynq_mqtt.h
@@ -0,0 +1,70 @@
+#ifndef __LYNQ_MQTT_H__

+#define __LYNQ_MQTT_H__

+#include <mosquitto.h>

+

+

+struct mqtt_set_will{

+	int will_flag;

+	char *will_topic;

+	int will_payloadlen;

+	char *will_payload;

+	int will_qos;

+	bool retain;

+};

+

+struct mqtt_set_parament

+{

+	char *protocol;
+	int  session;
+	char *action;

+	int modify_thread;
+	int add_thread;

+

+	 char *usrname; //服务端用户名

+	 char *pwd; //服务端密码

+	 char *ip_addr;

+	 int port;

+	 int keep_time; 

+

+	 int subscribe_qos;

+	 int publish_qos;

+

+	 char *subscribe_topic;

+	 char *unsubscribe_topic; //lt add @2021.7.13 for unsubscribe topic

+

+	 char *publish_topic;

+	 char *publish_data;

+

+	char *client_id;

+	bool clean_session;

+

+	struct mqtt_set_will set_will;

+	 

+};

+

+

+#define NO_ERROR 0

+#define CREATE_LIENT_ERROR 1

+#define USER_PWD_ERROR 2

+#define CONNECT_FAIL 3

+#define CREATE_LOOP_FAIL 4

+#define MQTT_DISCONNECT_FAIL 5

+#define MQTT_CONNECT_FAIL 6

+

+

+int lynq_mqtt_connect_init(struct mqtt_set_parament mqtt_message);

+void lynq_mosquitto_set_connect_callback(void (*connect_callback)(struct mosquitto *mosq, void *userdata, int result));

+void lynq_mosquitto_set_message_callback(void (*message_callback)(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message));

+void lynq_mosquitto_set_subscribe_callback(void (*subscribe_callback)(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos));

+void lynq_mosquitto_set_disconnect_callback( void (*disconnect_callback)( struct mosquitto *mosq,void *obj, int rc));

+void lynq_mosquitto_set_publish_callback(void (*on_publish)(struct mosquitto *mosq, void *obj, int mid));

+

+void lynq_mosquitto_publish_message(char *pub_topic,int pub_buf_len,char *pub_buf,int qos); //发布

+void lynq_mosquitto_subscribe_message(char *sub_topic,int sub_qos); // 订阅

+void lynq_mosquitto_disconnect(void); //断开

+

+int lynq_mqtt_login(struct mqtt_set_parament mqtt_message);

+void lynq_mosquitto_subscribe_message(char *sub_topic,int sub_qos);

+void lynq_mosquitto_publish_message(char *pub_topic,int pub_buf_len,char *pub_buf,int qos);

+void lynq_mosquitto_unsubscribe_message(char *unsub_topic);

+#endif //__LYNQ_MQTT_H__

diff --git a/src/lynq/lib/liblynq-protcl/lynq_mqtt/lynq_mqtt.c b/src/lynq/lib/liblynq-protcl/lynq_mqtt/lynq_mqtt.c
new file mode 100644
index 0000000..a7380ae
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/lynq_mqtt/lynq_mqtt.c
@@ -0,0 +1,227 @@
+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <unistd.h>

+#include "lynq_mqtt/lynq_mqtt.h"

+#include "liblog/lynq_deflog.h"

+

+#define HOST "58.246.1.50"  // IP

+#define PORT  63743	

+

+#define KEEP_ALIVE 60

+

+

+static int mqtt_session = 0;

+

+

+void my_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)

+{

+    char *str_payload = NULL;

+    if(message->payloadlen){

+	LYVERBLOG("+[mqtt][message%d]: topic:%s---data:%s\n",mqtt_session,message->topic, (char *)message->payload);//lt mod @2021.7.13 for mqtt_session

+	str_payload = malloc(message->payloadlen);

+	memset(str_payload,0,message->payloadlen);

+	memcpy(str_payload,message->payload,message->payloadlen);

+printf("0x:");//lt add @2021.7.13 for debug

+for(int i = 0; i < (message->payloadlen); i++)

+{

+printf(" %02x",str_payload[i]);

+}

+printf("\n");

+	free(str_payload);

+	str_payload = NULL;

+    }else{

+    	     LYVERBLOG("+[mqtt][message%d]: %s (null)\n",mqtt_session,message->topic); //lt mod @2021.7.13 for mqtt_session

+    }

+}

+

+void my_connect_callback(struct mosquitto *mosq, void *userdata, int result)

+{

+    int i;

+    if(!result){

+	LYVERBLOG("+[mqtt][connect][session%d]: ok!!\n", mqtt_session);

+    }else{

+	LYVERBLOG("+[mqtt][connect][session%d]: error num = %d\n", mqtt_session,MQTT_CONNECT_FAIL);

+    }

+}

+

+void my_disconnect_callback(struct mosquitto *mosq, void *userdata, int result)

+{

+    int i;

+    if(!result){

+	LYVERBLOG("+[mqtt][disconnect][session%d]: ok!!\n", mqtt_session);

+    }else{

+		LYVERBLOG("+[mqtt][disconnect][session%d]: error num = %d\n", mqtt_session,MQTT_DISCONNECT_FAIL);

+    }

+}

+

+void my_subscribe_callback(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos)

+{

+	LYVERBLOG("+[mqtt][subscribe][session%d]: ok!!\n", mqtt_session);

+}

+

+void my_unsubscribe_callback(struct mosquitto *mosq, void *obj, int mid)//lt add @2021.7.13 for unsubscribe callback function

+{

+	LYVERBLOG("+[mqtt][unsubscribe][session%d]: ok!!\n", mqtt_session);

+}

+

+void my_publish_callback(struct mosquitto *mosq, void *obj, int mid)

+{

+   LYVERBLOG("+[mqtt][publish][session%d]: ok!!\n", mqtt_session);

+}

+

+struct mosquitto *mosq = NULL;

+	

+void lynq_mosquitto_set_message_callback(void (*message_callback)(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message))

+{

+	mosquitto_message_callback_set(mosq, message_callback);

+}

+

+	

+void lynq_mosquitto_set_connect_callback(void (*connect_callback)(struct mosquitto *mosq, void *userdata, int result))

+{

+	mosquitto_connect_callback_set(mosq, connect_callback);

+}

+void lynq_mosquitto_set_subscribe_callback(void (*subscribe_callback)(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos))

+{

+	mosquitto_subscribe_callback_set(mosq, subscribe_callback); //lt mod @2021.7.13 for deleate my_subscribe_callback add subscribe_callback

+}

+

+void lynq_mosquitto_set_unsubscribe_callback(void (*on_unsubscribe)(struct mosquitto *mosq, void *obj, int mid)) //lt add @2021.7.13 for set unsubscribe callback function

+{

+	mosquitto_unsubscribe_callback_set(mosq,on_unsubscribe);

+}

+

+void lynq_mosquitto_set_publish_callback(void (*on_publish)(struct mosquitto *mosq, void *obj, int mid))

+{

+	mosquitto_publish_callback_set(mosq,on_publish);

+}

+

+void lynq_mosquitto_set_disconnect_callback( void (*disconnect_callback)( struct mosquitto *mosq,void *obj, int rc))

+{

+	mosquitto_disconnect_callback_set(mosq,disconnect_callback);

+}

+int lynq_mqtt_connect_init(struct mqtt_set_parament mqtt_message)

+{

+

+	int ret;

+	//libmosquitto ¿â³õʼ»¯

+	mosquitto_lib_init();

+	

+	if(mqtt_message.client_id != NULL)

+	{

+		mosq = mosquitto_new(mqtt_message.client_id,mqtt_message.clean_session,NULL);//´´½¨mosquitto¿Í»§¶Ë

+	}else{

+		mosq = mosquitto_new(NULL,true,NULL);//´´½¨mosquitto¿Í»§¶Ë

+	}

+	

+	if(!mosq){

+		 LYVERBLOG("+[mqtt][init][session%d]: error num = %d\n", mqtt_message.session,CREATE_LIENT_ERROR);

+		mosquitto_lib_cleanup();

+		return CREATE_LIENT_ERROR;

+	}

+

+

+	lynq_mosquitto_set_connect_callback(my_connect_callback);

+	lynq_mosquitto_set_message_callback(my_message_callback);

+	lynq_mosquitto_set_subscribe_callback(my_subscribe_callback);

+	lynq_mosquitto_set_unsubscribe_callback(my_unsubscribe_callback); //lt add @2021.7.13 for set  unsubscribe callback

+	lynq_mosquitto_set_disconnect_callback(my_disconnect_callback);

+	lynq_mosquitto_set_publish_callback(my_publish_callback);

+

+	 // ÉèÖÃÁ¬½ÓµÄÓû§ÃûÓëÃÜÂë:£¬

+     // ²ÎÊý£º¾ä±ú¡¢Óû§Ãû¡¢ÃÜÂë

+	ret = mosquitto_username_pw_set(mosq, mqtt_message.usrname, mqtt_message.pwd);

+	if(ret){

+//			LYVERBLOG("+[mqtt][init]: set username and password error!\n");

+			LYVERBLOG("+[mqtt][init][session%d]: error num = %d\n", mqtt_message.session,USER_PWD_ERROR);

+			mosquitto_destroy(mosq);

+			mosquitto_lib_cleanup();

+			return USER_PWD_ERROR;

+	}

+

+	if(mqtt_message.set_will.will_flag == 1)

+	{

+		mosquitto_will_set(	mosq,mqtt_message.set_will.will_topic,mqtt_message.set_will.will_payloadlen,mqtt_message.set_will.will_payload,mqtt_message.set_will.will_qos,mqtt_message.set_will.retain);

+	}

+     //Á¬½Ó·þÎñÆ÷

+    if(mosquitto_connect(mosq, mqtt_message.ip_addr, mqtt_message.port, mqtt_message.keep_time)){

+// 	LYVERBLOG("+[mqtt][init]: unable to connect!\n");

+	LYVERBLOG("+[mqtt][init][session%d]: error num = %d\n", mqtt_message.session,CONNECT_FAIL);

+        return CONNECT_FAIL;

+    }

+    //¿ªÆôÒ»¸öỊ̈߳¬ÔÚÏß³ÌÀﲻͣµÄµ÷Óà mosquitto_loop() À´´¦ÀíÍøÂçÐÅÏ¢

+    int loop = mosquitto_loop_start(mosq); 

+    if(loop != MOSQ_ERR_SUCCESS)

+    {

+//	LYVERBLOG("+[mqtt][init]: mosquitto loop error\n");

+	LYVERBLOG("+[mqtt][init][session%d]: error num = %d\n", mqtt_message.session,CREATE_LOOP_FAIL);

+        return CREATE_LOOP_FAIL;

+    }

+  return NO_ERROR;	

+}

+

+void lynq_mosquitto_publish_message(char *pub_topic,int pub_buf_len,char *pub_buf,int qos)

+{

+	mosquitto_publish(mosq,NULL,pub_topic,pub_buf_len,pub_buf,qos,0);

+}

+

+void lynq_mosquitto_subscribe_message(char *sub_topic,int sub_qos)

+{

+	mosquitto_subscribe(mosq, NULL, sub_topic, sub_qos);

+}

+

+void lynq_mosquitto_unsubscribe_message(char *unsub_topic) //lt add @2021.7.13 for unsubscribe function

+{

+	mosquitto_unsubscribe(mosq,NULL,unsub_topic);

+}

+    

+void lynq_mosquitto_disconnect(void)  

+{

+   mosquitto_disconnect(mosq);

+}   

+

+#if 1

+struct mqtt_set_parament mqtt_set_data;

+void factory_mqtt_test(void)

+{

+	char buff[10] = {"123456789"};

+	buff[10] = '\0';

+	

+	mqtt_set_data.usrname = "admin";

+	mqtt_set_data.pwd = "password";

+	mqtt_set_data.ip_addr = HOST;

+	mqtt_set_data.port = PORT;

+	mqtt_set_data.keep_time = KEEP_ALIVE;

+

+

+	lynq_mqtt_connect_init(mqtt_set_data);

+	

+	lynq_mosquitto_set_connect_callback(my_connect_callback);

+	lynq_mosquitto_set_message_callback(my_message_callback);

+	lynq_mosquitto_set_subscribe_callback(my_subscribe_callback);

+	lynq_mosquitto_set_disconnect_callback(my_disconnect_callback);

+	lynq_mosquitto_set_publish_callback(my_publish_callback);

+	

+	lynq_mosquitto_subscribe_message("/S2C/DATA ",2);

+

+	for(int i = 1000; i > 1; i--)

+	{

+		if((i % 10) == 0)

+		{	  

+			/*·¢²¼ÏûÏ¢*/

+			lynq_mosquitto_publish_message("/S2C/DATA ",10,buff,0);

+		}

+		sleep(1);

+	    memset(buff,0,10);

+	}

+}

+#endif

+

+

+int lynq_mqtt_login(struct mqtt_set_parament mqtt_message)

+{

+	mqtt_session = mqtt_message.session;

+	lynq_mqtt_connect_init(mqtt_message);	

+}

+

diff --git a/src/lynq/lib/liblynq-protcl/makefile b/src/lynq/lib/liblynq-protcl/makefile
new file mode 100644
index 0000000..e7018b4
--- /dev/null
+++ b/src/lynq/lib/liblynq-protcl/makefile
@@ -0,0 +1,94 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -std=gnu++14 \
+                -g -Os \
+                -flto \
+                -DRIL_SHLIB \
+                -DATCI_PARSE \
+                -DKEEP_ALIVE \
+                -DECALL_SUPPORT \
+                -fpermissive \
+
+$(warning ################# C2K support: $(RAT_CONFIG_C2K_SUPPORT))
+ifeq ($(strip $(RAT_CONFIG_C2K_SUPPORT)), yes)
+    LOCAL_CFLAGS += -DC2K_SUPPORT
+
+endif
+
+ifeq ($(strip $(MTK_MULTI_SIM_SUPPORT)), dsds)
+    LOCAL_CFLAGS += -DANDROID_SIM_COUNT_2 \
+                     -DANDROID_MULTI_SIM \
+                     -DMODE_DSDS
+endif
+
+ifeq ($(strip $(MTK_MULTI_SIM_SUPPORT)), dsss)
+    LOCAL_CFLAGS += -DMODE_DSSS
+endif
+
+$(warning ################# TARGET_PLATFORM: $(TARGET_PLATFORM))
+ifeq ($(strip $(TARGET_PLATFORM)), mt2731)
+#$(warning #################add for debug $(ROOT), $(includedir))
+$(warning ################# TARGET_PLATFORM_MT2731)
+    LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2731 \
+                    -DMD_93_SUPPORT
+else ifeq ($(strip $(TARGET_PLATFORM)), mt2635)
+$(warning ################# TARGET_PLATFORM_MT2635)
+    LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2635 \
+                    -DMD_90_SUPPORT
+endif
+
+$(warning ################# RITA ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(ROOT)$(includedir)/openssl \
+  -I$(ROOT)$(includedir)/liblog \
+  -I$(LOCAL_PATH)/include \
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lpthread \
+    -llynq-log \
+    -lssl \
+    -lcrypto \
+    -lmosquitto \
+
+SOURCES = $(wildcard *.c wildcard *.h ftp/*.c http/src/*.c lynq_mqtt/*.c)
+
+EXECUTABLE = liblynq-protcl.so
+
+OBJECTS=$(SOURCES:.c=.o)
+
+
+.PHONY: build clean install pack_rootfs 
+
+all: build
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+	$(CC) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $< 
+
+build:  $(EXECUTABLE)
+	$(warning ########## build $(EXECUTABLE)  ##########)
+
+install:
+	mkdir -p $(ROOT)$(base_libdir)/
+	install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+	mkdir -p $(ROOT)$(includedir)/$(NAME)/sdk
+
+pack_rootfs:
+	mkdir -p $(PACK_INITRAMFS_TO)$(base_libdir)/
+	cp -af $(EXECUTABLE) $(PACK_INITRAMFS_TO)$(base_libdir)/
+	$(CROSS)strip $(PACK_INITRAMFS_TO)$(base_libdir)/$(EXECUTABLE)
+	mkdir -p $(PACK_TO)$(base_libdir)/
+	cp -af $(EXECUTABLE) $(PACK_TO)$(base_libdir)/
+	$(CROSS)strip $(PACK_TO)$(base_libdir)/$(EXECUTABLE)
+.PHONY: clean
+clean:
+	$(RM) $(OBJECTS) $(EXECUTABLE)