PPT
-
Upload
webhostingguy -
Category
Documents
-
view
1.235 -
download
0
Transcript of PPT
1
Networking Programming
2
Outline
• Web servers– HTTP Protocol
– Web Content
– CGI
• The Tiny Web Server
• Suggested Reading:– 12.5~12.6
3
• Clients and servers communicate using the HyperText Transfer Protocol (HTTP)– client and server establish TCP connection
– Client requests content
– Server responds with requested content
– client and server close connection (usually)
• Current version is HTTP/1.1
– RFC 2616, June, 1999.
Web servers
4
Web servers
webserver
HTTP request
HTTP response(content)
webclient
(browser)
5
• Web servers return content to clients
– content: a sequence of bytes with an
associated MIME (Multipurpose Internet Mail
Extensions) type
Web content
6
• Example MIME types
– text/html HTML page
– text/plain Unformatted text
– application/postscript Postcript document
– image/gif Binary image encoded in GIF format
– image/jpg Binary image encoded in JPG format
Web content
7
• The content returned in HTTP responses can be either static or dynamic– Static content:
• content stored in files and retrieved in response to an HTTP request
• Examples: HTML files, images, audio clips.
– Dynamic content: • content produced on-the-fly in response to an HTTP
request• Example: content produced by a program executed
by the server on behalf of the client.
Static and dynamic content
8
• Each file managed by a server has a unique name called a URL (Universal Resource Locator)
• URLs for static content:– http://www.cs.cmu.edu:80/index.html– http://www.cs.cmu.edu/index.html– http://www.cs.cmu.edu
• identifies a file called index.html, managed by a Web server at www.cs.cmu.edu that is listening on port 80.
URLs
9
• URLs for dynamic content:
– http://www.cs.cmu.edu:8000/cgi-bin/
adder?15000&213
• identifies an executable file called adder, managed
by a Web server at www.cs.cmu.edu that is listening
on port 8000, that should be called with two argument
strings: 15000 and 213.
URLs
10
• Example URL:
http://www.aol.com:80/index.html
• Clients use prefix (http://www.aol.com:80)
to infer:
– What kind of server to contact (Web server)
– Where the server is (www.aol.com)
– What port it is listening on (80)
How clients and servers use URLs
11
• Servers use suffix (/index.html) to:– Determine if request is for static or dynamic
content.• No hard and fast rules for this.
• Convention: executables reside in cgi-bin directory
– Find file on filesystem• Initial “/” in suffix denotes home directory for
requested content.
• Minimal suffix is “/”, which all servers expand to some default home page (e.g., index.html).
How clients and servers use URLs
12
//Client: open connection to serverunix> telnet www.aol.com 80//Telnet prints 3 lines to the terminalTrying 205.188.146.23...Connected to aol.com.Escape character is '^]'.//Client: request lineGET / HTTP/1.1//Client: required HTTP/1.1 HOST headerhost: www.aol.com//Client: empty line terminates headers
Anatomy of an HTTP transaction
13
//Server: response lineHTTP/1.0 200 OK//Server: followed by five response headersMIME-Version: 1.0Date: Mon, 08 Jan 2001 04:59:42 GMTServer: NaviServer/2.0 AOLserver/2.3.3//Server: expect HTML in the response body Content-Type: text/html//Server: expect 42,092 bytes in the resp bodyContent-Length: 42092//Server: empty line (“\r\n”) terminates hdrs
Anatomy of an HTTP transaction
14
//Server: first HTML line in response body<html> ... //Server: 766 lines of HTML not shown.
</html>//Server: last HTML line in response body//Server: closes connection Connection closed by foreign host. Client: closes connection and terminates unix>
Anatomy of an HTTP transaction
15
• Client sends request to server
• If request URI contains the string “/cgi-bin”,
then the server assumes that the request
is for dynamic content.
Serving dynamic content
client server
GET /cgi-bin/env.pl HTTP/1.1
16
• The server creates a
child process and
runs the program
identified by the URI
in that process
client server
env.pl
fork/exec
Serving dynamic content
17
• The child runs and generates the dynamic content.
• The server captures the content of the child and forwards it without modification to the client
client server
env.pl
content
content
Serving dynamic content
18
• How does the client pass program
arguments to the server?
• How does the server pass these arguments
to the child?
• How does the server pass other info
relevant to the request to the child?
Serving dynamic content
19
• How does the server capture the content
produced by the child?
• These issues are addressed by the
Common Gateway Interface (CGI)
specification.
Serving dynamic content
20
Serving dynamic content
client server
content
content
request
create
env.pl
21
• Question: – How does the client pass arguments to the
server?
• Answer: – The arguments are appended to the URI
• http://add.com/cgi-bin/adder?1&2• adder is the CGI program on the server that will do
the addition.• argument list starts with “?”• arguments separated by “&” • spaces represented by “%20”
Serving dynamic content
22
• Question:
– How does the server pass these arguments to
the child?
• Answer:
– In environment variable QUERY_STRING
• a single string containing everything after the “?”
• for add.com: QUERY_STRING = “1&2”
Serving dynamic content
23
Serving dynamic content
if ((buf = getenv("QUERY_STRING")) != NULL) {
p = strchr(buf, ’&’);
*p = ’\0’;
strcpy(arg1, buf);
strcpy(arg2, p+1);
n1 = atoi(arg1);
n2 = atoi(arg2);
}
24
• Question:
– How does the server pass other info relevant to
the request to the child?
• Answer:
– in a collection of environment variables defined
by the CGI spec.
Serving dynamic content
25
• Request-specific– QUERY_STRING (contains GET args)– SERVER_PORT
– REQUEST_METHOD (GET, POST, etc)– REMOTE_HOST (domain name of client)– REMOTE_ADDR (IP address of client)– CONTENT_TYPE (for POST, MIME type of the
request body )– CONTENT_LENGTH (for POST, length in bytes)
Some CGI environment variables
26
• Question: – How does the server capture the content
produced by the child?
• Answer: – The child generates its output on stdout.
Server uses dup2 to redirect stdout to its connected socket.
– Notice that only the child knows the type and size of the content.
– Thus the child (not the server) must generate the corresponding headers.
Serving dynamic content
27
/* Domain Name Service (DNS) host entry */struct hostent {/* official name of host */char *h_name; /* alias list */char **h_aliases; /* host address type */int h_addrtype; /* length of address */int h_length; /* list of addresses */char **h_addr_list;
}
28
/* Internet address */struct in_addr { /* 32-bit IP address */ unsigned int s_addr;
};
/* Generic socket address structure(for connect, bind, and accept)
*/struct sockaddr {/* protocol family */unsigned short sa_family ;/* address data */char sa_data[14];
}
29
/* Internet style socket address */struct sockaddr_in { /* Address family (AF_INET) */unsigned short sin_family; /* Port number */unsigned short sin_port; /* IP address */struct in_addr sin_addr;/* Pad to sizeof “struct sockaddr” */unsigned char sin_zero[8];
};
30
struct hostent *genhostbyname(const char *name);
struct hostent *genhostbyaddr(const char *addr, int
len,0);
int socket(int domain, int type, int protocol);
clientfd = socekt(AF_INET,SOCKET_STREAM, 0) ;
int connect(int sockfd, struct sockaddr *serv_addr, int addr_len);
31
int bind(int sockfd,
struct sockaddr *my_addr,
int addrlen);
int listen(int sockfd, int backlog) ;
int accept(int listenfd,
struct sockaddr *addr,
int addrlen) ;
32
1 /*
2 * tiny.c - A simple HTTP/1.0 Web server that uses the GET method
3 * to serve static and dynamic content.
4 */
5 #include "csapp.h"
6
7 void doit(int fd);
8 void read_requesthdrs(int fd);
The Tiny Web Server
33
9 int parse_uri(char *uri, char *filename, char
*cgiargs);
10 void serve_static(rio_t *rio, char *filename, int filesize);
11 void get_filetype(char *filename, char *filetype);
12 void serve_dynamic(rio_t *rio,char *filename,char*cgiargs);13 void clienterror(rio_t *rio, char *cause, char *errnum,
14 char *shortmsg, char *longmsg);
15
The Tiny Web Server
34
16 int main(int argc, char **argv)17 {18 int listenfd, connfd, port, clientlen;19 struct sockaddr_in clientaddr;2021 /* check command line args */22 if (argc != 2) {23 fprintf(stderr,"usage: %s <port>\n", argv
[0]);24 exit(1);25 }26 port = atoi(argv[1]);27
The Tiny Web Server
35
28 listenfd = open_listenfd(port);
29 while (1) {
30 clientlen = sizeof(clientaddr);
31 connfd = Accept(listenfd, (SA *) &clientaddr, &clientlen);
32 doit(connfd);
33 Close(connfd);
34 }
35 }
The Tiny Web Server
36
1 void doit(int fd)
2 {
3 int is_static;
4 struct stat sbuf;
5 char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE];
6 char filename[MAXLINE], cgiargs[MAXLINE];
7 rio_t rio;
8
The Tiny Web Server
37
9 /* read request line and headers */10 Rio_readinitb(&rio, fd)11 Rio_readlineb(&rio, buf, MAXLINE);12 sscanf(buf, "%s %s %s\n", method, uri, version);13 if (strcasecmp(method, "GET")) {14 clienterror(fd, method, "501", "Not
Implemented",15 "Tiny does not implement this method");16 return;17 }18 read_requesthdrs(&rio);19
The Tiny Web Server
38
20 /* parse URI from GET request */21 is_static = parse_uri(uri, filename, cgiargs);22 if (stat(filename, &sbuf) < 0) {23 clienterror(fd, filename, "404", "Not found",24 "Tiny couldn’t find this file");25 return;26 }27
The Tiny Web Server
39
28 if (is_static) { /* serve static content */29 if (!(S_ISREG(sbuf.st_mode)) ||
!(S_IRUSR & sbuf.st_mode)) {30 clienterror(fd, filename, "403", 31 "Forbidden","Tiny couldn’t read the
file");32 return;33 }34 serve_static(&rio, filename, sbuf.st_size);35 }
The Tiny Web Server
40
34 else { /* serve dynamic content */35 if (!(S_ISREG(sbuf.st_mode)) ||
!(S_IXUSR & sbuf.st_mode)) {36 clienterror(fd, filename, "403", "Forbidden",37 "Tiny couldn’t run the CGI program");38 return;39 }40 serve_dynamic(&rio, filename, cgiargs);41 }42 }
The Tiny Web Server
41
1 void clienterror(rio_t *fd, char *cause, char *errnum,2 char *shortmsg, char *longmsg)3 {4 char buf[MAXLINE], body[MAXBUF];56 /* build the HTTP response body */7 sprintf(body, "<html><title>Tiny Error</title>");8 sprintf(body, "%s<body bgcolor=""ffffff"">\r\n", body);9 sprintf(body, "%s%s: %s\r\n", body, errnum, shortmsg);10 sprintf(body, "%s<p>%s: %s\r\n", body, longmsg, cause);11 sprintf(body, "%s<hr><em>The Tiny Web server</em>\r\n", body);1213 /* print the HTTP response */14 sprintf(buf, "HTTP/1.0 %s %s\r\n", errnum, shortmsg);15 Rio_writen(fd, buf, strlen(buf));16 sprintf(buf, "Content-type: text/html\r\n");17 Rio_writen(fd, buf, strlen(buf));18 sprintf(buf, "Content-length: %d\r\n\r\n", strlen(body));19 Rio_writen(fd, buf, strlen(buf));20 Rio_writen(fd, body, strlen(body));21 }
42
1 void read_requesthdrs(rio_t *fd)2 {3 char buf[MAXLINE];45 Readline(fd, buf, MAXLINE);6 while(strcmp(buf, "\r\n"))7 Rio_readlineb(fd, buf, MAXLINE);8 return;9 }
The Tiny Web Server
43
1 int parse_uri(char *uri, char *filename, char *cgiargs)2 {3 char *ptr;45 if (!strstr(uri, "cgi-bin")) { /* static content */6 strcpy(cgiargs, "");7 strcpy(filename, ".");8 strcat(filename, uri);9 if (uri[strlen(uri)-1] == ’/’)10 strcat(filename, "home.html");11 return 1;12 }13 else { /* dynamic content */14 ptr = index(uri, ’?’);15 if (ptr) {16 strcpy(cgiargs, ptr+1);17 *ptr = ’\0’;18 }19 else20 strcpy(cgiargs, "");21 strcpy(filename, ".");22 strcat(filename, uri);23 return 0;24 }25 }
44
1 void serve_static(int fd, char *filename, int filesize)2 {3 int srcfd;4 char *srcp, filetype[MAXLINE], buf[MAXBUF];56 /* send response headers to client */7 get_filetype(filename, filetype);8 sprintf(buf, "HTTP/1.0 200 OK\r\n");9 sprintf(buf, "%sServer: Tiny Web Server\r\n", buf);10 sprintf(buf, "%sContent-length: %d\n", buf, filesize);11 sprintf(buf, "%sContent-type: %s\r\n\r\n", buf, filetype);12 Rio_writen(fd, buf, strlen(buf));1314 /* send response body to client */15 srcfd = Open(filename, O_RDONLY, 0);16 srcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);17 Close(srcfd);18 Rio_writen(fd, srcp, filesize);19 Munmap(srcp, filesize);20 }21
45
22 /*23 * get_filetype - derive file type from file name24 */25 void get_filetype(char *filename, char *filetype)26 {27 if (strstr(filename, ".html"))28 strcpy(filetype, "text/html");29 else if (strstr(filename, ".gif"))30 strcpy(filetype, "image/gif");31 else if (strstr(filename, ".jpg"))32 strcpy(filetype, "image/jpg");33 else34 strcpy(filetype, "text/plain");35 }
The Tiny Web Server
46
The Tiny Web Server1 void serve_dynamic(int fd, char *filename, char *cgiargs)2 {3 char buf[MAXLINE];45 /* return first part of HTTP response */6 sprintf(buf, "HTTP/1.0 200 OK\r\n");7 Rio_writen(fd, buf, strlen(buf));8 sprintf(buf, "Server: Tiny Web Server\r\n");9 Rio_writen(fd, buf, strlen(buf));1011 if (Fork() == 0) { /* child */12 /* real server would set all CGI vars here */13 setenv("QUERY_STRING", cgiargs, 1);14 Dup2(fd, STDOUT_FILENO); /* redirect output to client*/15 Execve(filename, NULL, environ); /* run CGI program */16 }17 Wait(NULL); /* parent reaps child */18 }