src/server/safs/service.c

changeset 54
3a1d5a52adfc
parent 48
37a512d7b8f6
child 55
b7908bf38f9f
--- a/src/server/safs/service.c	Fri Mar 01 22:44:54 2013 +0100
+++ b/src/server/safs/service.c	Sat Mar 16 23:11:34 2013 +0100
@@ -34,6 +34,7 @@
 #include "../util/io.h"
 #include "../util/pblock.h"
 #include "../daemon/protocol.h"
+#include "../daemon/vfs.h"
 
 #include <sys/sendfile.h>
 #include "../util/strbuf.h"
@@ -54,44 +55,29 @@
  *
  * adds content-length header and starts the response
  *
- * return the file descriptor or -1
+ * return the opened file
  */
-int prepare_service_file(Session *sn, Request *rq) {
+SYS_FILE prepare_service_file(Session *sn, Request *rq, struct stat *s) {
     char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
 
     /* open the file */
-    int fd = open(ppath, O_RDONLY);
-    if(fd < 0) {
-        //perror("prepare_service_file: open");
-
-        int status = 500;
-        int en = errno;
-        switch(en) {
-            case EACCES: {
-                status = 403;
-                break;
-            }
-            case ENOENT: {
-                status = 404;
-                break;
-            }
-        }
-        protocol_status(sn, rq, status, NULL);
-        return -1;
+    VFSContext *vfs = vfs_request_context(sn, rq);
+    SYS_FILE fd = vfs_open(vfs, ppath, O_RDONLY);
+    if(!fd) {
+        // vfs_open sets http status code
+        return NULL;
     }
 
     /* get stat */
-    struct stat stat;
-    if (fstat(fd, &stat) != 0) {
+    if (vfs_fstat(vfs, fd, s) != 0) {
         //perror("prepare_service_file: stat");
-
         protocol_status(sn, rq, 500, NULL);
-        return -1;
+        return NULL;
     }
 
     /* add content-length header*/
     char contentLength[32];
-    int len = snprintf(contentLength, 32, "%d", stat.st_size);
+    int len = snprintf(contentLength, 32, "%d", s->st_size);
 
     pblock_kvinsert(pb_key_content_length, contentLength, len, rq->srvhdrs);
 
@@ -103,21 +89,33 @@
 }
 
 int send_file(pblock *pb, Session *sn, Request *rq) {
-    int fd = prepare_service_file(sn, rq);
-    if(fd < 0) {
+    struct stat s;
+    SYS_FILE fd = prepare_service_file(sn, rq, &s);
+    if(!fd) {
         // if an error occurs, prepare_service_file sets the http status code
         // we can just return REQ_ABORTED
         return REQ_ABORTED;
     }
+    
+    // send file
+    sendfiledata sfd;
+    sfd.fd = fd;
+    sfd.len = s.st_size;
+    sfd.offset = 0;
+    sfd.header = NULL;
+    sfd.trailer = NULL;
+    net_sendfile(sn->csd, &sfd);
+    
+    vfs_close(fd);
+    
 
     /* send file*/
-    SystemIOStream *io = (SystemIOStream*) sn->csd;
+    //SystemIOStream *io = (SystemIOStream*) sn->csd;
+    //off_t fileoffset = 0;
+    //int len = atoi(pblock_findkeyval(pb_key_content_length, rq->srvhdrs));
+    //sendfile(io->fd, fd->fd, &fileoffset, len);
 
-    off_t fileoffset = 0;
-    int len = atoi(pblock_findkeyval(pb_key_content_length, rq->srvhdrs));
-    sendfile(io->fd, fd, &fileoffset, len);
-
-    close(fd);
+    //close(fd);
 
     return REQ_PROCEED;
 }

mercurial