diff -r 1fdbf4170ef4 -r b8bf95b39952 src/server/service.c --- a/src/server/service.c Sun Jan 08 15:46:47 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,227 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2011 Olaf Wintermann. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include "service.h" -#include "io.h" -#include "pblock.h" -#include "protocol.h" - -#include -#include "strbuf.h" - -// TODO: system sendfile Abstraktionen in neue Datei auslagern -/* -ssize_t sys_sendfile(int out_fd, int in_fd, off_t *off, size_t len) { - -} -*/ -#define sys_sendfile sendfile - - -/* - * prepares for servicing a file - * - * adds content-length header and starts the response - * - * return the file descriptor or an error code - */ -int prepare_service_file(Session *sn, Request *rq) { - 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; - switch(errno) { - case EACCES: { - status = 403; - break; - } - case ENOENT: { - status = 404; - break; - } - } - protocol_status(sn, rq, status, NULL); - return -1; - } - - /* get stat */ - struct stat stat; - if (fstat(fd, &stat) != 0) { - perror("prepare_service_file: stat"); - - protocol_status(sn, rq, 500, NULL); - return -1; - } - - /* add content-length header*/ - char contentLength[32]; - int len = snprintf(contentLength, 32, "%d", stat.st_size); - - pblock_kvinsert(pb_key_content_length, contentLength, len, rq->srvhdrs); - - /* start response */ - protocol_status(sn, rq, 200, NULL); - http_start_response(sn, rq); - - return fd; -} - -int send_file(pblock *pb, Session *sn, Request *rq) { - printf("test_service\n"); - - // request body test begin - char *ctval = pblock_findkeyval(pb_key_content_length, rq->headers); - if(ctval != NULL) { - printf("read request body\n"); - - printf("netbuf{%d}\n", sn->inbuf); - - int c; - while((c = netbuf_getc(sn->inbuf)) != IO_EOF) { - putchar(c); - } - printf("\n"); - } - - - // end test - - int fd = prepare_service_file(sn, rq); - if(fd < 0) { - /* TODO: service error */ - http_start_response(sn, rq); - return REQ_PROCEED; - } - - /* send file*/ - SystemIOStream *io = (SystemIOStream*) sn->csd; - - off_t fileoffset = 0; - int len = atoi(pblock_findkeyval(pb_key_content_length, rq->srvhdrs)); - printf("content-length: %d\n", len); - sendfile(io->fd, fd, &fileoffset, len); - - close(fd); - - return REQ_PROCEED; -} - -int service_hello(pblock *pb, Session *sn, Request *rq) { - pblock_nninsert("content-length", 13, rq->srvhdrs); - protocol_status(sn, rq, 200, NULL); - http_start_response(sn, rq); - 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, "\n\nIndex of "); - sbuf_puts(out, uri); - sbuf_puts(out, "\n\n

Index of "); - sbuf_puts(out, uri); - sbuf_puts(out, "


\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, ""); - sbuf_append(out, filename); - sbuf_puts(out, "
\n"); - } - - sbuf_puts(out, "\n\n\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; -}