ע ¼  
 ӹע
   ʾһ  |  ر
ܰʾ΢֤Ƶ΢ʺŰѹڣ°󶨣°΢  |  ر

Mihooke's blog

IT֮

 
 
 
 
 

־

 
 

tinyhttpԴС  

2015-05-03 01:07:14|  ࣺ UNIX |  ǩ |ٱ |ֺС 

  LOFTER ҵƬ  |
ӣһ

/**********************************************************************/

/* Get a line from a socket, whether the line ends in a newline,

 * carriage return, or a CRLF combination.  Terminates the string read

 * with a null character.  If no newline indicator is found before the

 * end of the buffer, the string is terminated with a null.  If any of

 * the above three line terminators is read, the last character of the

 * string will be a linefeed and the string will be terminated with a

 * null character.

 * Parameters: the socket descriptor

 *             the buffer to save the data in

 *             the size of the buffer

 * Returns: the number of bytes stored (excluding null) */

/**********************************************************************/

int get_line(int sockchar *bufint size)

{

int i = 0;

char c = '\0';

int n;

 

while ((i < size - 1) && (c != '\n'))

{

/*socketϢصֵǶֽ*/

n = recv(sock, &c, 1, 0);

/* DEBUG printf("%02X\n", c); */

if (n > 0)

{

if (c == '\r')

{

/*鵽ַ\rٲ鿴ϢϢ\nȫ

\n

*/

n = recv(sock, &c, 1, MSG_PEEK);

   /* DEBUG printf("%02X\n", c); */

if ((n > 0) && (c == '\n'))

recv(sock, &c, 1, 0);

else

c = '\n';

}

buf[i] = c;

i++;

}

else

  c = '\n';

}

buf[i] = '\0';

 

return(i);

}

 

/**********************************************************************/

/* Return the informational HTTP headers about a file. */

/* Parameters: the socket to print the headers on

 *             the name of the file */

/**********************************************************************/

void headers(int clientconst char *filename)

{

char buf[1024];

(void)filename;  /* could use filename to determine file type */

 

strcpy(buf"HTTP/1.0 200 OK\r\n");

send(clientbufstrlen(buf), 0);

strcpy(bufSERVER_STRING);

send(clientbufstrlen(buf), 0);

sprintf(buf"Content-Type: text/html\r\n");

send(clientbufstrlen(buf), 0);

strcpy(buf"\r\n");

send(clientbufstrlen(buf), 0);

}

 

/**********************************************************************/

/* Give a client a 404 not found status message. */

/**********************************************************************/

void not_found(int client)

{

char buf[1024];

 

sprintf(buf"HTTP/1.0 404 NOT FOUND\r\n");

send(clientbufstrlen(buf), 0);

sprintf(bufSERVER_STRING);

send(clientbufstrlen(buf), 0);

sprintf(buf"Content-Type: text/html\r\n");

send(clientbufstrlen(buf), 0);

sprintf(buf"\r\n");

send(clientbufstrlen(buf), 0);

sprintf(buf"<HTML><TITLE>Not Found</TITLE>\r\n");

send(clientbufstrlen(buf), 0);

sprintf(buf"<BODY><P>The server could not fulfill\r\n");

send(clientbufstrlen(buf), 0);

sprintf(buf"your request because the resource specified\r\n");

send(clientbufstrlen(buf), 0);

sprintf(buf"is unavailable or nonexistent.\r\n");

send(clientbufstrlen(buf), 0);

sprintf(buf"</BODY></HTML>\r\n");

send(clientbufstrlen(buf), 0);

}

 

/**********************************************************************/

/* Send a regular file to the client.  Use headers, and report

 * errors to client if they occur.

 * Parameters: a pointer to a file structure produced from the socket

 *              file descriptor

 *             the name of the file to serve */

/**********************************************************************/

void serve_file(int clientconst char *filename)

{

FILE *resource = NULL;

int numchars = 1;

char buf[1024];

 

buf[0] = 'A'buf[1] = '\0';

while ((numchars > 0) && strcmp("\n"buf))  /* read & discard headers */

numchars = get_line(clientbufsizeof(buf));

 

resource = fopen(filename"r");

if (resource == NULL)

not_found(client);

else

{

/*ͷļ*/

headers(clientfilename);

cat(clientresource);

}

fclose(resource);

}

 

/**********************************************************************/

/* This function starts the process of listening for web connections

 * on a specified port.  If the port is 0, then dynamically allocate a

 * port and modify the original port variable to reflect the actual

 * port.

 * Parameters: pointer to variable containing the port to connect on

 * Returns: the socket */

/**********************************************************************/

int startup(u_short *port)

{

int httpd = 0;

struct sockaddr_in name;

 

/*socket,return an unsigned fdfdļ*/

httpd = socket(PF_INETSOCK_STREAM, 0);

if (httpd == -1)

error_die("socket");

memset(&name, 0, sizeof(name));

name.sin_family = AF_INET;

name.sin_port = htons(*port);

name.sin_port = htons(*port);/*λֽ˳תΪֽ˳*/

/*IPַṹǣunsigned int s_addr*/

name.sin_addr.s_addr = htonl(INADDR_ANY);/*λֽ˳תΪֽ˳,תĿΪһ紫׼*/

if (bind(httpd, (struct sockaddr *)&namesizeof(name)) < 0)

error_die("bind");

if (*port == 0)  /* ַûportʾportΪport */

{

int namelen = sizeof(name);

 

/*getsocknameһsocketصĵַserverԸõclientĵַ

* clientԸõӳɹsocketIPport

*/

 

if (getsockname(httpd, (struct sockaddr *)&name, &namelen) == -1)

error_die("getsockname");

*port = ntohs(name.sin_port);

}

 

/*ʼ*/

if (listen(httpd, 5) < 0)

error_die("listen");

return(httpd);

}

 

/**********************************************************************/

/* Inform the client that the requested web method has not been

 * implemented.

 * Parameter: the client socket */

/**********************************************************************/

void unimplemented(int client)

{

char buf[1024];

 

sprintf(buf"HTTP/1.0 501 Method Not Implemented\r\n");

send(clientbufstrlen(buf), 0);

sprintf(bufSERVER_STRING);

send(clientbufstrlen(buf), 0);

sprintf(buf"Content-Type: text/html\r\n");

send(clientbufstrlen(buf), 0);

sprintf(buf"\r\n");

send(clientbufstrlen(buf), 0);

sprintf(buf"<HTML><HEAD><TITLE>Method Not Implemented\r\n");

send(clientbufstrlen(buf), 0);

sprintf(buf"</TITLE></HEAD>\r\n");

send(clientbufstrlen(buf), 0);

sprintf(buf"<BODY><P>HTTP request method not supported.\r\n");

send(clientbufstrlen(buf), 0);

sprintf(buf"</BODY></HTML>\r\n");

send(clientbufstrlen(buf), 0);

}

 

/**********************************************************************/

 

int main(void)

{

/*sockaddr_inṹ壺

* struct sockaddr_in {

unsigned short sin_family;

unsigned short sin_port;

struct in_addr sin_addr;

unsigned char sin_zero[8];

};

clientnameserver˴socketϢ

server_sock_fd:socketļ

*/

int server_scok_fd = -1;

u_short port = 0;

int client_scok_fd = -1;

struct sockaddr_in client_name;

int client_name_len = sizeof(client_name);

pthread_t newthread;

 

/*startupȡһΪserversocket*/

server_scok_fd = startup(&port);

printf("httpd running on port %d\n"port);

/*ѭserversocket*/

while (1)

{

client_scok_fd = accept(server_scok_fd,

  (struct sockaddr *)&client_name,

  &client_name_len);

if (client_scok_fd == -1)

error_die("accept");

/* pthread߳server͵client*/

if (pthread_create(&newthread , NULLaccept_requestclient_scok_fd) != 0)

perror("pthread_create");

}

 

close(server_scok_fd);

 

return(0);

}


 
 
Ķ(32)| (0)
Ƽ ת

ʷϵĽ

LOFTERĸ

<#--־Ⱥ־--> <#--Ƽ־--> <#--ü¼--> <#--Ƽ--> <#--Ķ--> <#--ҳƼ--> <#--ʷϵĽ--> <#--Ƽ־--> <#--һƪһƪ--> <#-- ȶ --> <#-- Ź --> <#--ұģṹ--> <#--ģṹ--> <#--ģṹ--> <#--ͶƱ-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

ҳ

ҵƬ - ͷ - ֻ - LOFTER APP - Ĵ˲

׹˾Ȩ ©1997-2017