Пример #1
0
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;
}
Пример #2
0
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;
}