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

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 d23c0b2 was b57db73, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

httpforall now only loads file if explicit path is given.

  • Property mode set to 100644
File size: 3.6 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, -1`s, &this.cancel, 0p );
38 // int fd = accept4( this.[sockfd, addr, addrlen, flags] );
39 if(fd < 0) {
40 if( errno == ECONNABORTED ) break;
41 if( this.done && (errno == EINVAL || errno == EBADF) ) break;
42 abort( "accept error: (%d) %s\n", (int)errno, strerror(errno) );
43 }
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, &this.cancel);
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.