static int listener0(void *ctx, HTTPServerRef const server, HTTPConnectionRef const conn) { HTTPMethod method; str_t URI[URI_MAX]; ssize_t len = HTTPConnectionReadRequest(conn, &method, URI, sizeof(URI)); if(UV_EOF == len) { // HACK: Force the connection to realize it's dead. // Otherwise there is a timeout period of like 15-20 seconds // and we can run out of file descriptors. I suspect this // is a bug with libuv, but I'm not sure. HTTPConnectionWrite(conn, (byte_t const *)STR_LEN("x")); HTTPConnectionFlush(conn); return 0; } if(UV_EMSGSIZE == len) return 414; // Request-URI Too Large if(len < 0) { fprintf(stderr, "Request error: %s\n", uv_strerror(len)); return 500; } HTTPHeadersRef headers; int rc = HTTPHeadersCreateFromConnection(conn, &headers); if(UV_EMSGSIZE == rc) return 431; // Request Header Fields Too Large if(rc < 0) return 500; strarg_t const host = HTTPHeadersGet(headers, "host"); str_t domain[1023+1]; domain[0] = '\0'; if(host) sscanf(host, "%1023[^:]", domain); // TODO: Verify Host header to prevent DNS rebinding. if(SERVER_PORT_TLS && server == server_raw) { // Redirect from HTTP to HTTPS if('\0' == domain[0]) return 400; strarg_t const port = SERVER_PORT_TLS; str_t loc[URI_MAX]; rc = snprintf(loc, sizeof(loc), "https://%s:%s%s", domain, port, URI); if(rc >= sizeof(loc)) 414; // Request-URI Too Large if(rc < 0) return 500; HTTPConnectionSendRedirect(conn, 301, loc); return 0; } strarg_t const cookie = HTTPHeadersGet(headers, "cookie"); SLNSessionCacheRef const cache = SLNRepoGetSessionCache(repo); SLNSessionRef session = NULL; rc = SLNSessionCacheCopyActiveSession(cache, cookie, &session); if(rc < 0) return 500; // Note: null session is valid (zero permissions). rc = -1; rc = rc >= 0 ? rc : SLNServerDispatch(repo, session, conn, method, URI, headers); rc = rc >= 0 ? rc : BlogDispatch(blog, session, conn, method, URI, headers); SLNSessionRelease(&session); HTTPHeadersFree(&headers); return rc; }
static int listener0(void *ctx, HTTPServerRef const server, HTTPConnectionRef const conn) { HTTPMethod method; str_t URI[URI_MAX]; ssize_t len = HTTPConnectionReadRequest(conn, &method, URI, sizeof(URI)); if(UV_EOF == len) return 0; if(UV_ECONNRESET == len) return 0; if(UV_EMSGSIZE == len) return 414; // Request-URI Too Large if(len < 0) { alogf("Request error: %s\n", uv_strerror(len)); return 500; } HTTPHeadersRef headers; int rc = HTTPHeadersCreateFromConnection(conn, &headers); if(UV_EMSGSIZE == rc) return 431; // Request Header Fields Too Large if(rc < 0) return 500; strarg_t const host = HTTPHeadersGet(headers, "host"); str_t domain[1023+1]; domain[0] = '\0'; if(host) sscanf(host, "%1023[^:]", domain); // TODO: Verify Host header to prevent DNS rebinding. if(SERVER_PORT_TLS && server == server_raw) { // Redirect from HTTP to HTTPS if('\0' == domain[0]) return 400; strarg_t const port = SERVER_PORT_TLS; str_t loc[URI_MAX]; rc = snprintf(loc, sizeof(loc), "https://%s:%s%s", domain, port, URI); if(rc >= sizeof(loc)) 414; // Request-URI Too Large if(rc < 0) return 500; HTTPConnectionSendRedirect(conn, 301, loc); return 0; } strarg_t const cookie = HTTPHeadersGet(headers, "cookie"); SLNSessionCacheRef const cache = SLNRepoGetSessionCache(repo); SLNSessionRef session = NULL; rc = SLNSessionCacheCopyActiveSession(cache, cookie, &session); if(rc < 0) return 500; // Note: null session is valid (zero permissions). rc = -1; rc = rc >= 0 ? rc : SLNServerDispatch(repo, session, conn, method, URI, headers); rc = rc >= 0 ? rc : BlogDispatch(blog, session, conn, method, URI, headers); SLNSessionRelease(&session); HTTPHeadersFree(&headers); return rc; }