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; }
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; }
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; }
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; }