source: benchmark/io/http/worker.cfa@ 7223dbf2

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 7223dbf2 was ee59ede, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Improved error handling in server

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