#include "httpd.h"
void threadFunc(void* arg, int conn){
Httpd* httpd = (Httpd*)arg;
char bodyBuf[1024] = {0};
int recvSize = recv(conn, bodyBuf, sizeof(bodyBuf), 0);
printf("%s\n", bodyBuf);
std::string strMethod;
std::string strUri;
std::string strVersion;
std::map<std::string, std::string> requestHead;
std::string requestBody;
httpd->parseHttpRequestInfo(bodyBuf, strMethod, strUri, strVersion);
httpd->parseHttpRequestHead(bodyBuf, requestHead);
httpd->parseHttpRequestBody(bodyBuf, requestBody);
if(strMethod.compare("GET") == 0){
httpd->httpResponseHtml(conn);
}else if(strMethod.compare("POST") == 0){
std::string data1;
std::string data2;
if(httpd->parseBodyJson(requestBody, data1, data2)){
httpd->httpResponseJson(conn, data1, data2);
}
}
close(conn);
}
bool Httpd::start(){
int server_sockfd = socket(AF_INET,SOCK_STREAM, 0);
struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(4000);
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1){
perror("bind");
return false;
}
if(listen(server_sockfd, 5) == -1){
perror("listen");
return false;
}
char buffer[1024] = {0};
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr);
int conn = 0;
while(1){
conn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length);
if(conn < 0){
perror("connect");
return false;
}
std::thread th;
th = std::thread(threadFunc, this, conn);
th.join();
}
close(server_sockfd);
return true;
}
bool Httpd::parseHttpRequestInfo(std::string httpRequest, std::string& method, std::string& uri, std::string& version){
int recvSize = httpRequest.size();
std::string strRequestHead;
int pos = httpRequest.find("\r\n");
strRequestHead = httpRequest.substr(0, pos);
method = strRequestHead.substr(0, strRequestHead.find(" "));
uri = strRequestHead.substr(strRequestHead.find(" ") + 1, strRequestHead.find(" ", strRequestHead.find(" ") + 1) - strRequestHead.find(" "));
version = strRequestHead.substr(strRequestHead.rfind(" "), strRequestHead.size() - strRequestHead.rfind(" "));
return true;
}
bool Httpd::parseHttpRequestHead(std::string httpRequest, std::map<std::string, std::string>& requestHead){
int recvSize = httpRequest.size();
int headPos = httpRequest.find("\r\n");
int bodySize = parseBodySize(httpRequest);
std::string strRequestH;
do{
int iPos = httpRequest.find("\r\n", headPos + strlen("\r\n"));
strRequestH = httpRequest.substr(headPos, iPos - headPos);
if(strRequestH.find(":") != std::string::npos){
std::string strKey = strRequestH.substr(0, strRequestH.find(":"));
std::string strValue = strRequestH.substr(strRequestH.find(":") + 1, strRequestH.size() - strRequestH.find(":"));
requestHead.insert(std::pair<std::string, std::string>(strKey, strValue));
}
headPos = iPos;
} while(headPos < recvSize - bodySize && headPos > 0);
return true;
}
bool Httpd::parseHttpRequestBody(std::string httpRequest, std::string& requestBody){
int recvSize = httpRequest.size();
int bodySize = parseBodySize(httpRequest);
if(bodySize == 0){
return false;
}
requestBody = httpRequest.substr(recvSize - bodySize, bodySize);
return true;
}
int Httpd::parseBodySize(std::string httpRequest){
std::string strContentLength;
int posLengthStart = httpRequest.find("Content-Length: ") + strlen("Content-Length: ");
int posLengthEnd = httpRequest.find("\r\n", httpRequest.find("Content-Length: ") + strlen("Content-Length: "));
strContentLength = httpRequest.substr(posLengthStart, posLengthEnd - posLengthStart);
return atoi(strContentLength.c_str());
}