source: benchmark/io/http/protocol.cfa @ 0aec496

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

First attempt at webserver, no option support yet

  • Property mode set to 100644
File size: 2.2 KB
RevLine 
[0aec496]1#include "protocol.hfa"
2
3#include <iofwd.hfa>
4
5#include <assert.h>
6// #include <stdio.h> // Don't use stdio.h, too slow to compile
7extern "C" {
8      int snprintf ( char * s, size_t n, const char * format, ... );
9}
10#include <string.h>
11
12#include <errno.h>
13
14
15const char * http_msgs[] = {
16        "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: %zu\n\n",
17        "HTTP/1.1 400 Bad Request\nContent-Type: text/plain\nContent-Length: 0\n\n",
18        "HTTP/1.1 404 Not Found\nContent-Type: text/plain\nContent-Length: 0\n\n",
19        "HTTP/1.1 413 Payload Too Large\nContent-Type: text/plain\nContent-Length: 0\n\n",
20        "HTTP/1.1 414 URI Too Long\nContent-Type: text/plain\nContent-Length: 0\n\n",
21};
22
23_Static_assert( KNOWN_CODES == (sizeof(http_msgs) / sizeof(http_msgs[0])));
24
25static inline int answer( int fd, const char * it, int len) {
26        while(len > 0) {
27                // Call write
28                int ret = write(fd, it, len);
29                if( ret < 0 ) { if( errno != EAGAIN && errno != EWOULDBLOCK) abort( "'answer error' error: (%d) %s\n", (int)errno, strerror(errno) ); }
30
31                // update it/len
32                it  += ret;
33                len -= ret;
34        }
35        return 0;
36}
37
38int answer_error( int fd, HttpCode code ) {
39        /* paranoid */ assert( code < KNOWN_CODES && code != OK200 );
40        int idx = (int)code;
41        return answer( fd, http_msgs[idx], strlen( http_msgs[idx] ) );
42}
43
44int answer_header( int fd, size_t size ) {
45        const char * fmt = http_msgs[OK200];
46        int len = 100;
47        char buffer[len];
48        len = snprintf(buffer, len, fmt, size);
49        return answer( fd, buffer, len );
50}
51
52[HttpCode code, bool closed, * const char file, size_t len] http_read(int fd, []char buffer, size_t len) {
53        char * it = buffer;
54        size_t count = len - 1;
55        int rlen = 0;
56        READ:
57        for() {
58                int ret = cfa_read(fd, it, count);
59                if(ret < 0 ) {
60                        if( errno ) return [OK200, true, 0p, 0];
61                        if( errno == EAGAIN || errno == EWOULDBLOCK) continue READ;
62                        abort( "read error: (%d) %s\n", (int)errno, strerror(errno) );
63                }
64                it[ret + 1] = '\0';
65                rlen += ret;
66
67                if( strstr( it, "\r\n\r\n" ) ) break;
68
69                it += ret;
70                count -= ret;
71
72                if( count < 1 ) return [E414, false, 0p, 0];
73        }
74
75        printf("%.*s\n", rlen, buffer);
76
77        it = buffer;
78        int ret = memcmp(it, "GET /", 5);
79        if( ret != 0 ) return [E400, false, 0p, 0];
80        it += 5;
81
82        char * end = strstr( it, " " );
83        return [OK200, false, it, end - it];
84}
Note: See TracBrowser for help on using the repository browser.