adamc@116: #include adamc@116: adamc@116: #include adamc@116: #include adamc@116: #include adamc@116: #include adamc@116: adamc@117: #include "lacweb.h" adamc@117: adamc@116: int lw_port = 8080; adamc@116: int lw_backlog = 10; adamc@116: int lw_bufsize = 1024; adamc@116: adamc@117: void lw_handle(lw_context, char*); adamc@116: adamc@116: static void worker(int sock) { adamc@116: char buf[lw_bufsize+1], *back = buf, *s; adamc@116: adamc@116: while (1) { adamc@116: int r = recv(sock, back, lw_bufsize - (back - buf), 0); adamc@116: adamc@116: if (r < 0) { adamc@116: fprintf(stderr, "Recv failed\n"); adamc@116: close(sock); adamc@116: return; adamc@116: } adamc@116: adamc@116: if (r == 0) { adamc@116: printf("Connection closed.\n"); adamc@116: close(sock); adamc@116: return; adamc@116: } adamc@116: adamc@116: printf("Received %d bytes.\n", r); adamc@116: adamc@116: back += r; adamc@116: *back = 0; adamc@116: adamc@116: if (s = strstr(buf, "\r\n\r\n")) { adamc@116: char *cmd, *path; adamc@117: lw_context ctx; adamc@116: adamc@116: *s = 0; adamc@116: adamc@117: if (!(s = strstr(buf, "\r\n"))) { adamc@116: fprintf(stderr, "No newline in buf\n"); adamc@116: close(sock); adamc@116: return; adamc@116: } adamc@116: adamc@116: *s = 0; adamc@116: cmd = s = buf; adamc@116: adamc@116: if (!strsep(&s, " ")) { adamc@116: fprintf(stderr, "No first space in HTTP command\n"); adamc@116: close(sock); adamc@116: return; adamc@116: } adamc@116: adamc@116: if (strcmp(cmd, "GET")) { adamc@116: fprintf(stderr, "Not ready for non-get command: %s\n", cmd); adamc@116: close(sock); adamc@116: return; adamc@116: } adamc@116: adamc@116: path = s; adamc@116: if (!strsep(&s, " ")) { adamc@116: fprintf(stderr, "No second space in HTTP command\n"); adamc@116: close(sock); adamc@116: return; adamc@116: } adamc@116: adamc@116: printf("Serving URI %s....\n", path); adamc@117: adamc@136: ctx = lw_init(1024, 1024); adamc@117: lw_write (ctx, "HTTP/1.1 200 OK\r\n"); adamc@117: lw_write(ctx, "Content-type: text/html\r\n\r\n"); adamc@117: lw_write(ctx, ""); adamc@117: lw_handle(ctx, path); adamc@117: lw_write(ctx, ""); adamc@117: adamc@117: lw_send(ctx, sock); adamc@116: adamc@136: lw_free(ctx); adamc@116: printf("Done with client.\n\n"); adamc@116: close(sock); adamc@116: return; adamc@116: } adamc@116: } adamc@116: } adamc@102: adamc@102: int main() { adamc@116: // The skeleton for this function comes from Beej's sockets tutorial. adamc@116: int sockfd, new_fd; // listen on sock_fd, new connection on new_fd adamc@116: struct sockaddr_in my_addr; adamc@116: struct sockaddr_in their_addr; // connector's address information adamc@116: int sin_size, yes = 1; adamc@116: adamc@116: sockfd = socket(PF_INET, SOCK_STREAM, 0); // do some error checking! adamc@116: adamc@116: if (sockfd < 0) { adamc@116: fprintf(stderr, "Listener socket creation failed\n"); adamc@116: return 1; adamc@116: } adamc@116: adamc@116: if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0) { adamc@116: fprintf(stderr, "Listener socket option setting failed\n"); adamc@116: return 1; adamc@116: } adamc@116: adamc@116: my_addr.sin_family = AF_INET; // host byte order adamc@116: my_addr.sin_port = htons(lw_port); // short, network byte order adamc@116: my_addr.sin_addr.s_addr = INADDR_ANY; // auto-fill with my IP adamc@116: memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero); adamc@116: adamc@116: if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) < 0) { adamc@116: fprintf(stderr, "Listener socket bind failed\n"); adamc@116: return 1; adamc@116: } adamc@116: adamc@116: if (listen(sockfd, lw_backlog) < 0) { adamc@116: fprintf(stderr, "Socket listen failed\n"); adamc@116: return 1; adamc@116: } adamc@116: adamc@116: sin_size = sizeof their_addr; adamc@116: adamc@116: printf("Listening on port %d....\n", lw_port); adamc@116: adamc@116: while (1) { adamc@116: new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); adamc@116: adamc@116: if (new_fd < 0) { adamc@116: fprintf(stderr, "Socket accept failed\n"); adamc@116: return 1; adamc@116: } adamc@116: adamc@116: printf("Accepted connection.\n"); adamc@116: worker(new_fd); adamc@116: } adamc@102: }