diff -r 5ec9abba1027 -r 3a1d5a52adfc src/server/safs/service.c --- 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 #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; }