void loop() { if (wifly.available() > 0) { /* See if there is a request */ if (wifly.gets(buf, sizeof(buf))) { if (strncmp_P(buf, PSTR("GET /ping"), 9) == 0) { /* GET request */ #ifdef DEBUG Serial.println(F("PONG XML requested")); #endif while (wifly.gets(buf, sizeof(buf)) > 0) { //Skip rest of request } sendPong(); } else if (strncmp_P(buf, PSTR("GET /data"), 9) == 0) { /* POST request */ #ifdef DEBUG Serial.println(F("DATACOLLECTOR XML: sendind sensors data")); #endif while (wifly.gets(buf, sizeof(buf)) > 0) { //Skip rest of request } // discard rest of input // wifly.flushRx(); sendSensorsDataXML(); } else { // Unexpected request #ifdef DEBUG Serial.print(F("Unexpected: ")); Serial.println(buf); Serial.println(F("Sending 404")); #endif while (wifly.gets(buf, sizeof(buf)) > 0) { //Skip rest of request } // discard rest of input wifly.flushRx(); send404(); } } } }
void deleteResponse(Request* req, ConnObj* conn_state){ std::string requestObject = "www" + req->request_URI; // Check to see if the directory has user permissions int allowed = conn_state->authorized(req->request_method, req->request_URI); if(!allowed){ send403(conn_state); } else{ if(remove(requestObject.c_str()) == 0){ // File was deleted send200(conn_state); } else { // If it was not deleted send404(conn_state); } } }
void *processConn(int connfd){ char *buf=NULL,*holder; int offset = 0; char *file; ssize_t rcount; /* "getp" is where in the "Working buffer" the "GET" string is found. Case sensitive. "http" is where in the "Working buffer" the "HTTP/1.1" string is found. Case insensitive. "host" is where in the "Working buffer" the "HOST" string is found. Case insensitive. "eomp" is where in the "Holding buffer" the "\r\n\r\n" string is found. */ char *getp=NULL, *http=NULL, *host=NULL, *eomp=NULL, *ptr; int i = 0; int *filesize=&i; FILE *fp=NULL; /* Holder is the "Holding buffer" where the input from the connection is read into until the end of message "\r\n\r\n" is found. */ holder = (char*) malloc(sizeof(char)*(512+1)); holder = memset(holder,'\0',512); read: /* While the connection has more to give, or when the connection has nothing left to give but the "Holding buffer" still has content. Offset is the current offset into the "Holding Buffer" after every read. */ while(((rcount = read(connfd,holder+offset,512))>0)||((rcount==0)&&(strlen(holder)>0))){ offset = offset + rcount; /* Null terminate what we have just read in */ *(holder+offset)='\0'; #ifdef SERVER_DEBUG fprintf(stderr,"Characters Read: %zu\n",rcount); fprintf(stderr,"Holding Buffer: %s\n",holder); #endif eomp = strcasestr(holder,"\r\n\r\n"); if(eomp!=NULL){ /* We have found a finished header! Move this into the "Working Buffer". The "Working Buffer" is "buf". */ *eomp='\0'; buf = (char *) malloc(eomp-holder); buf = memcpy(buf,holder,eomp-holder); /* Slide the rest of the "Holding Buffer" after where the end of the header was found to the beginning of the header with the null terminator still on the end. */ *holder='\0'; holder = memmove(holder,(eomp+4), (holder+offset)-(eomp+3)); offset = strlen(holder); #ifdef SERVER_DEBUG fprintf(stderr,"FOUND HEADER\n------------\nBUFFER: %s\nHOLDER: %s\nOFFSET: %d\n\n",buf,holder,offset); #endif break; } /* if nothing was read, but the "Holding Buffer" still had contents and the "Holding Buffer" did not contain the end of message then send a bad request. */ else if(rcount==0) goto badReq; /* End of message has not yet been found, expand the buffer and continue trying to read. */ holder = realloc(holder,(strlen(holder)+513)*sizeof(char)); } /* Connection was established and then closed, so no read. Close the connection */ if(buf==NULL) goto end; /* Check if the required contents are present */ getp = strstr(buf,"GET"); http = strcasestr(buf,"HTTP/1.1"); host = strcasestr(buf,"Host:"); /* Get the current working directory and add on the requested file name */ file=malloc(sizeof(char)*180); if((file=getcwd(file,180)) != NULL){ #ifdef SERVER_DEBUG fprintf(stdout,"CWD: %s:%zu\n",file,strlen(file)); #endif } if((file=realloc(file,(strlen(file)+(http-(getp+4))*sizeof(char))))!=NULL){ *(--http)='\0'; file=strcat(file,(getp+4)); } #ifdef SERVER_DEBUG fprintf(stdout,"BUF: %s\n",buf); fprintf(stdout,"GETP:%c HTTP:%c HOST:%c EOMP:%c\n",*getp,*http,*host,*eomp); fprintf(stdout,"FILE:%s :%zu\n",file,strlen(file)); #endif /* If this is a valid start line */ if(getp!=NULL&&http!=NULL&&host!=NULL){ fp = getFile(host+6,file,filesize); if(fp==NULL){ /* File does not exist */ if(send404(connfd)==-1) perror("Unable to send 404"); } else{ /* File exists, attempt to send it and then close the file */ if((ptr=strstr(file,".htm"))!=NULL){ if(!sendSuccess(connfd,fp,"text/html",filesize)){ fprintf(stderr,"Failed to send %s\n",file); } fclose(fp); } else if ((ptr=strstr(file,".txt"))!=NULL){ if(!sendSuccess(connfd,fp,"text/plain",filesize)){ fprintf(stderr,"Failed to send %s\n",file); } fclose(fp); } else if ((ptr=strstr(file,".jpeg"))||(ptr=strstr(file,".jpg"))!=NULL){ if(!sendSuccess(connfd,fp,"image/jpeg",filesize)){ fprintf(stderr,"Failed to send %s\n",file); } fclose(fp); } else if ((ptr=strstr(file,".gif"))!=NULL){ if(!sendSuccess(connfd,fp,"image/gif",filesize)){ fprintf(stderr,"Failed to send %s\n",file); } fclose(fp); } else{ if(!sendSuccess(connfd,fp,"application/octet-stream",filesize)){ fprintf(stderr,"Failed to send %s\n",file); } fclose(fp); } } } else{ badReq: if(send400(connfd)==-1) perror("Failed to send 404"); goto end; } free(file); free(buf); file = buf = NULL; /* If there is still contents in the "Holding Buffer" */ if(strlen(holder)!=0) goto read; end: close(connfd); #ifdef SERVER_DEBUG printf("Connection Closed\n"); #endif return NULL; }
int main() { struct sockaddr_in sin; int s, pcapfd; socklen_t sinl; struct clientData clients[MAX_CONNECTIONS]; int i, j, len; int sockopt, one = 1; struct timeval now; char buf[MAX_LINE]; struct pollfd fds[MAX_CONNECTIONS + 2]; /* signals */ signal (SIGINT, leave); signal (SIGTERM, leave); signal (SIGQUIT, leave); /* Ignore quitting clients */ sigignore(SIGPIPE); /* build address data structure */ bzero((char *)&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(PORT); /* passive open */ if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); exit(1); } /* Make the socket non-blocking */ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); if ((sockopt = fcntl(s, F_GETFL)) < 0) { perror("getting options"); exit(1); } if ((fcntl(s, F_SETFL, (sockopt | O_NONBLOCK))) < 0) { perror("setting non-blocking"); exit(1); } if ((bind(s, (struct sockaddr *)&sin, sizeof(sin))) < 0) { perror("bind"); exit(1); } listen(s, MAX_PENDING); /* Open Listener */ // TODO(willscott): pcap setup. /* Initialize connection information */ for (i = 0; i < MAX_CONNECTIONS; ++i) { clients[i].d = 0; bzero((char *)&clients[i].cin, sizeof(clients[i].cin)); } numcon = 0; pcapfd = beginCapture(); while (running) { fds[0].fd = s; fds[0].events = POLLIN; fds[1].fd = pcapfd; fds[1].events = POLLIN; for (i = 0; i < numcon; ++i) { fds[i + 2].fd = clients[i].d; fds[i + 2].events = POLLIN; } if (error > 0) { // TODO(willscott): Reset state. error = 0; } if (poll(fds, numcon + 2, 100)) { gettimeofday(&now, NULL); for (i = 0; i < numcon; ++i) { if ((clients[i].state == 4 && (unsigned long)now.tv_sec * 1000000 + now.tv_usec > clients[i].delay + 3000000) || (clients[i].state == 0 && clients[i].traceid != NULL && (unsigned long)now.tv_sec * 1000000 + now.tv_usec > clients[i].delay + 5000000)) { printf("Stats now\n"); // Summary statistics if (clients[i].traceid != NULL) { send200(clients[i].d, (struct trace*)clients[i].traceid); cleanupTrace(clients[i].traceid); } else { send404(clients[i].d); } close(clients[i].d); for (j = i + 1; j < numcon; ++j) { clients[j - 1] = clients[j]; fds[j] = fds[j + 1]; } --numcon; --i; } /* Read from an existing client */ if (fds[i + 2].revents != 0) { //printf("got client event\n"); len = recv(clients[i].d, buf, sizeof(buf), 0); //Disconnect if (len <= 0) { close(clients[i].d); if (clients[i].traceid != NULL) { cleanupTrace(clients[i].traceid); } for (j = i + 1; j < numcon; ++j) { clients[j - 1] = clients[j]; fds[j] = fds[j + 1]; } --numcon; --i; } else { if (clients[i].state == 0) { // no data read yet. if (strncasecmp("GET / ", buf, 6) == 0) { clients[i].state = 1; } else if (strncasecmp("GET /result.json", buf, 16) == 0) { // Delay this request 1 second to give trace time to return. clients[i].state = 4; clients[i].delay = (unsigned long)now.tv_sec * 1000000 + now.tv_usec; printf("Stats in 1 second compared.\n"); } else { send404(clients[i].d); close(clients[i].d); for (j = i + 1; j < numcon; ++j) { clients[j - 1] = clients[j]; fds[j] = fds[j + 1]; } if (clients[i].traceid != NULL) { cleanupTrace(clients[i].traceid); } --numcon; --i; } } if (clients[i].state == 1) { if(strstr(buf, "\r\n\r\n") != 0) { clients[i].state = 0; clients[i].delay = (unsigned long)now.tv_sec * 1000000 + now.tv_usec; clients[i].data = (void*)get302(); clients[i].left = strlen((char*)clients[i].data); printf("End of Input!\n"); clients[i].traceid = beginTrace(clients[i].d, &clients[i].cin); clients[i].left -= send(clients[i].d, clients[i].data, clients[i].left, 0); } else if (strlen(buf) > 2 && strncmp(&buf[strlen(buf) - 2], "\r\n\r\n", 4) == 0) { clients[i].state = 2; } } else if (clients[i].state == 2 && strncmp(buf, "\r\n\r\n", 4) == 0) { clients[i].state = 0; clients[i].delay = (unsigned long)now.tv_sec * 1000000 + now.tv_usec; clients[i].data = (void*)get302(); clients[i].left = strlen((char*)clients[i].data); printf("End of Input!\n"); clients[i].traceid = beginTrace(clients[i].d, &clients[i].cin); clients[i].left -= send(clients[i].d, clients[i].data, clients[i].left, 0); } else if (clients[i].state == 2) { clients[i].state = 1; } } } } if (fds[0].revents != 0 && numcon < MAX_CONNECTIONS) { /* Accept new Clients */ printf("will accept..."); sinl = sizeof(clients[numcon].cin); if ((clients[numcon].d = accept(s, (struct sockaddr *)&clients[numcon].cin, &sinl)) < 0) { if (errno == EAGAIN) { continue; } perror("client accept failure"); exit(1); } gettimeofday(&clients[numcon].start, NULL); printf("accepted\n"); clients[numcon].state = 0; clients[numcon].traceid = NULL; if ((sockopt = fcntl(s, F_GETFL)) < 0) { perror("client options failure"); exit(1); } if ((fcntl(s, F_SETFL,(sockopt | O_NONBLOCK))) < 0) { perror("client non-blocking failure"); exit(1); } numcon++; } if (fds[1].revents != 0) { processPcap(); } } } /* Cleanup */ return 0; }
void Visualight::processServer() { if (wifly.available() > 0) { // check for data from wifly if (wifly.gets(buf, sizeof(buf))) { /* See if there is a request */ if (strstr_P(buf, PSTR("GET /mac")) > 0) { /* GET request */ VPRINTLN(F("Got GET MAC request")); while (wifly.gets(buf, sizeof(buf)) > 0) { /* Skip rest of request */ } //int numNetworks = wifly.getNumNetworks(); sendMac(); wifly.flushRx(); // discard rest of input VPRINTLN(F("Sent Mac address")); wifly.close(); } else if (strstr_P(buf, PSTR("GET / ")) > 0) { // GET request VPRINTLN(F("Got GET request")); while (wifly.gets(buf, sizeof(buf)) > 0) { /* Skip rest of request */ } //int numNetworks = wifly.getNumNetworks(); wifly.flushRx(); // discard rest of input sendIndex(); VPRINTLN(F("Sent index page")); wifly.close(); } else if (strstr_P(buf, PSTR("POST")) > 0) { /* Form POST */ VPRINTLN(F("Got POST")); if (wifly.match(F("net="))) { /* Get posted field value */ //Serial.println(buf); memset(decodeBuffer, 0, 65); wifly.getsTerm(decodeBuffer, sizeof(decodeBuffer),'&'); urldecode(network, decodeBuffer); replaceAll(network,"+","$"); VPRINTLN(F("Got network: ")); VPRINTLN(network); if (wifly.match(F("pas="******"+","$"); //wifly.gets(security, 1); //no need for sizeof() -- it's a 1 or 2 VPRINTLN(F("Got password: "******"sec="))) { wifly.gets(security, sizeof(security)); VPRINTLN(F("Got security: ")); VPRINTLN(security); } } wifly.flushRx(); // discard rest of input VPRINT(F("Sending greeting page: ")); sendGreeting(network); //send greeting back delay(500); sendGreeting(network); //send a second time *just in case* delay(500); wifly.flushRx(); joinWifi(); } } else { /* Unexpected request */ delay(100); wifly.flushRx(); // discard rest of input VPRINTLN(F("Sending 404")); send404(); } } } }