Пример #1
0
int
urlForbidden(AtomPtr url,
             int (*handler)(int, AtomPtr, AtomPtr, AtomPtr, void*),
             void *closure)
{
    int forbidden = urlIsMatched(url->string, url->length,
                                 forbiddenDomains, forbiddenRegex);
    int code = 0;
    AtomPtr message = NULL, headers = NULL;


    if(forbidden) {
        message = internAtomF("Forbidden URL %s", url->string);
        if(forbiddenUrl) {
            code = forbiddenRedirectCode;
            headers = internAtomF("\r\nLocation: %s", forbiddenUrl->string);
        } else {
            code = 403;
        }
    }

#ifndef NO_REDIRECTOR
    if(code == 0 && redirector) {
        RedirectRequestPtr request;
        request = malloc(sizeof(RedirectRequestRec));
        if(request == NULL) {
            do_log(L_ERROR, "Couldn't allocate redirect request.\n");
            goto done;
        }
        request->url = url;
        request->handler = handler;
        request->data = closure;
        if(redirector_request_first == NULL)
            redirector_request_first = request;
        else
            redirector_request_last->next = request;
        redirector_request_last = request;
        request->next = NULL;
        if(request == redirector_request_first)
            redirectorTrigger();
        return 1;
    }

#endif

 done:
    handler(code, url, message, headers, closure);
    return 1;
}
Пример #2
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;
}
Пример #3
0
int httpSpecialDoSideFinish(AtomPtr data, HTTPRequestPtr requestor)
{
	ObjectPtr object = requestor->object;

	if (matchUrl("/s_server/config", object)) {
		AtomListPtr list = NULL;
		int i, rc;

		if (disableConfiguration) {
			abortObject(object, 403,
				    internAtom("Action not allowed"));
			goto out;
		}

		list = urlDecode(data->string, data->length);
		if (list == NULL) {
			abortObject(object, 400,
				    internAtom
				    ("Couldn't parse variable to set"));
			goto out;
		}
		for (i = 0; i < list->length; i++) {
			rc = parseConfigLine(list->list[i]->string, NULL, 0, 1);
			if (rc < 0) {
				abortObject(object, 400,
					    rc == -1 ?
					    internAtom
					    ("Couldn't parse variable to set") :
					    internAtom
					    ("Variable is not settable"));
				destroyAtomList(list);
				goto out;
			}
		}
		destroyAtomList(list);
		object->date = current_time.tv_sec;
		object->age = current_time.tv_sec;
		object->headers = internAtom("\r\nLocation: /s_server/config?");
		object->code = 303;
		object->message = internAtom("Done");
		object->flags &= ~OBJECT_INITIAL;
		object->length = 0;
	} else if (matchUrl("/s_server/status", object)) {
		AtomListPtr list = NULL;
		int i;

		if (disableConfiguration) {
			abortObject(object, 403,
				    internAtom("Action not allowed"));
			goto out;
		}

		list = urlDecode(data->string, data->length);
		if (list == NULL) {
			abortObject(object, 400,
				    internAtom("Couldn't parse action"));
			goto out;
		}
		for (i = 0; i < list->length; i++) {
			char *equals = memchr(list->list[i]->string, '=',
					      list->list[i]->length);
			AtomPtr name =
			    equals ? internAtomN(list->list[i]->string,
						 equals -
						 list->
						 list[i]->string) :
			    retainAtom(list->list[i]);
			if (name == atomInitForbidden)
				initForbidden();
			else if (name == atomReopenLog)
				reopenLog();
			else if (name == atomDiscardObjects)
				discardObjects(1, 0);
			else if (name == atomWriteoutObjects)
				writeoutObjects(1);
			else if (name == atomFreeChunkArenas)
				free_chunk_arenas();
			else {
				abortObject(object, 400,
					    internAtomF("Unknown action %s",
							name->string));
				releaseAtom(name);
				destroyAtomList(list);
				goto out;
			}
			releaseAtom(name);
		}
		destroyAtomList(list);
		object->date = current_time.tv_sec;
		object->age = current_time.tv_sec;
		object->headers = internAtom("\r\nLocation: /s_server/status?");
		object->code = 303;
		object->message = internAtom("Done");
		object->flags &= ~OBJECT_INITIAL;
		object->length = 0;
	} else {
		abortObject(object, 405, internAtom("Method not allowed"));
	}

      out:
	releaseAtom(data);
	notifyObject(object);
	requestor->connection->flags &= ~CONN_READER;
	return 1;
}
Пример #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;
}