#include "protocol.hfa" #include #include // #include // Don't use stdio.h, too slow to compile extern "C" { int snprintf ( char * s, size_t n, const char * format, ... ); } #include #include const char * http_msgs[] = { "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: %zu\n\n", "HTTP/1.1 400 Bad Request\nContent-Type: text/plain\nContent-Length: 0\n\n", "HTTP/1.1 404 Not Found\nContent-Type: text/plain\nContent-Length: 0\n\n", "HTTP/1.1 413 Payload Too Large\nContent-Type: text/plain\nContent-Length: 0\n\n", "HTTP/1.1 414 URI Too Long\nContent-Type: text/plain\nContent-Length: 0\n\n", }; _Static_assert( KNOWN_CODES == (sizeof(http_msgs) / sizeof(http_msgs[0]))); static inline int answer( int fd, const char * it, int len) { while(len > 0) { // Call write int ret = write(fd, it, len); if( ret < 0 ) { if( errno != EAGAIN && errno != EWOULDBLOCK) abort( "'answer error' error: (%d) %s\n", (int)errno, strerror(errno) ); } // update it/len it += ret; len -= ret; } return 0; } int answer_error( int fd, HttpCode code ) { /* paranoid */ assert( code < KNOWN_CODES && code != OK200 ); int idx = (int)code; return answer( fd, http_msgs[idx], strlen( http_msgs[idx] ) ); } int answer_header( int fd, size_t size ) { const char * fmt = http_msgs[OK200]; int len = 100; char buffer[len]; len = snprintf(buffer, len, fmt, size); return answer( fd, buffer, len ); } [HttpCode code, bool closed, * const char file, size_t len] http_read(int fd, []char buffer, size_t len) { char * it = buffer; size_t count = len - 1; int rlen = 0; READ: for() { int ret = cfa_read(fd, it, count); if(ret < 0 ) { if( errno ) return [OK200, true, 0p, 0]; if( errno == EAGAIN || errno == EWOULDBLOCK) continue READ; abort( "read error: (%d) %s\n", (int)errno, strerror(errno) ); } it[ret + 1] = '\0'; rlen += ret; if( strstr( it, "\r\n\r\n" ) ) break; it += ret; count -= ret; if( count < 1 ) return [E414, false, 0p, 0]; } printf("%.*s\n", rlen, buffer); it = buffer; int ret = memcmp(it, "GET /", 5); if( ret != 0 ) return [E400, false, 0p, 0]; it += 5; char * end = strstr( it, " " ); return [OK200, false, it, end - it]; }