Exemplo n.º 1
0
int
redirectorStreamHandler1(int status,
                         FdEventHandlerPtr event,
                         StreamRequestPtr srequest)
{
    RedirectRequestPtr request = (RedirectRequestPtr)srequest->data;

    if(status) {
        if(status >= 0)
            status = -EPIPE;
        do_log_error(L_ERROR, -status, "Write to redirector failed");
        goto fail;
    }

    if(!streamRequestDone(srequest))
        return 0;

    do_stream(IO_READ, redirector_read_fd, 0,
              redirector_buffer, REDIRECTOR_BUFFER_SIZE,
              redirectorStreamHandler2, request);
    return 1;

 fail:
    request->handler(status < 0 ? status : -EPIPE,
                     request->url, NULL, NULL, request->data);
    redirectorDestroyRequest(request);
    redirectorKill();
    return 1;
}
Exemplo n.º 2
0
void
redirectorTrigger(void)
{
    RedirectRequestPtr request = redirector_request_first;
    int rc;

    if(!request)
        return;

    if(redirector_read_fd < 0) {
        rc = runRedirector(&redirector_pid,
                           &redirector_read_fd, &redirector_write_fd);
        if(rc < 0) {
            request->handler(rc, request->url, NULL, NULL, request->data);
            redirectorDestroyRequest(request);
            return;
        }
    }
    do_stream_2(IO_WRITE, redirector_write_fd, 0,
                request->url->string, request->url->length,
                "\n", 1,
                redirectorStreamHandler1, request);
}
Exemplo n.º 3
0
int
redirectorStreamHandler2(int status,
                         FdEventHandlerPtr event,
                         StreamRequestPtr srequest)
{
    RedirectRequestPtr request = (RedirectRequestPtr)srequest->data;
    char *c;
    AtomPtr message;
    AtomPtr headers;
    int code;

    if(status < 0) {
        do_log_error(L_ERROR, -status, "Read from redirector failed");
        request->handler(status, request->url, NULL, NULL, request->data);
        goto kill;
    }
    c = memchr(redirector_buffer, '\n', srequest->offset);
    if(!c) {
        if(!status && srequest->offset < REDIRECTOR_BUFFER_SIZE)
            return 0;
        do_log(L_ERROR, "Redirector returned incomplete reply.\n");
        request->handler(-EREDIRECTOR, request->url, NULL, NULL, request->data);
        goto kill;
    }
    *c = '\0';

    if(srequest->offset > c + 1 - redirector_buffer)
        do_log(L_WARN, "Stray bytes in redirector output.\n");

    if(c > redirector_buffer + 1 &&
       (c - redirector_buffer != request->url->length ||
        memcmp(redirector_buffer, request->url->string,
               request->url->length) != 0)) {
        code = redirectorRedirectCode;
        message = internAtom("Redirected by external redirector");
        if(message == NULL) {
            request->handler(-ENOMEM, request->url, NULL, NULL, request->data);
            goto kill;
        }

        headers = internAtomF("\r\nLocation: %s", redirector_buffer);
        if(headers == NULL) {
            releaseAtom(message);
            request->handler(-ENOMEM, request->url, NULL, NULL, request->data);
            goto kill;
        }
    } else {
        code = 0;
        message = NULL;
        headers = NULL;
    }
    request->handler(code, request->url,
                     message, headers, request->data);
    goto cont;

 cont:
    redirectorDestroyRequest(request);
    redirectorTrigger();
    return 1;

 kill:
    redirectorKill();
    goto cont;
}
Exemplo n.º 4
0
int
redirectorStreamHandler2(int status,
                         FdEventHandlerPtr event,
                         StreamRequestPtr srequest)
{
    RedirectRequestPtr request = (RedirectRequestPtr)srequest->data;
    char *c, *c2, *buf;
    AtomPtr url = request->url;
    AtomPtr message = NULL;
    AtomPtr headers = NULL;
    int code = 0;

    if(status < 0) {
        do_log_error(L_ERROR, -status, "Read from redirector failed");
        request->handler(status, request->url, NULL, NULL, request->data);
        goto kill;
    }
    c = memchr(redirector_buffer, '\n', srequest->offset);
    if(!c) {
        if(!status && srequest->offset < REDIRECTOR_BUFFER_SIZE)
            return 0;
        do_log(L_ERROR, "Redirector returned incomplete reply.\n");
        request->handler(-EREDIRECTOR, request->url, NULL, NULL, request->data);
        goto kill;
    }
    c2 = memchr(redirector_buffer, ' ', srequest->offset);
    if (c2 != NULL) c = c2;
    *c = '\0';

    buf = redirector_buffer;
    if (digit(buf[0]) && digit(buf[1]) && digit(buf[2]) && buf[3] == ':') {
        code = strtol(buf, NULL, 10);
        buf += 4;
    }

    if(c > buf + 1 &&
       (c - buf != request->url->length ||
        memcmp(buf, request->url->string,
               request->url->length) != 0)) {
        if (!redirectorIsServerSide || (300 <= code && code <= 399)) {
            if (!(300 <= code && code <= 399))
                code = redirectorRedirectCode;
            message = internAtom("Redirected by external redirector");
            if(message == NULL) {
                request->handler(-ENOMEM, request->url, NULL, NULL, request->data);
                goto kill;
            }
            headers = internAtomF("\r\nLocation: %s", redirector_buffer);
            if(headers == NULL) {
                releaseAtom(message);
                request->handler(-ENOMEM, request->url, NULL, NULL, request->data);
                goto kill;
            }
        } else {
            url = internAtom(buf);
            if(url == NULL) {
                request->handler(-ENOMEM, request->url, NULL, NULL, request->data);
                goto kill;
            }
        }
    }
    request->handler(code, url,
                     message, headers, request->data);
    goto cont;

 cont:
    redirectorDestroyRequest(request);
    redirectorTrigger();
    return 1;

 kill:
    redirectorKill();
    goto cont;
}