#include #include #include #include #include typedef enum PROTOCOL_STATUS { PS_NONE, PS_SNIFF, PS_HTTP_READ_HEADER, PS_HTTP_READ_BODY, PS_STREAM, PS_ERROR } PROTOCOL_STATUS; typedef enum PROTOCOL_NAME { PN_NONE, PN_HTTP, PN_HTTP_CHUNKED, PN_HTTP_WEBSOCKET, PN_HTTP_KEEP_ALIVE, PN_HTTP_REQUEST, PN_SSH, PN_RAW, PN_ERROR } PROTOCOL_NAME ; char * http_get_header_value(char * headers, char * key){ char * result = NULL; char * start = strstr(headers, key); if(!start){ return NULL; } start += strlen(key); start += 2; char * end = strstr(start, "\r\n"); if(!end){ return NULL; } result = (char *)malloc(end - start + 1); strncpy(result, start, end - start); result[end-start] = 0; return result; } PROTOCOL_NAME protocol_sniff(int fd){ char buffer[4096] = {0}; ssize_t bytes_received = recv(fd, buffer,sizeof(buffer),MSG_PEEK); buffer[bytes_received] = 0; if(bytes_received <= 0){ return PN_ERROR; } if(strncmp(buffer,"HTTP",4) == 0){ if(strstr(buffer,"Transfer-Encoding: chunked")) return PN_HTTP_CHUNKED; if(strstr(buffer,"Connection: keep-alive")){ return PN_HTTP_KEEP_ALIVE; } return PN_HTTP; } if(!strncmp(buffer,"GET ",4) && strstr(buffer,"Upgrade: websocket")){ return PN_HTTP_WEBSOCKET; } if(!strncmp(buffer,"SSH ",4)){ return PN_SSH; } if(!strncmp(buffer,"GET ", 4)){ return PN_HTTP_REQUEST; } return PN_RAW; }