src/server/service.c

Tue, 27 Dec 2011 20:12:21 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 27 Dec 2011 20:12:21 +0100
changeset 6
ce8fecc9847d
parent 4
998844b5ed25
child 8
f4d56bf9de40
permissions
-rw-r--r--

improved request processing

3
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2011 Olaf Wintermann. All rights reserved.
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 #include <stdio.h>
6
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
30 #include <errno.h>
3
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32 #include "service.h"
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
33 #include "io.h"
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
34 #include "pblock.h"
4
998844b5ed25 Added some protocol functions
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 3
diff changeset
35 #include "protocol.h"
3
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
36
6
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
37 #include <sys/sendfile.h>
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
38
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
39 // TODO: system sendfile Abstraktionen in neue Datei auslagern
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
40 /*
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
41 ssize_t sys_sendfile(int out_fd, int in_fd, off_t *off, size_t len) {
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
42
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
43 }
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
44 */
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
45 #define sys_sendfile sendfile
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
46
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
47
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
48 /*
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
49 * prepares for servicing a file
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
50 *
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
51 * adds content-length header and starts the response
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
52 *
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
53 * return the file descriptor or an error code
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
54 */
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
55 int prepare_service_file(Session *sn, Request *rq) {
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
56 char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
57
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
58 /* open the file */
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
59 int fd = open(ppath, O_RDONLY);
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
60 if(fd < 0) {
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
61 perror("prepare_service_file: open");
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
62
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
63 int status = 500;
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
64 switch(errno) {
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
65 case EACCES: {
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
66 status = 403;
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
67 break;
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
68 }
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
69 case ENOENT: {
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
70 status = 404;
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
71 break;
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
72 }
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
73 }
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
74 protocol_status(sn, rq, status, NULL);
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
75 return -1;
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
76 }
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
77
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
78 /* get stat */
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
79 struct stat stat;
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
80 if (fstat(fd, &stat) != 0) {
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
81 perror("prepare_service_file: stat");
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
82
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
83 protocol_status(sn, rq, 500, NULL);
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
84 return -1;
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
85 }
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
86
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
87 /* add content-length header*/
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
88 char contentLength[32];
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
89 int len = snprintf(contentLength, 32, "%d", stat.st_size);
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
90
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
91 pblock_kvinsert(pb_key_content_length, contentLength, len, rq->srvhdrs);
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
92
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
93 /* start response */
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
94 protocol_status(sn, rq, 200, NULL);
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
95 http_start_response(sn, rq);
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
96
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
97 return fd;
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
98 }
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
99
3
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 int test_service(pblock *pb, Session *sn, Request *rq) {
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 printf("test_service\n");
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102
6
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
103 int fd = prepare_service_file(sn, rq);
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
104 if(fd < 0) {
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
105 /* TODO: service error */
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
106 http_start_response(sn, rq);
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
107 return REQ_PROCEED;
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
108 }
4
998844b5ed25 Added some protocol functions
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 3
diff changeset
109
6
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
110 /* send file*/
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
111 SystemIOStream *io = (SystemIOStream*) sn->csd;
3
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112
6
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
113 off_t fileoffset = 0;
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
114 int len = atoi(pblock_findkeyval(pb_key_content_length, rq->srvhdrs));
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
115 printf("content-length: %d\n", len);
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
116 sendfile(io->fd, fd, &fileoffset, len);
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
117
ce8fecc9847d improved request processing
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 4
diff changeset
118 close(fd);
3
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120 return REQ_PROCEED;
137197831306 minimal request handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
121 }

mercurial