90 likes | 316 Views
Web Server Architecture. Web Server Architecture. Complex Helpful to consider best design practices Items to consider Response Time Use concurrency Features HTTP/1.1 CGI. Web Server Architecture. Client. use dup2 to redirect stdin and stdout back to the web server. Web Server.
E N D
Web Server Architecture • Complex • Helpful to consider best design practices • Items to consider • Response Time • Use concurrency • Features • HTTP/1.1 • CGI
Web Server Architecture Client use dup2 to redirect stdin and stdout back to the web server Web Server http stdin CGI program stdout
while(1) sock = deQ() recv() process send() close(sock) while(1) sock = deQ() recv() process send() close(sock) while(1) sock = deQ() recv() process send() close(sock) while(1) sock = deQ() recv() process send() close(sock) while(1) sock = deQ() recv() process send() close(sock) while(1) sock = deQ() recv() process send() close(sock) while(1) sock = deQ() read() process write() close(sock) Web Server Architecture Main Thread for(j=0;j<nthread; pthread_create() while(1) newsock = accept() enQ(newsock) Thread Pool Connection Queue Connect() Client Notice the Producer-Consumer Relationships
Web Server Architecture • Minimize Overhead • Launch threads that stay around • Use semaphores to eliminate busy wait • Be Careful with shared data structures • Connection Queue • Producer - main thread • Consumers - connection handling threads
Web Server Architecture #include … Queue connectionQ; main() { // Use signal handlers to shut down nicely SetUpSignalHandlers() SetUpSocket() for(j = 0; j < nthreads; j++) pthread_create(thread[j], HandleConn,args) pthread_create(logthread, LogWriter, args) for(;;) { sock = accept(…) connectionQ.enQ(sock) } } void *HandleConn(void *args) { while(we are still running) { // This call should block until I have a connection // You will need producer-consumer code sock = connectionQ.deQ(); recv(sock, message…) processURL() if (cgi) DoCGI() else { read file send(sock, response…) close(sock) } } }
Shared Data Structures • Queue of socket connections • Strategy • Write a template queue that inherits from the STL queue class • Override the enqueue and dequeue methods init(EmptySem, QSIZE); init(PresentSem, 0); init(mutex, 1); template <class Elem> void MyQueue<Elem>::enqueue(const Elem &Item) { wait(EmptySem) wait(mutex) super.enqueue(Item) post(mutex) post(PresentSem) } template <class Elem> Elem MyQueue<Elem>::dequeue(void) { wait(PresentSem) wait(mutex) super.dequeue(Item) signal(mutex) signal(EmptySem) }
Sample Exchange GET /path/file.html HTTP/1.1 Host: www.host1.com:80 [blank line here] HTTP/1.0 200 OK Date: Fri, 31 Dec 1999 23:59:59 GMT Content-Type: text/html Content-Length: 1354 <html> <body> <h1>Happy New Year!</h1> (more fiile contents) . . . </body> </html>
Web Request Processing • Receive the request • Process the URL • Append URL to DocumentRoot • Use stat to determine if file exists or if it is a directory • Send Response GET /CS360 HTTP/1.1 Host: star.cs.byu.edu HTTP/1.1 200 OK Content-type: text/html, image/jpg or other mime type Content-length: #bytes as reported by stat Binary Data (Write a loop that reads a buffer full of data and writes it to the socket until EOF)