source: benchmark/io/http/worker.cfa @ e95a117

arm-ehjacob/cs343-translationnew-astnew-ast-unique-expr
Last change on this file since e95a117 was e95a117, checked in by Thierry Delisle <tdelisle@…>, 15 months ago

Fixed handling of closed connections.
Started work on cleanly closing server

  • Property mode set to 100644
File size: 2.9 KB
Line 
1#include "worker.hfa"
2
3#include <errno.h>
4#include <stdio.h>
5#include <string.h>
6#include <unistd.h>
7
8#include <iofwd.hfa>
9
10#include "options.hfa"
11#include "protocol.hfa"
12#include "filecache.hfa"
13
14extern "C" {
15// extern ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
16extern ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);
17}
18
19ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) {
20        return splice(in_fd, offset, out_fd, 0p, count, 0);
21}
22
23
24//=============================================================================================
25// Worker Thread
26//=============================================================================================
27void ?{}( Worker & this ) {
28        ((thread&)this){ "Server Worker Thread", *options.clopts.instance };
29        int ret = pipe(this.pipe);
30        if( ret < 0 ) { abort( "pipe error: (%d) %s\n", (int)errno, strerror(errno) ); }
31}
32
33void main( Worker & this ) {
34        CONNECTION:
35        for() {
36                int fd = take(wait_connect);
37                if (fd < 0) break;
38
39                printf("New connection %d, waiting for requests\n", fd);
40                REQUEST:
41                for() {
42                        bool closed;
43                        HttpCode code;
44                        const char * file;
45                        size_t name_size;
46
47                        // Read the http request
48                        size_t len = 1024;
49                        char buffer[len];
50                        printf("Reading request\n");
51                        [code, closed, file, name_size] = http_read(fd, buffer, len);
52
53                        // if we are done, break out of the loop
54                        if( closed ) {
55                                printf("Connection closed\n");
56                                continue CONNECTION;
57                        }
58
59                        // If this wasn't a request retrun 400
60                        if( code != OK200 ) {
61                                printf("Invalid Request : %d\n", code_val(code));
62                                answer_error(fd, code);
63                                continue REQUEST;
64                        }
65
66                        printf("Request for file %.*s\n", (int)name_size, file);
67
68                        // Get the fd from the file cache
69                        int ans_fd;
70                        size_t count;
71                        [ans_fd, count] = get_file( file, name_size );
72
73                        // If we can't find the file, return 404
74                        if( ans_fd < 0 ) {
75                                printf("File Not Found\n");
76                                answer_error(fd, E404);
77                                continue REQUEST;
78                        }
79
80                        // Send the header
81                        answer_header(fd, count);
82
83                        // Send the desired file
84                        sendfile( this.pipe, fd, ans_fd, count);
85
86                        printf("File sent\n");
87                }
88        }
89}
90
91//=============================================================================================
92// Acceptor Thread
93//=============================================================================================
94void ?{}( Acceptor & this, int sockfd, struct sockaddr * addr, socklen_t * addrlen, int flags ) {
95        ((thread&)this){ "Acceptor Thread", *options.clopts.instance };
96        this.sockfd  = sockfd;
97        this.addr    = addr;
98        this.addrlen = addrlen;
99        this.flags   = flags;
100}
101
102void main( Acceptor & this ) {
103        for() {
104                int ret = cfa_accept4( this.[sockfd, addr, addrlen, flags] );
105                if(ret < 0) {
106                        if( errno == ECONNABORTED ) break;
107                        abort( "accept error: (%d) %s\n", (int)errno, strerror(errno) );
108                }
109
110                printf("New connection accepted\n");
111                put( wait_connect, ret );
112        }
113}
Note: See TracBrowser for help on using the repository browser.