websrv.c

00001 /*
00002  * Copyright (c) 2010 Jiri Svoboda
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00036 #include <stdio.h>
00037 
00038 #include <net/in.h>
00039 #include <net/inet.h>
00040 #include <net/socket.h>
00041 
00042 #include <str.h>
00043 
00044 #define PORT_NUMBER 8080
00045 
00047 #define BUFFER_SIZE 1024
00048 static char buf[BUFFER_SIZE];
00049 
00051 static const char *response_msg =
00052     "HTTP/1.0 200 OK\r\n"
00053     "\r\n"
00054     "<h1>Hello from HelenOS!</h1>\r\n";
00055 
00056 int main(int argc, char *argv[])
00057 {
00058         struct sockaddr_in addr;
00059         struct sockaddr_in raddr;
00060 
00061         socklen_t raddr_len;
00062 
00063         int listen_sd, conn_sd;
00064         int rc;
00065 
00066         size_t response_size;
00067 
00068         addr.sin_family = AF_INET;
00069         addr.sin_port = htons(PORT_NUMBER);
00070 
00071         rc = inet_pton(AF_INET, "127.0.0.1", (void *) &addr.sin_addr.s_addr);
00072         if (rc != EOK) {
00073                 printf("Error parsing network address.\n");
00074                 return 1;
00075         }
00076 
00077         printf("Creating socket.\n");
00078 
00079         listen_sd = socket(PF_INET, SOCK_STREAM, 0);
00080         if (listen_sd < 0) {
00081                 printf("Error creating listening socket.\n");
00082                 return 1;
00083         }
00084 
00085         rc = bind(listen_sd, (struct sockaddr *) &addr, sizeof(addr));
00086         if (rc != EOK) {
00087                 printf("Error binding socket.\n");
00088                 return 1;
00089         }
00090 
00091         rc = listen(listen_sd, 1);
00092         if (rc != EOK) {
00093                 printf("Error calling listen() (%d).\n", rc);
00094                 return 1;
00095         }
00096 
00097         response_size = str_size(response_msg);
00098 
00099         printf("Listening for connections at port number %u.\n", PORT_NUMBER);
00100         while (true) {
00101                 raddr_len = sizeof(raddr);
00102                 conn_sd = accept(listen_sd, (struct sockaddr *) &raddr,
00103                     &raddr_len);
00104 
00105                 if (conn_sd < 0) {
00106                         printf("accept() failed.\n");
00107                         return 1;
00108                 }
00109 
00110                 printf("Accepted connection, sd=%d.\n", conn_sd);
00111 
00112                 printf("Wait for client request\n");
00113 
00114                 /* Really we should wait for a blank line. */
00115                 rc = recv(conn_sd, buf, BUFFER_SIZE, 0);
00116                 if (rc < 0) {
00117                         printf("recv() failed\n");
00118                         return 1;
00119                 }
00120 
00121                 /* Send a canned response. */
00122                 printf("Send response...\n");
00123                 rc = send(conn_sd, (void *) response_msg, response_size, 0);
00124                 if (rc < 0) {
00125                         printf("send() failed.\n");
00126                         return 1;
00127                 }
00128 
00129                 rc = closesocket(conn_sd);
00130                 if (rc != EOK) {
00131                         printf("Error closing connection socket: %d\n", rc);
00132                         return 1;
00133                 }
00134 
00135                 printf("Closed connection.\n");
00136         }
00137 
00138         /* Not reached. */
00139         return 0;
00140 }
00141 

Generated on Thu Jun 2 07:45:43 2011 for HelenOS/USB by  doxygen 1.4.7