X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fcontext_loop.c;h=ff95e825ebe5ad428d604b610d8621ae6a6a327f;hb=a648fdc96cf64d183b394f9b46822b4104192528;hp=f3d54c4ce0bfd099f186194a9d1d753143500442;hpb=6f15cc2bff396cec081b969bf5b3097bfbafe4d5;p=citadel.git diff --git a/webcit/context_loop.c b/webcit/context_loop.c index f3d54c4ce..ff95e825e 100644 --- a/webcit/context_loop.c +++ b/webcit/context_loop.c @@ -4,21 +4,15 @@ * keep track of things. If the HTTP request doesn't belong to any currently * active session, a new session is started. * - * Copyright (c) 1996-2011 by the citadel.org team + * Copyright (c) 1996-2012 by the citadel.org team * * This program is open source software. You can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. + * modify it under the terms of the GNU General Public License version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "webcit.h" @@ -56,7 +50,7 @@ void shutdown_sessions(void) wcsession *sptr; for (sptr = SessionList; sptr != NULL; sptr = sptr->next) { - sptr->killthis = 1; + sptr->killthis = 1; } } @@ -74,7 +68,7 @@ void do_housekeeping(void) /* Kill idle sessions */ if ((time(NULL) - (sptr->lastreq)) > (time_t) WEBCIT_TIMEOUT) { - syslog(3, "Timeout session %d\n", sptr->wc_session); + syslog(3, "Timeout session %d", sptr->wc_session); sptr->killthis = 1; } @@ -101,7 +95,7 @@ void do_housekeeping(void) * Now free up and destroy the culled sessions. */ while (sessions_to_kill != NULL) { - syslog(3, "Destroying session %d\n", sessions_to_kill->wc_session); + syslog(3, "Destroying session %d", sessions_to_kill->wc_session); sptr = sessions_to_kill->next; session_destroy_modules(&sessions_to_kill); sessions_to_kill = sptr; @@ -120,7 +114,7 @@ void check_thread_pool_size(void) (num_threads_executing >= num_threads_existing) && (num_threads_existing < MAX_WORKER_THREADS) ) { - syslog(3, "%d of %d threads are executing. Adding another worker thread.\n", + syslog(3, "%d of %d threads are executing. Adding another worker thread.", num_threads_executing, num_threads_existing ); @@ -174,35 +168,36 @@ wcsession *FindSession(wcsession **wclist, ParsedHttpHdrs *Hdr, pthread_mutex_t switch (Hdr->HR.got_auth) { case AUTH_BASIC: - if ( (Hdr->HR.SessionKey != sptr->SessionKey)) - continue; - if ((!strcasecmp(ChrPtr(Hdr->c_username), ChrPtr(sptr->wc_username))) && - (!strcasecmp(ChrPtr(Hdr->c_password), ChrPtr(sptr->wc_password))) ) { + if ( (!strcasecmp(ChrPtr(Hdr->c_username), ChrPtr(sptr->wc_username))) + && (!strcasecmp(ChrPtr(Hdr->c_password), ChrPtr(sptr->wc_password))) + && (sptr->killthis == 0) + ) { + syslog(LOG_DEBUG, "Matched a session with the same http-auth"); TheSession = sptr; } - if (TheSession == NULL) - syslog(1, "found sessionkey [%d], but credentials for [%s|%s] didn't match\n", - Hdr->HR.SessionKey,ChrPtr(Hdr->c_username), ChrPtr(sptr->wc_username)); break; case AUTH_COOKIE: /* If cookie-session, look for a session with matching session ID */ - if ( (Hdr->HR.desired_session != 0) && - (sptr->wc_session == Hdr->HR.desired_session)) { + if ( (Hdr->HR.desired_session != 0) + && (sptr->wc_session == Hdr->HR.desired_session) + ) { + syslog(LOG_DEBUG, "Matched a session with the same cookie"); TheSession = sptr; } break; case NO_AUTH: /* Any unbound session is a candidate */ if ( (sptr->wc_session == 0) && (sptr->inuse == 0) ) { + syslog(LOG_DEBUG, "Reusing an unbound session"); TheSession = sptr; } break; } } CtdlLogResult(pthread_mutex_unlock(ListMutex)); - if (TheSession == NULL) - syslog(1, "didn't find sessionkey [%d] for user [%s]\n", - Hdr->HR.SessionKey, ChrPtr(Hdr->c_username)); + if (TheSession == NULL) { + syslog(LOG_DEBUG, "No existing session was matched"); + } return TheSession; } @@ -212,7 +207,6 @@ wcsession *CreateSession(int Lockable, int Static, wcsession **wclist, ParsedHtt TheSession = (wcsession *) malloc(sizeof(wcsession)); memset(TheSession, 0, sizeof(wcsession)); TheSession->Hdr = Hdr; - TheSession->SessionKey = Hdr->HR.SessionKey; TheSession->serv_sock = (-1); pthread_setspecific(MyConKey, (void *)TheSession); @@ -267,7 +261,6 @@ int ReadHttpSubject(ParsedHttpHdrs *Hdr, StrBuf *Line, StrBuf *Buf) void *vLine, *vHandler; const char *Pos = NULL; - Hdr->HR.ReqLine = Line; /* The requesttype... GET, POST... */ StrBufExtract_token(Buf, Hdr->HR.ReqLine, 0, ' '); @@ -332,15 +325,24 @@ int ReadHttpSubject(ParsedHttpHdrs *Hdr, StrBuf *Line, StrBuf *Buf) } if (Hdr->HR.Handler != NULL) { - if ((Hdr->HR.Handler->Flags & BOGUS) != 0) + if ((Hdr->HR.Handler->Flags & BOGUS) != 0) { return 1; + } Hdr->HR.DontNeedAuth = ( ((Hdr->HR.Handler->Flags & ISSTATIC) != 0) || ((Hdr->HR.Handler->Flags & ANONYMOUS) != 0) - ); + ); } else { - Hdr->HR.DontNeedAuth = 1; /* Flat request? show him the login screen... */ + /* If this is a "flat" request for the root, display the configured landing page. */ + int return_value; + StrBuf *NewLine = NewStrBuf(); + Hdr->HR.DontNeedAuth = 1; + StrBufAppendPrintf(NewLine, "GET /landing?go=%s HTTP/1.0", ChrPtr(Buf)); + syslog(LOG_DEBUG, "Replacing with: %s", ChrPtr(NewLine)); + return_value = ReadHttpSubject(Hdr, NewLine, Buf); + FreeStrBuf(&NewLine); + return return_value; } return 0; @@ -397,7 +399,7 @@ int ReadHTTPRequest (ParsedHttpHdrs *Hdr) memset(pHdr, 0, sizeof(OneHttpHeader)); pHdr->Val = Line; Put(Hdr->HTTPHeaders, HKEY("GET /"), pHdr, DestroyHttpHeaderHandler); - syslog(9, "%s\n", ChrPtr(Line)); + syslog(9, "%s", ChrPtr(Line)); isbogus = ReadHttpSubject(Hdr, Line, HeaderName); if (isbogus) break; continue; @@ -495,20 +497,19 @@ void context_loop(ParsedHttpHdrs *Hdr) isbogus = ReadHTTPRequest(Hdr); Hdr->HR.dav_depth = 32767; /* TODO: find a general way to have non-0 defaults */ - if (!isbogus) + + if (!isbogus) { isbogus = AnalyseHeaders(Hdr); + } - if ((isbogus) || - ((Hdr->HR.Handler != NULL) && - ((Hdr->HR.Handler->Flags & BOGUS) != 0))) - { + if ( (isbogus) + || ((Hdr->HR.Handler != NULL) + && ((Hdr->HR.Handler->Flags & BOGUS) != 0)) + ) { wcsession *Bogus; - Bogus = CreateSession(0, 1, NULL, Hdr, NULL); - do_404(); - - syslog(9, "HTTP: 404 [%ld.%06ld] %s %s \n", + syslog(9, "HTTP: 404 [%ld.%06ld] %s %s", ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) / 1000000, ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) % 1000000, ReqStrs[Hdr->HR.eReqType], @@ -529,7 +530,7 @@ void context_loop(ParsedHttpHdrs *Hdr) /* How long did this transaction take? */ gettimeofday(&tx_finish, NULL); - syslog(9, "HTTP: 200 [%ld.%06ld] %s %s \n", + syslog(9, "HTTP: 200 [%ld.%06ld] %s %s", ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) / 1000000, ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) % 1000000, ReqStrs[Hdr->HR.eReqType], @@ -549,30 +550,31 @@ void context_loop(ParsedHttpHdrs *Hdr) } /* - * See if there's an existing session open with the desired ID or user/pass + * See if there's an existing session open with any of: + * - The desired Session ID + * - A matching http-auth username and password + * - An unbound session flagged as reusable */ TheSession = FindSession(&SessionList, Hdr, &SessionListMutex); /* - * Create a new session if we have to + * If there were no qualifying sessions, then create a new one. */ if (TheSession == NULL) { TheSession = CreateSession(1, 0, &SessionList, Hdr, &SessionListMutex); + } - if ( (StrLength(Hdr->c_username) == 0) - && (!Hdr->HR.DontNeedAuth) - && (Hdr->HR.Handler != NULL) - && ((XHTTP_COMMANDS & Hdr->HR.Handler->Flags) == XHTTP_COMMANDS) - ) { - OverrideRequest(Hdr, HKEY("GET /401 HTTP/1.0")); - Hdr->HR.prohibit_caching = 1; - } - - if (StrLength(Hdr->c_language) > 0) { - syslog(9, "Session cookie requests language '%s'\n", ChrPtr(Hdr->c_language)); - set_selected_language(ChrPtr(Hdr->c_language)); - go_selected_language(); - } + /* + * Reject transactions which require http-auth, if http-auth was not provided + */ + if ( (StrLength(Hdr->c_username) == 0) + && (!Hdr->HR.DontNeedAuth) + && (Hdr->HR.Handler != NULL) + && ((XHTTP_COMMANDS & Hdr->HR.Handler->Flags) == XHTTP_COMMANDS) + ) { + syslog(LOG_DEBUG, "http-auth required but not provided"); + OverrideRequest(Hdr, HKEY("GET /401 HTTP/1.0")); + Hdr->HR.prohibit_caching = 1; } /* @@ -590,13 +592,25 @@ void context_loop(ParsedHttpHdrs *Hdr) TheSession->lastreq = time(NULL); /* log */ TheSession->Hdr = Hdr; + /* + * If a language was requested via a cookie, select that language now. + */ + if (StrLength(Hdr->c_language) > 0) { + syslog(LOG_DEBUG, "Session cookie requests language '%s'", ChrPtr(Hdr->c_language)); + set_selected_language(ChrPtr(Hdr->c_language)); + go_selected_language(); + } + + /* + * do the transaction + */ session_attach_modules(TheSession); - session_loop(); /* do transaction */ + session_loop(); /* How long did this transaction take? */ gettimeofday(&tx_finish, NULL); - syslog(9, "HTTP: 200 [%ld.%06ld] %s %s \n", + syslog(9, "HTTP: 200 [%ld.%06ld] %s %s", ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) / 1000000, ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) % 1000000, ReqStrs[Hdr->HR.eReqType], @@ -701,7 +715,8 @@ const char *ReqStrs[eNONE] = { "DELETE", "HEAD", "MOVE", - "COPY" + "COPY", + "REPORT" }; void @@ -747,6 +762,10 @@ ServerStartModule_CONTEXT v = malloc(sizeof(long)); *v = eCOPY; Put(HttpReqTypes, HKEY("COPY"), v, NULL); + + v = malloc(sizeof(long)); + *v = eREPORT; + Put(HttpReqTypes, HKEY("REPORT"), v, NULL); } void