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

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since a06023f was 4f762d3, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Fix httpforall after changes to I/O

  • Property mode set to 100644
File size: 3.5 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 <fstream.hfa>
9#include <iofwd.hfa>
10
11#include "options.hfa"
12#include "protocol.hfa"
13#include "filecache.hfa"
14
15//=============================================================================================
16// Worker Thread
17//=============================================================================================
18void ?{}( Worker & this ) {
19        ((thread&)this){ "Server Worker Thread", *options.clopts.instance };
20        this.pipe[0] = -1;
21        this.pipe[1] = -1;
22        this.done = false;
23}
24
25extern "C" {
26extern int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
27}
28
29void main( Worker & this ) {
30        park();
31        /* paranoid */ assert( this.pipe[0] != -1 );
32        /* paranoid */ assert( this.pipe[1] != -1 );
33
34        CONNECTION:
35        for() {
36                if( options.log ) sout | "=== Accepting connection ===";
37                int fd = cfa_accept4( this.[sockfd, addr, addrlen, flags], 0 );
38                if(fd < 0) {
39                        if( errno == ECONNABORTED ) break;
40                        if( this.done && (errno == EINVAL || errno == EBADF) ) break;
41                        abort( "accept error: (%d) %s\n", (int)errno, strerror(errno) );
42                }
43                if(this.done) break;
44
45                if( options.log ) sout | "=== New connection" | fd | "" | ", waiting for requests ===";
46                REQUEST:
47                for() {
48                        bool closed;
49                        HttpCode code;
50                        const char * file;
51                        size_t name_size;
52
53                        // Read the http request
54                        size_t len = options.socket.buflen;
55                        char buffer[len];
56                        if( options.log ) sout | "=== Reading request ===";
57                        [code, closed, file, name_size] = http_read(fd, buffer, len);
58
59                        // if we are done, break out of the loop
60                        if( closed ) break REQUEST;
61
62                        // If this wasn't a request retrun 400
63                        if( code != OK200 ) {
64                                sout | "=== Invalid Request :" | code_val(code) | "===";
65                                answer_error(fd, code);
66                                continue REQUEST;
67                        }
68
69                        if(0 == strncmp(file, "plaintext", min(name_size, sizeof("plaintext") ))) {
70                                if( options.log ) sout | "=== Request for /plaintext ===";
71
72                                char text[] = "Hello, World!\n";
73
74                                // Send the header
75                                int ret = answer_plain(fd, text, sizeof(text));
76                                if( ret == -ECONNRESET ) break REQUEST;
77
78                                if( options.log ) sout | "=== Answer sent ===";
79                                continue REQUEST;
80                        }
81
82                        if(0 == strncmp(file, "ping", min(name_size, sizeof("ping") ))) {
83                                if( options.log ) sout | "=== Request for /ping ===";
84
85                                // Send the header
86                                int ret = answer_empty(fd);
87                                if( ret == -ECONNRESET ) break REQUEST;
88
89                                if( options.log ) sout | "=== Answer sent ===";
90                                continue REQUEST;
91                        }
92
93                        if( options.log ) {
94                                sout | "=== Request for file " | nonl;
95                                write(sout, file, name_size);
96                                sout | " ===";
97                        }
98
99                        if( !options.file_cache.path ) {
100                                if( options.log ) {
101                                        sout | "=== File Not Found (" | nonl;
102                                        write(sout, file, name_size);
103                                        sout | ") ===";
104                                }
105                                answer_error(fd, E405);
106                                continue REQUEST;
107                        }
108
109                        // Get the fd from the file cache
110                        int ans_fd;
111                        size_t count;
112                        [ans_fd, count] = get_file( file, name_size );
113
114                        // If we can't find the file, return 404
115                        if( ans_fd < 0 ) {
116                                if( options.log ) {
117                                        sout | "=== File Not Found (" | nonl;
118                                        write(sout, file, name_size);
119                                        sout | ") ===";
120                                }
121                                answer_error(fd, E404);
122                                continue REQUEST;
123                        }
124
125                        // Send the header
126                        int ret = answer_header(fd, count);
127                        if( ret == -ECONNRESET ) break REQUEST;
128
129                        // Send the desired file
130                        ret = sendfile( this.pipe, fd, ans_fd, count);
131                        if( ret == -ECONNRESET ) break REQUEST;
132
133                        if( options.log ) sout | "=== Answer sent ===";
134                }
135
136                if( options.log ) sout | "=== Connection closed ===";
137                close(fd);
138                continue CONNECTION;
139        }
140}
Note: See TracBrowser for help on using the repository browser.