summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle K <kylek389@gmail.com>2011-09-15 02:14:13 -0500
committerKamil Kaminski <kamilkss@gmail.com>2011-09-15 02:14:13 -0500
commita9b6eba2f0767604e7a9dc3c83de5e330a97bf83 (patch)
tree97221e5cd03a3a45bf03de2e55a2a79da9f033e6
parent76765068743a956fb68d9b942426bcd43e84f092 (diff)
downloadsandbox-a9b6eba2f0767604e7a9dc3c83de5e330a97bf83.tar.gz
sandbox-a9b6eba2f0767604e7a9dc3c83de5e330a97bf83.tar.bz2
sandbox-a9b6eba2f0767604e7a9dc3c83de5e330a97bf83.zip
tcpclient2: import
-rw-r--r--tcpserver2.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/tcpserver2.c b/tcpserver2.c
new file mode 100644
index 0000000..629feef
--- /dev/null
+++ b/tcpserver2.c
@@ -0,0 +1,164 @@
+/* Kamil Kaminski
+ * kkamin8@uic.edu
+ *
+ *
+ * Note: implement content-size, if index.html is not present, generate a page
+ * that lists root directory, you can use select() to deal with multiple
+ * requests instead of forking
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/wait.h>
+
+int main(int argc, char **argv)
+{
+ if (argc != 3)
+ {
+ fprintf(stderr, "usage: %s <port> <dir>\n", argv[0]);
+ exit(1);
+ }
+
+ int server_sockfd, ret;
+
+ if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+ {
+ perror("socket");
+ close(server_sockfd);
+ exit(-1);
+ }
+
+ /* allow fast reuse of ports */
+ int reuse_true = 1;
+ setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse_true,
+ sizeof(reuse_true));
+
+ struct sockaddr_in addr;
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(atoi(argv[1]));
+ addr.sin_addr.s_addr = INADDR_ANY;
+
+ if (bind(server_sockfd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
+ {
+ perror("bind");
+ exit(-1);
+ }
+
+ if (listen(server_sockfd, 0) == -1)
+ {
+ perror("listen");
+ exit(-1);
+ }
+
+ while (1)
+ {
+ int sockfd;
+ struct sockaddr_in remote_addr;
+ unsigned int socklen = sizeof(remote_addr);
+ sockfd = accept(server_sockfd, (struct sockaddr *) &remote_addr, &socklen);
+ if (sockfd == -1)
+ {
+ perror("accept");
+ continue;
+ }
+
+ char ipstr[INET6_ADDRSTRLEN];
+ inet_ntop(remote_addr.sin_family, &remote_addr.sin_addr, ipstr, sizeof(ipstr));
+ printf("got connection from %s\n", ipstr);
+
+ /* read the http header request from the client */
+ char recv_buff[512] = { 0 };
+ if ((ret = recv(sockfd, recv_buff, sizeof(recv_buff), 0)) < 0)
+ {
+ perror("recv");
+ shutdown(sockfd, SHUT_RDWR);
+ close(sockfd);
+ continue;
+ }
+ /* printf("%s", recv_buff); */
+
+ char *p;
+ if (!(p = strstr(recv_buff, "GET")))
+ continue;
+
+ char filereq[100] = { 0 };
+ sscanf(p, "GET %s HTTP/1.*[01]\r\n", filereq);
+ printf("requested file: \"%s\"\n", filereq);
+
+ char path[200] = { 0 };
+ sprintf(path, "%s%s", argv[2], filereq[strlen(filereq) - 1] == '/' ?
+ "/index.html" : filereq);
+ printf("path is: \"%s\"\n", path);
+
+ struct stat stat_buff;
+ if (stat(path, &stat_buff) == -1)
+ {
+ perror("stat");
+ char err[] = "HTTP/1.0 404 Not Found\r\n\r\n";
+ send(sockfd, err, sizeof(err), 0);
+ }
+ else
+ {
+ pid_t pid;
+ if ((pid = fork()) == 0)
+ {
+ char http_header[100] = { 0 };
+ char *p = strstr(path, "."), *type = NULL;
+ if (p)
+ {
+ if (strcmp(p, ".html") == 0)
+ type = "Content-Type: text/html\r\n";
+ else if (strcmp(p, ".gif") == 0)
+ type = "Content-Type: image/gif\r\n";
+ else if (strcmp(p, ".png") == 0)
+ type = "Content-Type: image/png\r\n";
+ else if (strcmp(p, ".jpeg") == 0 || strcmp(p, ".jpg") == 0)
+ type = "Content-Type: image/jpeg\r\n";
+ else if (strcmp(p, ".pdf") == 0)
+ type = "Content-Type: application/pdf\r\n";
+ }
+ sprintf(http_header, "%s%s\r\n", "HTTP/1.1 200 OK\r\n", type ? type : "\r\n");
+ /* printf("http header:\n\"%s\"\n", http_header); */
+
+ FILE *fp = fopen(path, "r");
+ char *file = (char *) malloc(sizeof(char) * (stat_buff.st_size + strlen(http_header)));
+ if (file && fp)
+ {
+ memcpy(file, http_header, strlen(http_header));
+ fread(file + strlen(http_header), stat_buff.st_size, sizeof(char), fp);
+ send(sockfd, file, stat_buff.st_size + strlen(http_header), 0);
+ free(file);
+ }
+ fclose(fp);
+ shutdown(sockfd, SHUT_RDWR);
+ close(sockfd);
+ exit(0);
+ }
+ else if (pid > 0)
+ {
+ wait(NULL);
+ }
+ else
+ {
+ perror("fork");
+ shutdown(sockfd, SHUT_RDWR);
+ close(sockfd);
+ }
+ }
+ }
+
+ shutdown(server_sockfd, SHUT_RDWR);
+ close(server_sockfd);
+}
+