Beispiel #1
0
/*
 * getchr:
 *	Grab input and pass it along to the driver
 *	Return any characters from the driver
 *	When this routine is called by GETCHR, we already know there are
 *	no characters in the input buffer.
 */
static unsigned char
getchr()
{
	struct	pollfd set[2];
	int	nfds;

	set[0].fd = Socket;
	set[0].events = POLLIN;
	set[1].fd = STDIN;
	set[1].events = POLLIN;

one_more_time:
	do {
		errno = 0;
		nfds = poll(set, 2, INFTIM);
	} while (nfds <= 0 && errno == EINTR);

	if (set[1].revents && POLLIN)
		send_stuff();
	if (! (set[0].revents & POLLIN))
		goto one_more_time;
	icnt = read(Socket, ibuf, sizeof ibuf);
	if (icnt < 0) {
		bad_con();
		/* NOTREACHED */
	}
	if (icnt == 0)
		goto one_more_time;
	iptr = ibuf;
	icnt--;
	return *iptr++;
}
Beispiel #2
0
// the void *p is connfd
void *handle_requests(void *p) {
	// to be malloc'ed later
	char *filename;
	char *temp_buffer;
	char *big_send_buffer;

	// fixed size buffers
	char http_checker[8];			// to see if the last 8 bytes are 'HTTP/1.1'
	char rcv_buffer[1024];		// if the user sends more than 1024, I'd be surprised
	char send_buffer[1024];		// sort of a temporary buffer to store what we'll send

	int file_size = 0;
	int amt = 0;
	int connfd = *(int *)p;
	
	// for time&date
	time_t time_is;
	struct tm *time_struct;

	if (recv(connfd, rcv_buffer, 1024, 0) > 0) {					// wait for a message
		
		// this if statement keeps us for looking in the string when it's not long
		// enough to contain what we want, and so stops us from segfaulting
		if (strlen(rcv_buffer) <= 15) {

			temp_buffer = malloc(75);		// make some space
			strcat(temp_buffer, "\nYour query must be at least 16 characters.\n");
			strcat(temp_buffer, "Closing connection.\n");
			send_stuff(temp_buffer, connfd);		// send the message
			free(temp_buffer);					// give the space back
		

			close(connfd);					// close the connection

			// mutually exclusively write to stats.txt about their bad request
			pthread_mutex_lock(&mutex);
			write_to_stats(rcv_buffer);
			pthread_mutex_unlock(&mutex);

			return NULL;
		}


		if (!strncmp("GET", rcv_buffer, 3)) {								// if begins with 'GET'
			
			filename = malloc(strlen(rcv_buffer) - 14);				// make enough space
			strncpy(filename, rcv_buffer + 4, strlen(rcv_buffer) - 15);	// copy filename
			strncpy(http_checker, rcv_buffer + 4 + strlen(filename) + 1, 8);	// copy HTTP

			if (!strncmp(http_checker, "HTTP/1.1", 8)) {			// check for HTTP/1.1
		
				FILE *f = fopen(filename, "rt");		// try to open the filename they gave

				if (f == NULL) {					// if file not found, tell them
					strcat(send_buffer, "\nHTTP/1.1 404 Not Found\n\n");
					send_stuff(send_buffer, connfd);

					close(connfd);					// close the connection

					pthread_mutex_lock(&mutex);
					write_to_stats(rcv_buffer);
					pthread_mutex_unlock(&mutex);
					return NULL;						// and quit
				}
				// if we're here then it's a valid file
				
				fseek(f, 0, SEEK_END);		// go to the end
				file_size = ftell(f);			// and see how far we've gone, the file_size
				fseek(f, 0, SEEK_SET);		// then go back to the beginning

				time_is = time(NULL);							// get the current time
				time_struct = gmtime(&time_is);		// then convernt to GMC

				temp_buffer = malloc(50);			// make some room

				// this is pretty cool - printf for time/date basically
  			strftime (temp_buffer, 50, "Date: %a, %d %b %Y %X %Z\n", time_struct );

  			// start filling up the send_buffer with stuff to send
				strcat(send_buffer, "\nHTTP/1.1 200 OK\n");
				strcat(send_buffer, temp_buffer);					// copy in the time/date
				strcat(send_buffer, "Content-Length: ");
				sprintf(temp_buffer, "%d\n", file_size);	// convert file_size to string
				strcat(send_buffer, temp_buffer);					// copy in the file size
				strcat(send_buffer, "Connection: close\n");
				strcat(send_buffer, "Content-Type: text/html\n\n");

				free(temp_buffer);		// free the temp_buffer
				temp_buffer = malloc(file_size);		// make it big enough for the file

				fread(temp_buffer, 1, file_size, f);		// read in all the bytes!
				fclose(f);						// and now we're done with the file, so close it

				// make enough room for what we have, plus the file
				big_send_buffer = malloc(file_size + strlen(send_buffer));
				strcat(big_send_buffer, send_buffer);			// put in the old stuff
				strcat(big_send_buffer, temp_buffer);			// and the file

				send_stuff(big_send_buffer, connfd);			// then send it along!
			}
			else {
				// if here, then they didn't end with 'HTTP/1.1'
				strcat(send_buffer, "\nPlease follow the proper format:\n");
				strcat(send_buffer, "GET /FILENAME.html HTTP/1.1\n");
				strcat(send_buffer, "Closing connection.\n\n");

				send_stuff(send_buffer, connfd);
			}	
		}
		else {
			// if here, then they didn't start with 'GET'
			strcat(send_buffer, "\nPlease follow the proper format:\n");
			strcat(send_buffer, "GET /FILENAME.html HTTP/1.1\n");
			strcat(send_buffer, "Closing connection.\n\n");

			send_stuff(send_buffer, connfd);
		}
	}

	close(connfd);		// close the connection to the client
	
	pthread_mutex_lock(&mutex);
	write_to_stats(rcv_buffer);
	pthread_mutex_unlock(&mutex);

}