aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Isom <coder@kyleisom.net>2012-05-21 21:36:37 +0300
committerKyle Isom <coder@kyleisom.net>2012-05-21 21:36:37 +0300
commita0bac7d66bdf1f42409045a95b9224223004452d (patch)
tree2164a28a967dc5879f02fc3c55f086b404a53086
parentef72b098ebaa474b86fb21440d6eeb0943670c60 (diff)
downloadsrvwd-a0bac7d66bdf1f42409045a95b9224223004452d.tar.gz
srvwd-a0bac7d66bdf1f42409045a95b9224223004452d.tar.bz2
srvwd-a0bac7d66bdf1f42409045a95b9224223004452d.zip
add separate source for content-type handling
-rw-r--r--Makefile.in10
-rw-r--r--content.c122
-rw-r--r--content.h40
-rw-r--r--response.c39
4 files changed, 185 insertions, 26 deletions
diff --git a/Makefile.in b/Makefile.in
index 3849817..f4104fe 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,7 +1,7 @@
-VERSION := 1.4.2-rc3
+VERSION := 1.4.3
CC ?= gcc
TARGET := srvwd
-OBJS := response.o request.o server.o
+OBJS := response.o request.o server.o content.o
LIBS := -lc
LIBS += $OS_LIBS
@@ -24,7 +24,8 @@ clean:
-rm -f $(TARGET)-$(VERSION).tgz
$(TARGET): $(TARGET).o $(OBJS)
- ${CC} -o $(TARGET) ${CFLAGS} ${LDFLAGS} $(LIBS) $(OBJS) $(TARGET).o
+ @echo "AR $(TARGET)"
+ @${CC} -o $(TARGET) ${CFLAGS} ${LDFLAGS} $(LIBS) $(OBJS) $(TARGET).o
analyze:
clang --analyze ${CFLAGS} *.c
@@ -61,6 +62,7 @@ tags:
ctags *.[ch]
.c.o:
- $(CC) -c ${CFLAGS} $?
+ @echo "CC $?"
+ @$(CC) -c ${CFLAGS} $?
.PHONY: clean all install lint uninstall dist distclean htmldoc tags
diff --git a/content.c b/content.c
new file mode 100644
index 0000000..92d0087
--- /dev/null
+++ b/content.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2012 Kyle Isom <kyle@tyrfingr.is>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#include <sys/types.h>
+#ifdef _BSD_SOURCE /* _BSD_SOURCE is only defined on */
+#include <bsd/string.h> /* linux hosts, we need to use the */
+#endif /* BSD string library */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "content.h"
+#include "srvwd.h"
+
+
+/*
+ * returns an enum representing the content type
+ */
+CONTENT_TYPE
+content_type(char *filename)
+{
+ CONTENT_TYPE ct = CT_UNKNOWN;
+ char *extptr;
+ size_t i;
+
+ for (i = strlen(filename); i > 0; --i)
+ if ('.' == i)
+ break;
+
+ extptr = filename + i;
+ if (NULL != strstr(extptr, SRVWD_EXT_PLAIN))
+ ct = CT_TEXT;
+ else if (NULL != strstr(extptr, SRVWD_EXT_HTML))
+ ct = CT_HTML;
+ else if (NULL != strstr(extptr, SRVWD_EXT_CSS))
+ ct = CT_CSS;
+ else if (NULL != strstr(extptr, SRVWD_EXT_PDF))
+ ct = CT_PDF;
+ else
+ ct = CT_HTML;
+
+ return ct;
+}
+
+
+/*
+ * translate a CONTENT_TYPE enum to a string representing the content type
+ */
+char *
+content_type_to_str(CONTENT_TYPE ct)
+{
+ char *ct_str = NULL;
+ int error = 0;
+
+ ct_str = calloc(SRVWD_BUFSIZE, sizeof ct_str);
+ if (NULL == ct_str)
+ return ct_str;
+
+ switch (ct) {
+ case CT_TEXT:
+ if (strlcpy(ct_str, SRVWD_CT_PLAIN, SRVWD_BUFSIZE) < 1)
+ error = 1;
+ break;
+ case CT_HTML:
+ if (strlcpy(ct_str, SRVWD_CT_HTML, SRVWD_BUFSIZE) < 1)
+ error = 1;
+ break;
+ case CT_CSS:
+ if (strlcpy(ct_str, SRVWD_CT_CSS, SRVWD_BUFSIZE) < 1)
+ error = 1;
+ break;
+ case CT_PDF:
+ if (strlcpy(ct_str, SRVWD_CT_PDF, SRVWD_BUFSIZE) < 1)
+ error = 1;
+ break;
+ case CT_UNKNOWN:
+ error = 1;
+ break;
+ default:
+ /* NOT REACHED */
+ error = 1;
+ break;
+ }
+
+ if (error) {
+ free(ct_str);
+ ct_str = NULL;
+ }
+
+ return ct_str;
+}
+
+
+/*
+ * front end to content type code
+ */
+char *
+get_content_type(char *filename)
+{
+ char *ct_str;
+ CONTENT_TYPE ct;
+
+ ct = content_type(filename);
+ ct_str = content_type_to_str(ct);
+
+ return ct_str;
+}
diff --git a/content.h b/content.h
new file mode 100644
index 0000000..0f1e2f3
--- /dev/null
+++ b/content.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 Kyle Isom <kyle@tyrfingr.is>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#define SRVWD_EXT_PLAIN ".txt"
+#define SRVWD_EXT_HTML ".html"
+#define SRVWD_EXT_CSS ".css"
+#define SRVWD_EXT_PDF ".pdf"
+#define SRVWD_CT_PLAIN "text/plain"
+#define SRVWD_CT_CSS "text/css"
+#define SRVWD_CT_HTML "text/html"
+#define SRVWD_CT_PDF "application/pdf"
+
+
+enum E_CONTENT_TYPE {
+ CT_UNKNOWN,
+ CT_HTML,
+ CT_TEXT,
+ CT_CSS,
+ CT_PDF
+};
+
+typedef enum E_CONTENT_TYPE CONTENT_TYPE;
+
+CONTENT_TYPE content_type(char *);
+char *content_type_to_str(CONTENT_TYPE);
+char *get_content_type(char *);
diff --git a/response.c b/response.c
index b97041b..31056a9 100644
--- a/response.c
+++ b/response.c
@@ -28,9 +28,11 @@
#include <fcntl.h>
#include <libgen.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include "content.h"
#include "response.h"
#include "request.h"
#include "srvwd.h"
@@ -80,42 +82,35 @@ send_client_file(int clientfd, char *filename, request_type rtype)
"content-length: %d\r\nconnection: close\r\n"
"srvwd-version: %s\r\n\r\n";
char buf[SRVWD_CHUNKSIZE + 1];
- char content_type[SRVWD_BUFSIZE];
- char *extptr;
+ char *ct_str;
struct stat st;
FILE *filep;
- size_t chunk, i;
+ size_t chunk;
size_t progress;
size_t read_sz;
int headerslen;
- memset(content_type, 0, SRVWD_BUFSIZE);
- for (i = strlen(filename); i > 0; --i)
- if ('.' == i)
- break;
-
- if (i == strlen(filename))
- snprintf(content_type, SRVWD_BUFSIZE - 1, SRVWD_CT_PLAIN);
-
- extptr = filename + i;
- if (NULL != strstr(extptr, SRVWD_EXT_PLAIN))
- snprintf(content_type, SRVWD_BUFSIZE - 1, SRVWD_CT_PLAIN);
- else if (NULL != strstr(extptr, SRVWD_EXT_HTML))
- snprintf(content_type, SRVWD_BUFSIZE - 1, SRVWD_CT_HTML);
- else if (NULL != strstr(extptr, SRVWD_EXT_CSS))
- snprintf(content_type, SRVWD_BUFSIZE - 1, SRVWD_CT_CSS);
- else
- snprintf(content_type, SRVWD_BUFSIZE - 1, SRVWD_CT_HTML);
-
if (-1 == stat(filename, &st)) {
warn("send client file - stat failed");
send_client_404(clientfd, rtype);
return;
}
- snprintf(buf, SRVWD_CHUNKSIZE, headerstpl, content_type, st.st_size,
+ ct_str = get_content_type(filename);
+ if (NULL == ct_str) {
+ warnx("invalid content type");
+ send_client_404(clientfd, rtype);
+ return;
+ }
+ snprintf(buf, SRVWD_CHUNKSIZE, headerstpl, ct_str, st.st_size,
srvwd_VERSION);
headerslen = strlen(buf);
+ warnx("content-type: %s", ct_str);
+
+ if (NULL != ct_str) {
+ free(ct_str);
+ ct_str = NULL;
+ }
filep = fopen(filename, "r");
if (NULL == filep || -1 == ferror(filep)) {