Added directory index

Fri, 30 Dec 2011 17:50:05 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 30 Dec 2011 17:50:05 +0100
changeset 12
34aa8001ea53
parent 11
24d804a2799f
child 13
1fdbf4170ef4

Added directory index

src/server/conf.c file | annotate | diff | comparison | revisions
src/server/httprequest.c file | annotate | diff | comparison | revisions
src/server/object.c file | annotate | diff | comparison | revisions
src/server/service.c file | annotate | diff | comparison | revisions
src/server/service.h file | annotate | diff | comparison | revisions
src/server/ws-fn.c file | annotate | diff | comparison | revisions
templates/conf/obj.conf file | annotate | diff | comparison | revisions
--- a/src/server/conf.c	Fri Dec 30 15:19:16 2011 +0100
+++ b/src/server/conf.c	Fri Dec 30 17:50:05 2011 +0100
@@ -132,7 +132,7 @@
     /* create object config */
     ObjectConfParser parser;
     HTTPObjectConfig *conf = calloc(sizeof(HTTPObjectConfig), 1);
-    conf->pool = pool_create();
+    conf->pool = pool_create();   
     parser.conf = conf;
 
     FILE *in = fopen("conf/obj.conf", "r");
--- a/src/server/httprequest.c	Fri Dec 30 15:19:16 2011 +0100
+++ b/src/server/httprequest.c	Fri Dec 30 17:50:05 2011 +0100
@@ -325,7 +325,6 @@
     for(int i=NCX_DI(rq);i<dt->ndir;i++) {
         directive *d = dt->dirs[i];
 
-        printf("execute [%s]\n", d->func->name);
         ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
 
         /* check for name or ppath */
@@ -458,14 +457,30 @@
     }
 
     int ret = rq->context.last_req_code;
+    char *content_type = NULL;
     for(int i=NCX_OI(rq);i>=0;i--) {
-        httpd_object *obj = objset->obj[i];
+        httpd_object *obj = objset->obj[i];   
         dtable *dt = object_get_dtable(obj, NSAPIService);
 
         // execute directives
         for(int j=0;j<dt->ndir;j++) {
             directive *d = dt->dirs[j];
 
+            /* check type parameter */           
+            char *dtp = pblock_findkeyval(pb_key_type, d->param);
+            if(dtp) {
+                /* type parameter for directive */
+                if(!content_type) {
+                    content_type = pblock_findkeyval(
+                            pb_key_content_type,
+                            rq->rq.srvhdrs);
+                }
+                /* compare types */
+                if(strcmp(dtp, content_type) != 0) {
+                    continue;
+                }
+            }
+
             ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
             if(ret != REQ_NOACTION) {
                 if(ret == REQ_PROCESSING) {
--- a/src/server/object.c	Fri Dec 30 15:19:16 2011 +0100
+++ b/src/server/object.c	Fri Dec 30 17:50:05 2011 +0100
@@ -58,7 +58,17 @@
 void object_add_directive(httpd_object *obj, directive *dir, int dt) {
     dtable *l = object_get_dtable(obj, dt);
     // allocate space for the new directive
-    l->dirs = realloc(l->dirs, (l->ndir+1)*sizeof(directive*));
+
+    l->dirs = realloc(l->dirs, (l->ndir+1)*sizeof(void*));
+    /* TODO: aus irgend einem Grund funktioniert realloc nicht. warum?? */
+    
+    directive **drs = malloc((l->ndir+1)*sizeof(void*));
+    for(int i=0;i<l->ndir;i++) {
+        drs[i] = l->dirs[i];
+    }
+    free(l->dirs);
+    l->dirs = drs;
+
     // add directive
     l->dirs[l->ndir] = dir;
     l->ndir++;
--- a/src/server/service.c	Fri Dec 30 15:19:16 2011 +0100
+++ b/src/server/service.c	Fri Dec 30 17:50:05 2011 +0100
@@ -28,6 +28,8 @@
 
 #include <stdio.h>
 #include <errno.h>
+#include <sys/file.h>
+#include <sys/stat.h>
 
 #include "service.h"
 #include "io.h"
@@ -35,6 +37,7 @@
 #include "protocol.h"
 
 #include <sys/sendfile.h>
+#include "strbuf.h"
 
 // TODO: system sendfile Abstraktionen in neue Datei auslagern
 /*
@@ -144,3 +147,81 @@
     net_write(sn->csd, "Hello World!\n", 13);
     return REQ_PROCEED;
 }
+
+int service_index(pblock *pb, Session *sn, Request *rq) {
+    printf("service_index\n");
+
+    char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
+    char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
+
+    sstr_t r_uri = sstr(uri);
+
+    /* open the file */
+    int fd = open(ppath, O_RDONLY);
+    if(fd < 0) {
+        perror("service_index: open");
+
+        int status = 500;
+        switch(errno) {
+            case EACCES: {
+                status = 403;
+                break;
+            }
+            case ENOENT: {
+                status = 404;
+                break;
+            }
+        }
+        protocol_status(sn, rq, status, NULL);
+        printf("REQ_ABORTED\n");
+        return REQ_ABORTED;
+    }
+
+    DIR *dir = fdopendir(fd);
+    if(dir == NULL) {
+        protocol_status(sn, rq, 500, NULL);
+        printf("DIR is null\n");
+        return REQ_ABORTED;
+    }
+
+    sbuf_t *out = sbuf_new(1024); /* output buffer */
+
+    /* write html header  */
+    sbuf_puts(out, "<html>\n<head>\n<title>Index of ");
+    sbuf_puts(out, uri);
+    sbuf_puts(out, "</title>\n</head><body>\n<h1>Index of ");
+    sbuf_puts(out, uri);
+    sbuf_puts(out, "</h1><hr>\n\n");
+
+    struct dirent *f;
+    while((f = readdir(dir)) != NULL) {
+        if(strcmp(f->d_name, ".") == 0 || strcmp(f->d_name, "..") == 0) {
+            continue;
+        }
+
+        sstr_t filename = sstr(f->d_name);
+
+        sbuf_puts(out, "<a href=\"");
+        sbuf_append(out, r_uri);
+        sbuf_append(out, filename);
+        sbuf_puts(out, "\">");
+        sbuf_append(out, filename);
+        sbuf_puts(out, "</a><br>\n");
+    }
+
+    sbuf_puts(out, "\n</body>\n</html>\n");
+
+    /* send stuff to client */
+    pblock_removekey(pb_key_content_type, rq->srvhdrs);
+    pblock_kvinsert(pb_key_content_type, "text/html", 9, rq->srvhdrs);
+    pblock_nninsert("content-length", out->length, rq->srvhdrs);
+    protocol_status(sn, rq, 200, NULL);
+    http_start_response(sn, rq);
+
+    net_write(sn->csd, out->ptr, out->length);
+
+    /* close */
+    closedir(dir);
+
+    return REQ_PROCEED;
+}
--- a/src/server/service.h	Fri Dec 30 15:19:16 2011 +0100
+++ b/src/server/service.h	Fri Dec 30 17:50:05 2011 +0100
@@ -39,6 +39,7 @@
 
 int service_hello(pblock *pb, Session *sn, Request *rq);
 
+int service_index(pblock *pb, Session *sn, Request *rq);
 
 #ifdef	__cplusplus
 }
--- a/src/server/ws-fn.c	Fri Dec 30 15:19:16 2011 +0100
+++ b/src/server/ws-fn.c	Fri Dec 30 17:50:05 2011 +0100
@@ -37,6 +37,7 @@
     { "assign-name", assign_name, NULL, 0},
     { "type-by-extension", object_type_by_extension, NULL, 0},
     { "send-file", send_file, NULL, 0},
+    { "common-index", service_index, NULL, 0},
     { "service-hello", service_hello, NULL, 0},
     {NULL, NULL, NULL, 0}
 };
--- a/templates/conf/obj.conf	Fri Dec 30 15:19:16 2011 +0100
+++ b/templates/conf/obj.conf	Fri Dec 30 17:50:05 2011 +0100
@@ -7,6 +7,7 @@
 <Object name="default">
 NameTrans fn="assign-name" from="/hello" name="hello"
 ObjectType fn="type-by-extension"
+Service fn="common-index" type="internal/directory"
 Service fn="send-file"
 </Object>
 

mercurial