axdefs[6] = _("Aide"); /* chief */
}
+int ReEstablish_Session(void)
+{
+ StrBuf *Buf = NewStrBuf();
+ wcsession *WCC = WC;
+ serv_printf("USER %s", ChrPtr(WCC->Hdr->c_username));
+ StrBuf_ServGetln(Buf);
+ if (GetServerStatus(Buf, NULL) == 3) {
+ serv_printf("PASS %s", ChrPtr(WCC->Hdr->c_password));
+ StrBuf_ServGetln(Buf);
+ if (GetServerStatus(Buf, NULL) == 2) {
+ become_logged_in(WCC->Hdr->c_username,
+ WCC->Hdr->c_password, Buf);
+ get_preference("default_header_charset", &WCC->DefaultCharset);
+ }
+ }
+ /*
+ * If we don't have a current room, but a cookie specifying the
+ * current room is supplied, make an effort to go there.
+ */
+ if ((StrLength(WCC->wc_roomname) == 0) && (StrLength(WCC->Hdr->c_roomname) > 0)) {
+ serv_printf("GOTO %s",
+ ChrPtr(WCC->Hdr->c_roomname));
+ StrBuf_ServGetln(Buf);
+ if (GetServerStatus(Buf, NULL) == 2) {
+ if (WCC->wc_roomname == NULL) {
+ WCC->wc_roomname = NewStrBufDup(WCC->Hdr->c_roomname);
+ }
+ else {
+ FlushStrBuf(WCC->wc_roomname);
+ StrBufAppendBuf(WCC->wc_roomname, WCC->Hdr->c_roomname, 0);
+ }
+ }
+ }
+ FreeStrBuf(&Buf);
+}
/*
snprintf(buf, sizeof buf,
"OIDS %s|%s://%s/finalize_openid_login|%s://%s",
bstr("openid_url"),
- (is_https ? "https" : "http"), ChrPtr(WCC->http_host),
- (is_https ? "https" : "http"), ChrPtr(WCC->http_host)
+ (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->http_host),
+ (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->http_host)
);
serv_puts(buf);
const char *HKey;
HashPos *Cursor;
- Cursor = GetNewHashPos (WCC->urlstrings, 0);
- while (GetNextHashPos(WCC->urlstrings, Cursor, &HKLen, &HKey, &U)) {
+ Cursor = GetNewHashPos (WCC->Hdr->urlstrings, 0);
+ while (GetNextHashPos(WCC->Hdr->urlstrings, Cursor, &HKLen, &HKey, &U)) {
u = (urlcontent*) U;
if (!strncasecmp(u->url_key, "openid.", 7)) {
serv_printf("%s|%s", &u->url_key[7], ChrPtr(u->url_data));
InitModule_AUTH
(void)
{
- WebcitAddUrlHandler(HKEY("do_welcome"), do_welcome, ANONYMOUS);
- WebcitAddUrlHandler(HKEY("login"), do_login, ANONYMOUS);
+ WebcitAddUrlHandler(HKEY(""), do_welcome, ANONYMOUS|COOKIEUNNEEDED); /* no url pattern at all? Show login. */
+ WebcitAddUrlHandler(HKEY("do_welcome"), do_welcome, ANONYMOUS|COOKIEUNNEEDED);
+ WebcitAddUrlHandler(HKEY("login"), do_login, ANONYMOUS|COOKIEUNNEEDED);
WebcitAddUrlHandler(HKEY("display_openid_login"), _display_openid_login, ANONYMOUS);
WebcitAddUrlHandler(HKEY("openid_login"), do_openid_login, ANONYMOUS);
WebcitAddUrlHandler(HKEY("finalize_openid_login"), finalize_openid_login, ANONYMOUS);
WebcitAddUrlHandler(HKEY("openid_manual_create"), openid_manual_create, ANONYMOUS);
- WebcitAddUrlHandler(HKEY("do_logout"), do_logout, 0);
+ WebcitAddUrlHandler(HKEY("do_logout"), do_logout, ANONYMOUS|COOKIEUNNEEDED|FORCE_SESSIONCLOSE);
WebcitAddUrlHandler(HKEY("validate"), validate, 0);
WebcitAddUrlHandler(HKEY("display_reg"), _display_reg, 0);
WebcitAddUrlHandler(HKEY("display_changepw"), display_changepw, 0);
/*
* Anonymous request of freebusy data for a user
*/
-void do_freebusy(const char *req) {
+void do_freebusy(void)
+{ /// TODO: request line const char *req) {
+ const char req[] = "";
char who[SIZ];
char buf[SIZ];
int len;
-
void
InitModule_CALENDAR
(void)
RegisterPreference("dayend", _("Calendar day view ends at:"), PRF_INT, NULL);
RegisterPreference("weekstart", _("Week starts on:"), PRF_INT, NULL);
+ WebcitAddUrlHandler(HKEY("freebusy"), do_freebusy, COOKIEUNNEEDED|ANONYMOUS|FORCE_SESSIONCLOSE);
WebcitAddUrlHandler(HKEY("display_edit_task"), display_edit_task, 0);
WebcitAddUrlHandler(HKEY("save_task"), save_task, 0);
WebcitAddUrlHandler(HKEY("display_edit_event"), display_edit_event, 0);
pthread_key_t MyConKey; /**< TSD key for MySession() */
HashList *HttpReqTypes = NULL;
+HashList *HttpHeaderHandler = NULL;
+extern HashList *HandlerHash;
+
+void DestroyHttpHeaderHandler(void *V)
+{
+ OneHttpHeader *pHdr;
+ pHdr = (OneHttpHeader*) V;
+ FreeStrBuf(&pHdr->Val);
+ free(pHdr);
+}
void shutdown_sessions(void)
{
+
+/**
+ * \brief Detects a 'mobile' user agent
+ */
+int is_mobile_ua(char *user_agent) {
+ if (strstr(user_agent,"iPhone OS") != NULL) {
+ return 1;
+ } else if (strstr(user_agent,"Windows CE") != NULL) {
+ return 1;
+ } else if (strstr(user_agent,"SymbianOS") != NULL) {
+ return 1;
+ } else if (strstr(user_agent, "Opera Mobi") != NULL) {
+ return 1;
+ } else if (strstr(user_agent, "Firefox/2.0.0 Opera 9.51 Beta") != NULL) {
+ /* For some reason a new install of Opera 9.51beta decided to spoof. */
+ return 1;
+ }
+ return 0;
+}
+
+
+
/*
* Look for commonly-found probes of malware such as worms, viruses, trojans, and Microsoft Office.
* Short-circuit these requests so we don't have to send them through the full processing loop.
*/
-int is_bogus(StrBuf *http_cmd) {
+int is_bogus(StrBuf *http_cmd) {////TODO!
const char *url;
int i, max;
const char *bogus_prefixes[] = {
}
+int ReadHttpSubject(ParsedHttpHdrs *Hdr, StrBuf *Line, StrBuf *Buf)
+{
+ const char *Args;
+ void *vLine, *vHandler;
+ const char *Pos = NULL;
+
+
+ Hdr->ReqLine = Line;
+ /* The requesttype... GET, POST... */
+ StrBufExtract_token(Buf, Hdr->ReqLine, 0, ' ');
+ if (GetHash(HttpReqTypes, SKEY(Buf), &vLine) &&
+ (vLine != NULL))
+ {
+ Hdr->eReqType = *(long*)vLine;
+ }
+ else {
+ Hdr->eReqType = eGET;
+ return 1;
+ }
+ StrBufCutLeft(Hdr->ReqLine, StrLength(Buf) + 1);
+
+ /* the HTTP Version... */
+ StrBufExtract_token(Buf, Hdr->ReqLine, 1, ' ');
+ StrBufCutRight(Hdr->ReqLine, StrLength(Buf) + 1);
+ if ((StrLength(Buf) == 0) ||
+ is_bogus(Hdr->ReqLine)) {
+ Hdr->eReqType = eGET;
+ return 1;
+ }
+
+ Hdr->this_page = NewStrBufDup(Hdr->ReqLine);
+ /* chop Filename / query arguments */
+ Args = strchr(ChrPtr(Hdr->ReqLine), '?');
+ if (Args == NULL) /* whe're not that picky about params... TODO: this will spoil '&' in filenames.*/
+ Args = strchr(ChrPtr(Hdr->ReqLine), '&');
+ if (Args != NULL) {
+ Hdr->PlainArgs = NewStrBufPlain(
+ Args,
+ StrLength(Hdr->ReqLine) -
+ (Args - ChrPtr(Hdr->ReqLine)));
+ StrBufCutAt(Hdr->ReqLine, 0, Args);
+ } /* don't parse them yet, maybe we don't even care... */
+
+ /* now lookup what we are going to do with this... */
+ /* skip first slash */
+ StrBufExtract_NextToken(Buf, Hdr->ReqLine, &Pos, '/');
+ do {
+ StrBufExtract_NextToken(Buf, Hdr->ReqLine, &Pos, '/');
+
+ GetHash(HandlerHash, SKEY(Buf), &vHandler),
+ Hdr->Handler = (WebcitHandler*) vHandler;
+ if (Hdr->Handler == NULL)
+ break;
+ /* are we about to ignore some prefix like webcit/ ? */
+ if ((Hdr->Handler->Flags & URLNAMESPACE) == 0)
+ break;
+ } while (1);
+ /* remove the handlername from the URL */
+ if (Pos != NULL) {
+ StrBufCutLeft(Hdr->ReqLine,
+ Pos - ChrPtr(Hdr->ReqLine));
+ }
+/*
+ if (Hdr->Handler == NULL)
+ return 1;
+*/
+ Hdr->HTTPHeaders = NewHash(1, NULL);
+
+ return 0;
+}
+
+int AnalyseHeaders(ParsedHttpHdrs *Hdr)
+{
+ OneHttpHeader *pHdr;
+ void *vHdr;
+ long HKLen;
+ const char *HashKey;
+ HashPos *at = GetNewHashPos(Hdr->HTTPHeaders, 0);
+
+ while (GetNextHashPos(Hdr->HTTPHeaders, at, &HKLen, &HashKey, &vHdr) &&
+ (vHdr != NULL)) {
+ pHdr = (OneHttpHeader *)vHdr;
+ if (pHdr->HaveEvaluator)
+ pHdr->H(pHdr->Val, Hdr);
+
+ }
+ DeleteHashPos(&at);
+ return 0;
+}
+
/*const char *nix(void *vptr) {return ChrPtr( (StrBuf*)vptr);}*/
/*
- * handle one request
- *
- * This loop gets called once for every HTTP connection made to WebCit. At
- * this entry point we have an HTTP socket with a browser allegedly on the
- * other end, but we have not yet bound to a WebCit session.
- *
- * The job of this function is to locate the correct session and bind to it,
- * or create a session if necessary and bind to it, then run the WebCit
- * transaction loop. Afterwards, we unbind from the session. When this
- * function returns, the worker thread is then free to handle another
- * transaction.
+ * Read in the request
*/
-void context_loop(int *sock)
+int ReadHTTPRequset (ParsedHttpHdrs *Hdr)
{
- long eReqType = eGET;
- int isbogus = 0;
- const char *Pos = NULL;
- const char *buf;
- int desired_session = 0;
- int got_cookie = 0;
- int gzip_ok = 0;
- wcsession *TheSession, *sptr;
- char httpauth_string[1024];
- char httpauth_user[1024];
- char httpauth_pass[1024];
- int nLine = 0;
- int LineLen;
- void *vLine;
- StrBuf *Buf, *Line, *LastLine, *HeaderName, *ReqLine;
const char *pch, *pchs, *pche;
- HashList *HTTPHeaders;
-
- strcpy(httpauth_string, "");
- strcpy(httpauth_user, DEFAULT_HTTPAUTH_USER);
- strcpy(httpauth_pass, DEFAULT_HTTPAUTH_PASS);
+ OneHttpHeader *pHdr;
+ StrBuf *Line, *LastLine, *HeaderName;
+ int nLine = 0;
+ void *vF;
+ int isbogus = 0;
- /*
- * Find out what it is that the web browser is asking for
- */
HeaderName = NewStrBuf();
- Buf = NewStrBuf();
+ Hdr->ReadBuf = NewStrBuf();
LastLine = NULL;
- HTTPHeaders = NewHash(1, NULL);
-
- /*
- * Read in the request
- */
do {
nLine ++;
Line = NewStrBuf();
+ if (ClientGetLine(&Hdr->http_sock, Line, Hdr->ReadBuf, &Hdr->Pos) < 0) return 1;
- if (ClientGetLine(sock, Line, Buf, &Pos) < 0) return;
-
- LineLen = StrLength(Line);
-
- if (nLine == 1) {
- ReqLine = Line;
- /* The requesttype... GET, POST... */
- StrBufExtract_token(HeaderName, ReqLine, 0, ' ');
- if (GetHash(HttpReqTypes, SKEY(HeaderName), &vLine) &&
- (vLine != NULL))
- {
- eReqType = *(long*)vLine;
- }
- else {
- eReqType = eGET;
- isbogus = 1;
- break;
- }
- StrBufCutLeft(ReqLine, StrLength(HeaderName) + 1);
- /* the HTTP Version... */
- StrBufExtract_token(HeaderName, ReqLine, 1, ' ');
- StrBufCutRight(ReqLine, StrLength(HeaderName) + 1);
- if ((StrLength(HeaderName) == 0) ||
- is_bogus(ReqLine)) {
- eReqType = eGET;
- isbogus = 1;
- break;
- }
+ if (StrLength(Line) == 0) {
+ FreeStrBuf(&Line);
continue;
}
- if (LineLen == 0) {
- FreeStrBuf(&Line);
+ if (nLine == 1) {
+ isbogus = ReadHttpSubject(Hdr, Line, HeaderName);
+ if (isbogus) break;
continue;
}
StrBufCutLeft(Line, pch - pchs);
StrBufUpCase(HeaderName);
- Put(HTTPHeaders, SKEY(HeaderName), Line, HFreeStrBuf);
+
+ pHdr = (OneHttpHeader*) malloc(sizeof(OneHttpHeader));
+ memset(pHdr, 0, sizeof(OneHttpHeader));
+ pHdr->Val = Line;
+
+ if (GetHash(HttpHeaderHandler, SKEY(HeaderName), &vF) &&
+ (vF != NULL))
+ {
+ OneHttpHeader *FHdr = (OneHttpHeader*) vF;
+ pHdr->H = FHdr->H;
+ pHdr->HaveEvaluator = 1;
+ }
+ Put(Hdr->HTTPHeaders, SKEY(HeaderName), pHdr, DestroyHttpHeaderHandler);
LastLine = Line;
- } while (LineLen > 0);
+ } while (Line != NULL);
FreeStrBuf(&HeaderName);
- if (isbogus)
- StrBufPlain(ReqLine, HKEY("/404"));
+ return isbogus;
+}
-/* dbg_PrintHash(HTTPHeaders, nix, NULL); */
+/*
+ * handle one request
+ *
+ * This loop gets called once for every HTTP connection made to WebCit. At
+ * this entry point we have an HTTP socket with a browser allegedly on the
+ * other end, but we have not yet bound to a WebCit session.
+ *
+ * The job of this function is to locate the correct session and bind to it,
+ * or create a session if necessary and bind to it, then run the WebCit
+ * transaction loop. Afterwards, we unbind from the session. When this
+ * function returns, the worker thread is then free to handle another
+ * transaction.
+ */
+void context_loop(int *sock)
+{
+ ParsedHttpHdrs Hdr;
+ int isbogus = 0;
+ wcsession *TheSession, *sptr;
+ struct timeval tx_start;
+ struct timeval tx_finish;
+
+ gettimeofday(&tx_start, NULL); /* start a stopwatch for performance timing */
+ memset(&Hdr, 0, sizeof(ParsedHttpHdrs));
+ Hdr.eReqType = eGET;
+ Hdr.http_sock = *sock;
/*
- * Can we compress?
+ * Find out what it is that the web browser is asking for
*/
- if (!isbogus &&
- GetHash(HTTPHeaders, HKEY("ACCEPT-ENCODING"), &vLine) &&
- (vLine != NULL)) {
- buf = ChrPtr((StrBuf*)vLine);
- if (strstr(&buf[16], "gzip")) {
- gzip_ok = 1;
- }
- }
+ isbogus = ReadHTTPRequset(&Hdr);
- /*
- * Browser-based sessions use cookies for session authentication
- */
- if (!isbogus &&
- GetHash(HTTPHeaders, HKEY("COOKIE"), &vLine) &&
- (vLine != NULL)) {
- cookie_to_stuff(vLine, &desired_session,
- NULL, NULL, NULL);
- got_cookie = 1;
- }
+ if (!isbogus)
+ isbogus = AnalyseHeaders(&Hdr);
+/*
+ if (isbogus)
+ StrBufPlain(ReqLine, HKEY("/404"));
+*/
- /*
- * GroupDAV-based sessions use HTTP authentication
- */
- if (!isbogus &&
- GetHash(HTTPHeaders, HKEY("AUTHORIZATION"), &vLine) &&
- (vLine != NULL)) {
- Line = (StrBuf*)vLine;
- if (strncasecmp(ChrPtr(Line), "Basic", 5) == 0) {
- StrBufCutLeft(Line, 6);
- CtdlDecodeBase64(httpauth_string, ChrPtr(Line), StrLength(Line));
- extract_token(httpauth_user, httpauth_string, 0, ':', sizeof httpauth_user);
- extract_token(httpauth_pass, httpauth_string, 1, ':', sizeof httpauth_pass);
- }
- else
- lprintf(1, "Authentication scheme not supported! [%s]\n", ChrPtr(Line));
- }
+/* dbg_PrintHash(HTTPHeaders, nix, NULL); */
+
+
+///HttpHeaderHandler
- if (!isbogus &&
- GetHash(HTTPHeaders, HKEY("IF-MODIFIED-SINCE"), &vLine) &&
- (vLine != NULL)) {
- if_modified_since = httpdate_to_timestamp((StrBuf*)vLine);
- }
* If the request is prefixed by "/webcit" then chop that off. This
* allows a front end web server to forward all /webcit requests to us
* while still using the same web server port for other things.
- */
+ * /
if (!isbogus &&
(StrLength(ReqLine) >= 8) &&
(strstr(ChrPtr(ReqLine), "/webcit/")) ) {
StrBufCutLeft(ReqLine, 7);
}
- /* Begin parsing the request. */
+ /* Begin parsing the request. * /
#ifdef TECH_PREVIEW
if ((strncmp(ChrPtr(ReqLine), "/sslg", 5) != 0) &&
(strncmp(ChrPtr(ReqLine), "/static/", 8) != 0) &&
(strncmp(ChrPtr(ReqLine), "/wholist_section", 16) != 0) &&
(strstr(ChrPtr(ReqLine), "wholist_section") == NULL)) {
#endif
- lprintf(5, "HTTP: %s %s\n", ReqStrs[eReqType], ChrPtr(ReqLine));
+ lprintf(5, "HTTP: %s %s\n", ReqStrs[Hdr.eReqType], ChrPtr(ReqLine));
#ifdef TECH_PREVIEW
}
#endif
-
- /**
- * While we're at it, gracefully handle requests for the
- * robots.txt and favicon.ico files.
- */
- if ((StrLength(ReqLine) >= 11) &&
- !strncasecmp(ChrPtr(ReqLine), "/robots.txt", 11)) {
- StrBufPlain(ReqLine,
- HKEY("/static/robots.txt"
- "?force_close_session=yes HTTP/1.1"));
- eReqType = eGET;
- }
- else if ((StrLength(ReqLine) >= 11) &&
- !strncasecmp(ChrPtr(ReqLine), "/favicon.ico", 12)) {
- StrBufPlain(ReqLine, HKEY("/static/favicon.ico"));
- eReqType = eGET;
- }
-
- /**
- * These are the URL's which may be executed without a
- * session cookie already set. If it's not one of these,
- * force the session to close because cookies are
- * probably disabled on the client browser.
- */
- else if ( (StrLength(ReqLine) > 1 )
- && (strncasecmp(ChrPtr(ReqLine), "/listsub", 8))
- && (strncasecmp(ChrPtr(ReqLine), "/freebusy", 9))
- && (strncasecmp(ChrPtr(ReqLine), "/do_logout", 10))
- && (strncasecmp(ChrPtr(ReqLine), "/groupdav", 9))
- && (strncasecmp(ChrPtr(ReqLine), "/static", 7))
- && (strncasecmp(ChrPtr(ReqLine), "/rss", 4))
- && (strncasecmp(ChrPtr(ReqLine), "/404", 4))
- && (got_cookie == 0)) {
- StrBufPlain(ReqLine,
- HKEY("/static/nocookies.html"
- "?force_close_session=yes"));
- }
+*/
/**
* See if there's an existing session open with the desired ID or user/pass
((sptr != NULL) && (TheSession == NULL));
sptr = sptr->next) {
- /** If HTTP-AUTH, look for a session with matching credentials */
- if ( (!IsEmptyStr(httpauth_user))
+ /** If HTTP-AUTH, look for a session with matching credentials * /
+ if ( (////TODO check auth type here...
&&(!strcasecmp(ChrPtr(sptr->httpauth_user), httpauth_user))
&&(!strcasecmp(ChrPtr(sptr->httpauth_pass), httpauth_pass)) ) {
TheSession = sptr;
}
/** If cookie-session, look for a session with matching session ID */
- if ( (desired_session != 0) && (sptr->wc_session == desired_session)) {
+ if ( (Hdr.desired_session != 0) && (sptr->wc_session == Hdr.desired_session)) {
TheSession = sptr;
}
TheSession = (wcsession *)
malloc(sizeof(wcsession));
memset(TheSession, 0, sizeof(wcsession));
- TheSession->headers = HTTPHeaders;
+ TheSession->Hdr = &Hdr;
TheSession->serv_sock = (-1);
TheSession->chat_sock = (-1);
* doesn't, and that's a Bad Thing because it causes lots of spurious sessions
* to get created.
*/
- if (desired_session == 0) {
+ if (Hdr.desired_session == 0) {
TheSession->wc_session = GenerateSessionID();
}
else {
- TheSession->wc_session = desired_session;
+ TheSession->wc_session = Hdr.desired_session;
}
-
+/*
TheSession->httpauth_user = NewStrBufPlain(httpauth_user, -1);
- TheSession->httpauth_pass = NewStrBufPlain(httpauth_user, -1);
-
+ TheSession->httpauth_pass = NewStrBufPlain(httpauth_user, -1);
+*/
pthread_setspecific(MyConKey, (void *)TheSession);
session_new_modules(TheSession);
pthread_mutex_lock(&TheSession->SessionMutex); /* bind */
pthread_setspecific(MyConKey, (void *)TheSession);
- TheSession->eReqType = eReqType;
- TheSession->headers = HTTPHeaders;
TheSession->lastreq = time(NULL); /* log */
- TheSession->http_sock = *sock;
- TheSession->gzip_ok = gzip_ok;
+ TheSession->Hdr = &Hdr;
session_attach_modules(TheSession);
- session_loop(ReqLine, Buf, &Pos); /* do transaction */
+ session_loop(); /* do transaction */
session_detach_modules(TheSession);
- TheSession->headers = NULL;
+ TheSession->Hdr = NULL;
pthread_mutex_unlock(&TheSession->SessionMutex); /* unbind */
-
+/* TODO
+
+ FreeStrBuf(&c_username);
+ FreeStrBuf(&c_password);
+ FreeStrBuf(&c_roomname);
+ FreeStrBuf(&c_httpauth_user);
+ FreeStrBuf(&c_httpauth_pass);
+*/
/* Free the request buffer */
- DeleteHash(&HTTPHeaders);
- FreeStrBuf(&ReqLine);
- FreeStrBuf(&Buf);
+ ///DeleteHash(&HTTPHeaders);
+ ///FreeStrBuf(&ReqLine);
+
+ /* How long did this transaction take? */
+ gettimeofday(&tx_finish, NULL);
+
+ lprintf(9, "Transaction completed in %ld.%06ld seconds.\n",
+ ((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
+ );
}
void tmplput_nonce(StrBuf *Target, WCTemplputParams *TP)
StrBufAppendTemplate(Target, TP, WC->wc_roomname, 0);
}
+
+void Header_HandleCookie(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+ hdr->RawCookie = Line;
+ if (hdr->DontNeedAuth)
+ return;
+/*
+ c_username = NewStrBuf();
+ c_password = NewStrBuf();
+ c_roomname = NewStrBuf();
+ safestrncpy(c_httpauth_string, "", sizeof c_httpauth_string);
+ c_httpauth_user = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_USER));
+ c_httpauth_pass = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_PASS));
+*/
+ cookie_to_stuff(Line, &hdr->desired_session,
+ hdr->c_username,
+ hdr->c_password,
+ hdr->c_roomname);
+ hdr->got_cookie = 1;
+}
+
+
+ /*
+ * Browser-based sessions use cookies for session authentication
+ * /
+ if (!isbogus &&
+ GetHash(HTTPHeaders, HKEY("COOKIE"), &vLine) &&
+ (vLine != NULL)) {
+ cookie_to_stuff(vLine, &desired_session,
+ NULL, NULL, NULL);
+ got_cookie = 1;
+ }
+ */
+ /*
+ * GroupDAV-based sessions use HTTP authentication
+ */
+/*
+ if (!isbogus &&
+ GetHash(HTTPHeaders, HKEY("AUTHORIZATION"), &vLine) &&
+ (vLine != NULL)) {
+ Line = (StrBuf*)vLine;
+ if (strncasecmp(ChrPtr(Line), "Basic", 5) == 0) {
+ StrBufCutLeft(Line, 6);
+ CtdlDecodeBase64(httpauth_string, ChrPtr(Line), StrLength(Line));
+ extract_token(httpauth_user, httpauth_string, 0, ':', sizeof httpauth_user);
+ extract_token(httpauth_pass, httpauth_string, 1, ':', sizeof httpauth_pass);
+ }
+ else
+ lprintf(1, "Authentication scheme not supported! [%s]\n", ChrPtr(Line));
+ }
+
+*/
+void Header_HandleAuth(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+ const char *Pos = NULL;
+ StrBufDecodeBase64(Line);
+ StrBufExtract_NextToken(hdr->c_username, Line, &Pos, ':');
+ StrBufExtract_NextToken(hdr->c_password, Line, &Pos, ':');
+}
+
+void Header_HandleContentLength(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+ hdr->ContentLength = StrToi(Line);
+}
+
+void Header_HandleContentType(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+ hdr->ContentType = Line;
+}
+
+void Header_HandleUserAgent(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+ hdr->user_agent = Line;
+#ifdef TECH_PREVIEW
+/* TODO: do this later on session creating
+ if ((WCC->is_mobile < 0) && is_mobile_ua(&buf[12])) {
+ WCC->is_mobile = 1;
+ }
+ else {
+ WCC->is_mobile = 0;
+ }
+*/
+#endif
+}
+
+
+void Header_HandleHost(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+ if ((follow_xff) && (hdr->http_host != NULL))
+ return;
+ else
+ hdr->http_host = Line;
+}
+
+void Header_HandleXFFHost(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+ if (follow_xff)
+ hdr->http_host = Line;
+}
+
+
+void Header_HandleXFF(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+ hdr->browser_host = Line;
+
+ while (StrBufNum_tokens(hdr->browser_host, ',') > 1) {
+ StrBufRemove_token(hdr->browser_host, 0, ',');
+ }
+ StrBufTrim(hdr->browser_host);
+}
+
+void Header_HandleIfModSince(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+ hdr->if_modified_since = httpdate_to_timestamp(Line);
+}
+
+void Header_HandleAcceptEncoding(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+ /*
+ * Can we compress?
+ */
+ if (strstr(&ChrPtr(Line)[16], "gzip")) {
+ hdr->gzip_ok = 1;
+ }
+}
+
+/*
+{
+ c_username = NewStrBuf();
+ c_password = NewStrBuf();
+ c_roomname = NewStrBuf();
+ safestrncpy(c_httpauth_string, "", sizeof c_httpauth_string);
+ c_httpauth_user = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_USER));
+ c_httpauth_pass = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_PASS));
+}
+*/
+ /* *
+ * These are the URL's which may be executed without a
+ * session cookie already set. If it's not one of these,
+ * force the session to close because cookies are
+ * probably disabled on the client browser.
+ * /
+ else if ( (StrLength(ReqLine) > 1 )
+ && (strncasecmp(ChrPtr(ReqLine), "/404", 4))
+ && (Hdr.got_cookie == 0)) {
+ StrBufPlain(ReqLine,
+ HKEY("/static/nocookies.html"
+ "?force_close_session=yes"));
+ }
+*/
const char *ReqStrs[eNONE] = {
"GET",
"POST",
{
long *v;
HttpReqTypes = NewHash(1, NULL);
-
+ HttpHeaderHandler = NewHash(1, NULL);
v = malloc(sizeof(long));
*v = eGET;
(void)
{
DeleteHash(&HttpReqTypes);
+ DeleteHash(&HttpHeaderHandler);
}
-
+void RegisterHeaderHandler(const char *Name, long Len, Header_Evaluator F)
+{
+ OneHttpHeader *pHdr;
+ pHdr = (OneHttpHeader*) malloc(sizeof(OneHttpHeader));
+ memset(pHdr, 0, sizeof(OneHttpHeader));
+ pHdr->H = F;
+ Put(HttpHeaderHandler, Name, Len, pHdr, DestroyHttpHeaderHandler);
+}
+extern void blank_page(void); ///TODO: remove me
void
InitModule_CONTEXT
(void)
{
+ RegisterHeaderHandler(HKEY("COOKIE"), Header_HandleCookie);
+ RegisterHeaderHandler(HKEY("AUTHORIZATION"), Header_HandleAuth);
+ RegisterHeaderHandler(HKEY("CONTENT-LENGTH"), Header_HandleContentLength);
+ RegisterHeaderHandler(HKEY("CONTENT-TYPE"), Header_HandleContentType);
+ RegisterHeaderHandler(HKEY("USER-AGENT"), Header_HandleUserAgent);
+ RegisterHeaderHandler(HKEY("X-FORWARDED-HOST"), Header_HandleXFFHost);
+ RegisterHeaderHandler(HKEY("HOST"), Header_HandleHost);
+ RegisterHeaderHandler(HKEY("X-FORWARDED-FOR"), Header_HandleXFF);
+ RegisterHeaderHandler(HKEY("ACCEPT-ENCODING"), Header_HandleAcceptEncoding);
+ RegisterHeaderHandler(HKEY("IF-MODIFIED-SINCE"), Header_HandleIfModSince);
+
RegisterNamespace("CURRENT_USER", 0, 1, tmplput_current_user, CTX_NONE);
RegisterNamespace("CURRENT_ROOM", 0, 1, tmplput_current_room, CTX_NONE);
RegisterNamespace("NONCE", 0, 0, tmplput_nonce, 0);
+
+
+
+ WebcitAddUrlHandler(HKEY("blank"), blank_page, ANONYMOUS|BOGUS);
+
+ WebcitAddUrlHandler(HKEY("blank"), blank_page, URLNAMESPACE);
}
+//FreeStrBuf(&WCC->this_page);
+
snprintf (FileBuf, SIZ, "%s%s", static_dirs[0], "/diskette_24x.gif");
else
snprintf (FileBuf, SIZ, "%s%s", static_dirs[3], FileName);
- output_static(FileBuf);
+ //// TODO! output_static(FileBuf);
}
void download_file(void)
int force_download = 1;
Buf = NewStrBuf();
- StrBufUnescape(WCC->UrlFragment2, 1);
- serv_printf("OPEN %s", ChrPtr(WCC->UrlFragment2));
+ StrBufExtract_token(Buf, WCC->Hdr->ReqLine, 2, '/');
+ StrBufUnescape(Buf, 1);
+ serv_printf("OPEN %s", ChrPtr(Buf));
StrBuf_ServGetln(Buf);
if (GetServerStatus(Buf, NULL) == 2) {
StrBufCutLeft(Buf, 4);
* when there's no such image on the server.
*/
StrBufPrintf (Buf, "%s%s", static_dirs[0], "/blank.gif");
- output_static(ChrPtr(Buf));
+ //// TDODO output_static(ChrPtr(Buf));
FreeStrBuf(&Buf);
}
{
#ifdef ENABLE_NLS
void *vLine;
-
- if (GetHash(WC->headers, HKEY("ACCEPT-LANGUAGE"), &vLine) &&
+ ////TODO: make me a header getter
+ if (GetHash(WC->Hdr->HTTPHeaders, HKEY("ACCEPT-LANGUAGE"), &vLine) &&
(vLine != NULL)) {
StrBuf *accept_language = (StrBuf*) vLine;
httplang_to_locale(accept_language);
strcpy(dav_ifmatch, "");
dav_depth = 0;
- if ((StrLength(WCC->http_host) == 0) &&
+ if ((StrLength(WCC->Hdr->http_host) == 0) &&
GetHash(HTTPHeaders, HKEY("HOST"), &vLine) &&
(vLine != NULL)) {
- WCC->http_host = (StrBuf*)vLine;
+ WCC->Hdr->http_host = (StrBuf*)vLine;
}
if (GetHash(HTTPHeaders, HKEY("IF-MATCH"), &vLine) &&
(vLine != NULL)) {
}
}
- switch (WCC->eReqType)
+ switch (WCC->Hdr->eReqType)
{
/*
* The OPTIONS method is not required by GroupDAV. This is an
groupdav_common_headers();
hprintf("Content-Type: text/plain\r\n");
wprintf("GroupDAV method \"%s\" is not implemented.\r\n",
- ReqStrs[WCC->eReqType]);
+ ReqStrs[WCC->Hdr->eReqType]);
end_burst();
}
}
void groupdav_identify_host(void) {
wcsession *WCC = WC;
- if (StrLength(WCC->http_host)!=0) {
+ if (StrLength(WCC->Hdr->http_host)!=0) {
wprintf("%s://%s",
(is_https ? "https" : "http"),
- ChrPtr(WCC->http_host));
+ ChrPtr(WCC->Hdr->http_host));
}
}
+
+
+void
+InitModule_GROUPDAV
+(void)
+{
+
+ WebcitAddUrlHandler(HKEY("groupdav"), do_logout, XHTTP_COMMANDS|COOKIEUNNEEDED|FORCE_SESSIONCLOSE);
+
+}
email,
subtype,
(is_https ? "https" : "http"),
- ChrPtr(WC->http_host)
+ ChrPtr(WC->Hdr->http_host)
);
serv_getln(buf, sizeof buf);
if (buf[0] == '2') {
room,
email,
(is_https ? "https" : "http"),
- ChrPtr(WC->http_host)
+ ChrPtr(WC->Hdr->http_host)
);
serv_getln(buf, sizeof buf);
if (buf[0] == '2') {
wDumpContent(0);
end_webcit_session();
}
+
+
+
+void
+InitModule_LISTSUB
+(void)
+{
+ WebcitAddUrlHandler(HKEY("listsub"), do_listsub, ANONYMOUS|COOKIEUNNEEDED|FORCE_SESSIONCLOSE);
+
+
+}
wprintf("<br /><textarea name=\"g_input\" rows=10 cols=80 width=80></textarea><br />\n");
wprintf("<font size=-2>");
- wprintf(_("Detected host header is %s://%s"), (is_https ? "https" : "http"), ChrPtr(WC->http_host));
+ wprintf(_("Detected host header is %s://%s"), (is_https ? "https" : "http"), ChrPtr(WC->Hdr->http_host));
wprintf("</font>\n");
wprintf("<input type=\"submit\" name=\"sc_button\" value=\"%s\">", _("Send command"));
wprintf(" ");
output_headers(1, 0, 0, 0, 1, 0);
DoTemplate(HKEY("display_serverrestart"), NULL, &NoCtx);
end_burst();
- lingering_close(WC->http_sock);
+ lingering_close(WC->Hdr->http_sock);
sleeeeeeeeeep(10);
serv_printf("NOOP");
serv_printf("NOOP");
const StrBuf *Tmpl;
StrBuf *CmdBuf = NULL;
- msgnum = StrTol(WCC->UrlFragment3);
- gotoroom(WCC->UrlFragment2);
- switch (WCC->eReqType)
+ //msgnum = StrTol(WCC->UrlFragment3);
+ //gotoroom(WCC->UrlFragment2);
+ switch (WCC->Hdr->eReqType)
{
case eGET:
case ePOST:
case eCOPY:
CopyMessage = 1;
case eMOVE:
- if (GetHash(WCC->headers, HKEY("DESTINATION"), &vLine) &&
+ if (GetHash(WCC->Hdr->HTTPHeaders, HKEY("DESTINATION"), &vLine) &&
(vLine!=NULL)) {
Destination = (StrBuf*) vLine;
serv_printf("MOVE %ld|%s|%d", msgnum, ChrPtr(Destination), CopyMessage);
const StrBuf *Tmpl;
StrBuf *CmdBuf = NULL;
- msgnum = StrTol(WCC->UrlFragment2);
- switch (WCC->eReqType)
+ msgnum = StrBufExtract_long(WCC->Hdr->ReqLine, 2, '/');
+ switch (WCC->Hdr->eReqType)
{
case eGET:
case ePOST:
long msgnum = 0L;
const StrBuf *Mime;
- msgnum = StrTol(WC->UrlFragment2);
+ msgnum = StrBufExtract_long(WC->Hdr->ReqLine, 2, '/');
output_headers(0, 0, 0, 0, 0, 0);
hprintf("Content-type: text/html\r\n"
long msgnum = 0L;
const StrBuf *Mime;
- msgnum = StrTol(WC->UrlFragment2);
+ msgnum = StrBufExtract_long(WC->Hdr->ReqLine, 2, '/');
output_headers(1, 0, 0, 0, 0, 1);
begin_burst();
do_template("msgcontrols", NULL);
long msgnum = 0L;
char buf[1024];
- msgnum = StrTol(WC->UrlFragment2);
+ msgnum = StrBufExtract_long(WC->Hdr->ReqLine, 2, '/');
output_headers(0, 0, 0, 0, 0, 0);
hprintf("Content-type: text/plain\r\n"
*/
void mimepart(int force_download)
{
+ long msgnum, att;
wcsession *WCC = WC;
StrBuf *Buf;
off_t bytes;
StrBuf *ContentType = NewStrBufPlain(HKEY("application/octet-stream"));
const char *CT;
+ msgnum = StrBufExtract_long(WCC->Hdr->ReqLine, 2, '/');
+ att = StrBufExtract_long(WCC->Hdr->ReqLine, 3, '/');
+
Buf = NewStrBuf();
- serv_printf("OPNA %s|%s", ChrPtr(WCC->UrlFragment2), ChrPtr(WCC->UrlFragment3));
+ serv_printf("OPNA %ld|%ld", msgnum, att);
StrBuf_ServGetln(Buf);
if (GetServerStatus(Buf, NULL) == 2) {
StrBufCutLeft(Buf, 4);
if (!force_download) {
if (!strcasecmp(ChrPtr(ContentType), "application/octet-stream")) {
- CT = GuessMimeByFilename(SKEY(WCC->UrlFragment4));
+ StrBufExtract_token(Buf, WCC->Hdr->ReqLine, 4, '/');
+ CT = GuessMimeByFilename(SKEY(Buf));
}
if (!strcasecmp(ChrPtr(ContentType), "application/octet-stream")) {
CT = GuessMimeType(SKEY(WCC->WBuf));
}
void view_postpart(void) {
- postpart(WC->UrlFragment2,
- WC->UrlFragment3,
- 0);
+ StrBuf *filename = NewStrBuf();
+ StrBuf *partnum = NewStrBuf();
+
+ StrBufExtract_token(partnum, WC->Hdr->ReqLine, 2, '/');
+ StrBufExtract_token(filename, WC->Hdr->ReqLine, 3, '/');
+
+ postpart(partnum, filename, 0);
+
+ FreeStrBuf(&filename);
+ FreeStrBuf(&partnum);
}
void download_postpart(void) {
- postpart(WC->UrlFragment2,
- WC->UrlFragment3,
- 1);
+ StrBuf *filename = NewStrBuf();
+ StrBuf *partnum = NewStrBuf();
+
+ StrBufExtract_token(partnum, WC->Hdr->ReqLine, 2, '/');
+ StrBufExtract_token(filename, WC->Hdr->ReqLine, 3, '/');
+
+ postpart(partnum, filename, 1);
+
+ FreeStrBuf(&filename);
+ FreeStrBuf(&partnum);
}
void h_readnew(void) { readloop(readnew);}
WebcitAddUrlHandler(HKEY("delete_msg"), delete_msg, 0);
WebcitAddUrlHandler(HKEY("confirm_move_msg"), confirm_move_msg, 0);
WebcitAddUrlHandler(HKEY("msg"), embed_message, NEED_URL);
- WebcitAddUrlHandler(HKEY("message"), handle_one_message, NEED_URL|XHTTP_COMMANDS);
+ WebcitAddUrlHandler(HKEY("message"), handle_one_message, NEED_URL|XHTTP_COMMANDS|COOKIEUNNEEDED|FORCE_SESSIONCLOSE);
WebcitAddUrlHandler(HKEY("printmsg"), print_message, NEED_URL);
WebcitAddUrlHandler(HKEY("mobilemsg"), mobile_message_view, NEED_URL);
WebcitAddUrlHandler(HKEY("msgheaders"), display_headers, NEED_URL);
void SetAccessCommand(long Oper)
{
+/* TODO: whats achieved by this?
wcsession *WCC = WC;
if (WCC->UrlFragment1 != NULL ) {
}
else
WCC->UrlFragment1 = NewStrBufPlain(rlid[Oper].name.Key, rlid[Oper].name.len);
+*/
}
snprintf(buf, sizeof buf,
"OIDS %s|%s://%s/finalize_openid_login|%s://%s",
bstr("openid_url"),
- (is_https ? "https" : "http"), ChrPtr(WCC->http_host),
- (is_https ? "https" : "http"), ChrPtr(WCC->http_host)
+ (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->http_host),
+ (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->http_host)
);
serv_puts(buf);
urlcontent *u;
wcsession *WCC = WC;
- if (WCC->urlstrings == NULL)
- WCC->urlstrings = NewHash(1, NULL);
+ if (WCC->Hdr->urlstrings == NULL)
+ WCC->Hdr->urlstrings = NewHash(1, NULL);
eptr = ChrPtr(url) + StrLength(url);
up = ChrPtr(url);
while ((up < eptr) && (!IsEmptyStr(up))) {
continue;
}
- Put(WCC->urlstrings, u->url_key, keylen, u, free_url);
+ Put(WCC->Hdr->urlstrings, u->url_key, keylen, u, free_url);
len = bptr - aptr;
u->url_data = NewStrBufPlain(aptr, len);
StrBufUnescape(u->url_data, 1);
*/
void free_urls(void)
{
- DeleteHash(&WC->urlstrings);
+ DeleteHash(&WC->Hdr->urlstrings);
}
/*
const char *HKey;
HashPos *Cursor;
- Cursor = GetNewHashPos (WCC->urlstrings, 0);
- while (GetNextHashPos(WCC->urlstrings, Cursor, &HKLen, &HKey, &U)) {
+ Cursor = GetNewHashPos (WCC->Hdr->urlstrings, 0);
+ while (GetNextHashPos(WCC->Hdr->urlstrings, Cursor, &HKLen, &HKey, &U)) {
u = (urlcontent*) U;
wprintf("%38s = %s\n", u->url_key, ChrPtr(u->url_data));
}
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, keylen, &U)) {
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, keylen, &U)) {
*len = StrLength(((urlcontent *)U)->url_data);
return ChrPtr(((urlcontent *)U)->url_data);
}
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, strlen (key), &U)){
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, strlen (key), &U)){
*len = StrLength(((urlcontent *)U)->url_data);
return ChrPtr(((urlcontent *)U)->url_data);
}
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, strlen (key), &U))
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, strlen (key), &U))
return ChrPtr(((urlcontent *)U)->url_data);
else
return ("");
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, keylen, &U))
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, keylen, &U))
return ChrPtr(((urlcontent *)U)->url_data);
else
return ("");
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, strlen (key), &U))
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, strlen (key), &U))
return ((urlcontent *)U)->url_data;
else
return NULL;
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, keylen, &U))
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, keylen, &U))
return ((urlcontent *)U)->url_data;
else
return NULL;
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, keylen, &U))
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, keylen, &U))
return StrTol(((urlcontent *)U)->url_data);
else
return (0);
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, strlen(key), &U))
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, strlen(key), &U))
return StrTol(((urlcontent *)U)->url_data);
else
return (0);
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, keylen, &U))
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, keylen, &U))
return StrTol(((urlcontent *)U)->url_data);
else
return (0);
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, strlen(key), &U))
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, strlen(key), &U))
return StrToi(((urlcontent *)U)->url_data);
else
return (0);
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, keylen, &U))
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, keylen, &U))
return (StrLength(((urlcontent *)U)->url_data) != 0);
else
return (0);
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, strlen(key), &U))
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, strlen(key), &U))
return (StrLength(((urlcontent *)U)->url_data) != 0);
else
return (0);
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, keylen, &U))
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, keylen, &U))
return strcmp( ChrPtr(((urlcontent *)U)->url_data), "yes") == 0;
else
return (0);
{
void *U;
- if ((WC->urlstrings != NULL) &&
- GetHash(WC->urlstrings, key, strlen(key), &U))
+ if ((WC->Hdr->urlstrings != NULL) &&
+ GetHash(WC->Hdr->urlstrings, key, strlen(key), &U))
return strcmp( ChrPtr(((urlcontent *)U)->url_data), "yes") == 0;
else
return (0);
#ifdef DEBUG_URLSTRINGS
lprintf(9, "upload_handler() name=%s, type=%s, len=%d\n", name, cbtype, length);
#endif
- if (WC->urlstrings == NULL)
- WC->urlstrings = NewHash(1, NULL);
+ if (WC->Hdr->urlstrings == NULL)
+ WC->Hdr->urlstrings = NewHash(1, NULL);
/* Form fields */
if ( (length > 0) && (IsEmptyStr(cbtype)) ) {
safestrncpy(u->url_key, name, sizeof(u->url_key));
u->url_data = NewStrBufPlain(content, length);
- Put(WC->urlstrings, u->url_key, strlen(u->url_key), u, free_url);
+ Put(WC->Hdr->urlstrings, u->url_key, strlen(u->url_key), u, free_url);
#ifdef DEBUG_URLSTRINGS
lprintf(9, "Key: <%s> len: [%ld] Data: <%s>\n",
u->url_key,
u = (urlcontent*)malloc(sizeof(urlcontent));
memcpy(u->url_key, key, keylen + 1);
u->url_data = Value;
- Put(WC->urlstrings, u->url_key, keylen, u, free_url);
+ Put(WC->Hdr->urlstrings, u->url_key, keylen, u, free_url);
}
output_headers(1, 1, 1, 0, 0, 0);
wprintf("Session: %d<hr />\n", WC->wc_session);
wprintf("Command: <br /><PRE>\n");
- StrEscPuts(WC->UrlFragment1);
+/*
+StrEscPuts(WC->UrlFragment1);
wprintf("<br />\n");
StrEscPuts(WC->UrlFragment2);
wprintf("<br />\n");
StrEscPuts(WC->UrlFragment3);
+*/
wprintf("</PRE><hr />\n");
wprintf("Variables: <br /><PRE>\n");
dump_vars();
wcsession *WCC = WC;
if (WCC != NULL) {
- if (TP->Tokens->Params[0]->lvalue == 0)
- UrlBuf = WCC->UrlFragment1;
- else if (TP->Tokens->Params[0]->lvalue == 1)
- UrlBuf = WCC->UrlFragment2;
- else
- UrlBuf = WCC->UrlFragment3;
+ if (TP->Tokens->Params[0]->lvalue == 0) {
+ UrlBuf = NewStrBuf();
+ StrBufExtract_token(UrlBuf, WCC->Hdr->ReqLine, 1, '/');
+ }
+ else if (TP->Tokens->Params[0]->lvalue == 1) {
+ UrlBuf = NewStrBuf();
+ StrBufExtract_token(UrlBuf, WCC->Hdr->ReqLine, 2, '/');
+ }
+ else {
+ UrlBuf = NewStrBuf();
+ StrBufExtract_token(UrlBuf, WCC->Hdr->ReqLine, 3, '/');
+ }
+
if (UrlBuf == NULL) {
LogTemplateError(Target, "urlbuf", ERR_PARM1, TP, "not set.");
}
StrBufAppendTemplate(Target, TP, UrlBuf, 2);
+ FreeStrBuf(&UrlBuf);
}
}
SessionAttachModule_PARAMHANDLING
(wcsession *sess)
{
- sess->urlstrings = NewHash(1,NULL);
+ sess->Hdr->urlstrings = NewHash(1,NULL);
}
void
SessionDetachModule_PARAMHANDLING
(wcsession *sess)
{
- DeleteHash(&sess->urlstrings);
+ DeleteHash(&sess->Hdr->urlstrings);
}
void offer_start_page(StrBuf *Target, WCTemplputParams *TP)
{
wprintf("<a href=\"change_start_page?startpage=");
- urlescputs(ChrPtr(WC->this_page));
+ urlescputs(ChrPtr(WC->Hdr->this_page));
wprintf("\">");
wprintf(_("Make this my start page"));
wprintf("</a>");
*/
void embed_room_banner(char *got, int navbar_style) {
+ wcsession *WCC = WC;
char buf[256];
char buf2[1024];
char with_files[256];
* we want it to remember the URL as a "/dotskip" one instead of
* a "skip" or "gotonext" or something like that.
*/
- if (WC->this_page == NULL)
- WC->this_page = NewStrBuf();
- StrBufPrintf(WC->this_page,
+ if (WCC->Hdr->this_page == NULL)
+ WCC->Hdr->this_page = NewStrBuf();
+ StrBufPrintf(WCC->Hdr->this_page,
"dotskip&room=%s",
ChrPtr(WC->wc_roomname));
wprintf(_("The URL for subscribe/unsubscribe is: "));
wprintf("<TT>%s://%s/listsub</TT></td></tr>\n",
(is_https ? "https" : "http"),
- ChrPtr(WC->http_host));
+ ChrPtr(WC->Hdr->http_host));
/* Public posting? */
wprintf("<tr><td>");
wprintf(_("Allow non-subscribers to mail to this room."));
StrBuf *FloorDiv;
FloorDiv = NewStrBuf();
- StrBufAppendBuf(FloorDiv, WCC->UrlFragment2, 0);
+ StrBufExtract_token(FloorDiv, WCC->Hdr->ReqLine, 2, '/');
set_preference("floordiv_expanded", FloorDiv, 1);
WCC->floordiv_expanded = FloorDiv;
}
#define ALLOW_ANON_RSS 0
#define ANON_RSS_USER ""
#define ANON_RSS_PASS ""
-time_t if_modified_since; /**< the last modified stamp */
/*
* view rss Config menu
}
}
/*/ Commented out. Play dumb for now, also doesn't work with anonrss hack */
- /* if (if_modified_since > 0 && if_modified_since > now) {
+ /* if (WCC->Hdr->if_modified_since > 0 && WCC->Hdr->if_modified_since > now) {
lprintf(3, "RSS: Feed not updated since the last time you looked\n");
hprintf("HTTP/1.1 304 Not Modified\r\n");
hprintf("Last-Modified: %s\r\n", date);
hprintf("Content-Type: application/rss+xml\r\n");
hprintf("Server: %s\r\n", PACKAGE_STRING);
hprintf("Connection: close\r\n");
- if (WCC->eReqType == eHEAD)
+ if (WCC->Hdr->eReqType == eHEAD)
return;
/* <?xml.. etc confuses our subst parser, so do it here */
SVPutBuf("ROOM", WCC->wc_roomname, 1);
SVPutBuf("NODE", WCC->serv_info->serv_humannode, 1);
/* TODO: Fix me */
- svprintf(HKEY("ROOM_LINK"), WCS_STRING, "%s://%s/", (is_https ? "https" : "http"), ChrPtr(WCC->http_host));
+ svprintf(HKEY("ROOM_LINK"), WCS_STRING, "%s://%s/", (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->http_host));
/** Get room info for description */
serv_puts("RINF");
}
+void
+InitModule_RSS
+(void)
+{
+ WebcitAddUrlHandler(HKEY("do_welcome"), display_rss, COOKIEUNNEEDED|FORCE_SESSIONCLOSE);
+
+}
#include "webcit.h"
#include "webserver.h"
+int is_uds = 0;
+char serv_sock_name[PATH_MAX] = "";
void DeleteServInfo(ServInfo **FreeMe)
{
* browser_host the citadell we want to connect to
* user_agent which browser uses our client?
*/
-ServInfo *get_serv_info(StrBuf *browser_host, char *user_agent)
+ServInfo *get_serv_info(StrBuf *browser_host, StrBuf *user_agent)
{
ServInfo *info;
StrBuf *Buf;
DEVELOPER_ID,
CLIENT_ID,
CLIENT_VERSION,
- user_agent,
+ ChrPtr(user_agent),
ChrPtr(browser_host)
);
StrBuf_ServGetln(Buf);
return info;
}
+int GetConnected (void)
+{
+ StrBuf *Buf;
+ wcsession *WCC = WC;
+
+ if (WCC->ReadBuf == NULL)
+ WCC->ReadBuf = NewStrBuf();
+ if (is_uds) /* unix domain socket */
+ WCC->serv_sock = uds_connectsock(serv_sock_name);
+ else /* tcp socket */
+ WCC->serv_sock = tcp_connectsock(ctdlhost, ctdlport);
+
+ if (WCC->serv_sock < 0) {
+ do_logout();
+ FreeStrBuf(&WCC->ReadBuf);
+ return 1;
+ }
+ else {
+ long Status;
+ Buf = NewStrBuf();
+ WCC->connected = 1;
+ StrBuf_ServGetln(Buf); /* get the server greeting */
+ GetServerStatus(Buf, &Status);
+ FreeStrBuf(&Buf);
+ /* Are there too many users already logged in? */
+ if (Status == 571) {
+ wprintf(_("This server is already serving its maximum number of users and cannot accept any additional logins at this time. Please try again later or contact your system administrator."));
+ end_burst();
+ end_webcit_session();
+ return 1;
+ }
+
+ /*
+ * From what host is our user connecting? Go with
+ * the host at the other end of the HTTP socket,
+ * unless we are following X-Forwarded-For: headers
+ * and such a header has already turned up something.
+ */
+ if ( (!follow_xff) || (StrLength(WCC->Hdr->browser_host) == 0) ) {
+ if (WCC->Hdr->browser_host == NULL) {
+ WCC->Hdr->browser_host = NewStrBuf();
+ Put(WCC->Hdr->HTTPHeaders, HKEY("FreeMeWithTheOtherHeaders"),
+ WCC->Hdr->browser_host, HFreeStrBuf);
+ }
+ locate_host(WCC->Hdr->browser_host, WCC->Hdr->http_sock);
+ }
+ if (WCC->serv_info == NULL)
+ WCC->serv_info = get_serv_info(WCC->Hdr->browser_host, WCC->Hdr->user_agent);
+ if (WCC->serv_info == NULL){
+ begin_burst();
+ wprintf(_("Received unexpected answer from Citadel "
+ "server; bailing out."));
+ hprintf("HTTP/1.1 200 OK\r\n");
+ hprintf("Content-type: text/plain; charset=utf-8\r\n");
+ end_burst();
+ end_webcit_session();
+ return 1;
+ }
+ if (WCC->serv_info->serv_rev_level < MINIMUM_CIT_VERSION) {
+ begin_burst();
+ wprintf(_("You are connected to a Citadel "
+ "server running Citadel %d.%02d. \n"
+ "In order to run this version of WebCit "
+ "you must also have Citadel %d.%02d or"
+ " newer.\n\n\n"),
+ WCC->serv_info->serv_rev_level / 100,
+ WCC->serv_info->serv_rev_level % 100,
+ MINIMUM_CIT_VERSION / 100,
+ MINIMUM_CIT_VERSION % 100
+ );
+ hprintf("HTTP/1.1 200 OK\r\n");
+ hprintf("Content-type: text/plain; charset=utf-8\r\n");
+ end_burst();
+ end_webcit_session();
+ return 1;
+ }
+ }
+ if (WCC->ReadBuf == NULL)
+ WCC->ReadBuf = NewStrBuf();
+ if (is_uds)/* unix domain socket */
+ WCC->serv_sock = uds_connectsock(serv_sock_name);
+ else /* tcp socket */
+ WCC->serv_sock = tcp_connectsock(ctdlhost, ctdlport);
+
+ if (WCC->serv_sock < 0) {
+ do_logout();
+ FreeStrBuf(&WCC->ReadBuf);
+ return 1;
+ }
+ else {
+ long Status;
+ StrBuf *Buf;
+
+ Buf = NewStrBuf();
+ WCC->connected = 1;
+ StrBuf_ServGetln(Buf);
+ GetServerStatus(Buf,&Status);
+ /* get the server greeting */
+
+ /* Are there too many users already logged in? */
+ if (Status == 571) {
+ wprintf(_("This server is already serving its maximum number of users and cannot accept any additional logins at this time. Please try again later or contact your system administrator."));
+ end_burst();
+ end_webcit_session();
+ return 1;
+ }
+ /*
+ * From what host is our user connecting? Go with
+ * the host at the other end of the HTTP socket,
+ * unless we are following X-Forwarded-For: headers
+ * and such a header has already turned up something.
+ */
+ if ( (!follow_xff) || (StrLength(WCC->Hdr->browser_host) == 0) ) {
+ if (WCC->Hdr->browser_host == NULL) {
+ WCC->Hdr->browser_host = NewStrBuf();
+ Put(WCC->Hdr->HTTPHeaders, HKEY("FreeMeWithTheOtherHeaders"),
+ WCC->Hdr->browser_host, HFreeStrBuf);
+ }
+ locate_host(WCC->Hdr->browser_host, WCC->Hdr->http_sock);
+ }
+ if (WCC->serv_info == NULL)
+ WCC->serv_info = get_serv_info(WCC->Hdr->browser_host, WCC->Hdr->user_agent);
+ if (WCC->serv_info == NULL){
+ begin_burst();
+ wprintf(_("Received unexpected answer from Citadel "
+ "server; bailing out."));
+ hprintf("HTTP/1.1 200 OK\r\n");
+ hprintf("Content-type: text/plain; charset=utf-8\r\n");
+ end_burst();
+ end_webcit_session();
+ return 1;
+ }
+ if (WCC->serv_info->serv_rev_level < MINIMUM_CIT_VERSION) {
+ begin_burst();
+ wprintf(_("You are connected to a Citadel "
+ "server running Citadel %d.%02d. \n"
+ "In order to run this version of WebCit "
+ "you must also have Citadel %d.%02d or"
+ " newer.\n\n\n"),
+ WCC->serv_info->serv_rev_level / 100,
+ WCC->serv_info->serv_rev_level % 100,
+ MINIMUM_CIT_VERSION / 100,
+ MINIMUM_CIT_VERSION % 100
+ );
+ hprintf("HTTP/1.1 200 OK\r\n");
+ hprintf("Content-type: text/plain; charset=utf-8\r\n");
+ end_burst();
+ end_webcit_session();
+ return 1;
+ }
+ }
+ return 0;
+}
/**
* Read Citadel variformat text and spit it out as HTML.
InitModule_SERVFUNC
(void)
{
+ is_uds = strcasecmp(ctdlhost, "uds") == 0;
+ if (is_uds)
+ snprintf(serv_sock_name, PATH_MAX, "%s/citadel.socket", ctdlport);
RegisterConditional(HKEY("COND:SERV:OPENID"), 2, conditional_serv_supports_openid, CTX_NONE);
RegisterConditional(HKEY("COND:SERV:NEWU"), 2, conditional_serv_newuser_disabled, CTX_NONE);
Error,
eERROR), 1);
*/
- WildFireSerializePayload(Header, WCC->HBuf, &WCC->nWildfireHeaders, NULL);
+ WildFireSerializePayload(Header, WCC->HBuf, &WCC->Hdr->nWildfireHeaders, NULL);
}
else
{
ChrPtr(Error),
ChrPtr(TP->Tokens->FlatToken));
SerializeJson(Header, WildFireException(HKEY(__FILE__), __LINE__, Info, 1), 1);
- WildFireSerializePayload(Header, WCC->HBuf, &WCC->nWildfireHeaders, NULL);
+ WildFireSerializePayload(Header, WCC->HBuf, &WCC->Hdr->nWildfireHeaders, NULL);
}
FreeStrBuf(&Header);
FreeStrBuf(&Info);
0,
Info,
1), 1);
- WildFireSerializePayload(Header, WCC->HBuf, &WCC->nWildfireHeaders, NULL);
+ WildFireSerializePayload(Header, WCC->HBuf, &WCC->Hdr->nWildfireHeaders, NULL);
FreeStrBuf(&Header);
FreeStrBuf(&Info);
fd_set wset;
int fdflags;
- if (!DisableGzip && (WCC->gzip_ok) && CompressBuffer(WCC->WBuf))
+ if (!DisableGzip && (WCC->Hdr->gzip_ok) && CompressBuffer(WCC->WBuf))
{
hprintf("Content-encoding: gzip\r\n");
}
write(2, ptr, StrLength(WCC->WBuf));
write(2, "\033[30m", 5);
#endif
- fdflags = fcntl(WC->http_sock, F_GETFL);
+ fdflags = fcntl(WC->Hdr->http_sock, F_GETFL);
while (ptr < eptr) {
if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
FD_ZERO(&wset);
- FD_SET(WCC->http_sock, &wset);
- if (select(WCC->http_sock + 1, NULL, &wset, NULL, NULL) == -1) {
+ FD_SET(WCC->Hdr->http_sock, &wset);
+ if (select(WCC->Hdr->http_sock + 1, NULL, &wset, NULL, NULL) == -1) {
lprintf(2, "client_write: Socket select failed (%s)\n", strerror(errno));
return -1;
}
}
- if ((res = write(WCC->http_sock,
+ if ((res = write(WCC->Hdr->http_sock,
ptr,
count)) == -1) {
lprintf(2, "client_write: Socket write failed (%s)\n", strerror(errno));
while (ptr < eptr) {
if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
FD_ZERO(&wset);
- FD_SET(WCC->http_sock, &wset);
- if (select(WCC->http_sock + 1, NULL, &wset, NULL, NULL) == -1) {
+ FD_SET(WCC->Hdr->http_sock, &wset);
+ if (select(WCC->Hdr->http_sock + 1, NULL, &wset, NULL, NULL) == -1) {
lprintf(2, "client_write: Socket select failed (%s)\n", strerror(errno));
return -1;
}
}
- if ((res = write(WCC->http_sock,
+ if ((res = write(WCC->Hdr->http_sock,
ptr,
count)) == -1) {
lprintf(2, "client_write: Socket write failed (%s)\n", strerror(errno));
const char *contentType;
wcsession *WCC = WC;
- msgnum = StrTol(WCC->UrlFragment2);
+ msgnum = StrBufExtract_long(WCC->Hdr->ReqLine, 2, '/');
vcard = load_mimepart(msgnum,"1");
v = VCardLoad(vcard);
WebcitHandlerFunc F,
long Flags)
{
- WebcitHandler *NewHandler;
-
- if (HandlerHash == NULL)
- HandlerHash = NewHash(1, NULL);
-
+ WebcitHandler *NewHandler;
NewHandler = (WebcitHandler*) malloc(sizeof(WebcitHandler));
NewHandler->F = F;
NewHandler->Flags = Flags;
/*
* dump out static pages from disk
*/
-void output_static(const char *what)
+void output_static(void)
{
int fd;
struct stat statbuf;
const char *content_type;
int len;
const char *Err;
-
+ char what[] = "TODO";
fd = open(what, O_RDONLY);
if (fd <= 0) {
lprintf(9, "output_static('%s') -- NOT FOUND --\n", what);
wDumpContent(0);
}
+ /* If it's a "force 404" situation then display the error and bail. */
+void do_404(void)
+{
+ hprintf("HTTP/1.1 404 Not found\r\n");
+ hprintf("Content-Type: text/plain\r\n");
+ wprintf("Not found\r\n");
+ end_burst();
+}
+/* TODO: staticdata
+{
+ /* Static content can be sent without connecting to Citadel. * /
+ is_static = 0;
+ for (a=0; a<ndirs && ! is_static; ++a) {
+ if (!strcasecmp(action, (char*)static_content_dirs[a])) { /* map web to disk location * /
+ is_static = 1;
+ n_static = a;
+ }
+ }
+ if (is_static) {
+ if (nBackDots < 2)
+ {
+ snprintf(buf, sizeof buf, "%s/%s/%s/%s/%s/%s/%s/%s",
+ static_dirs[n_static],
+ index[1], index[2], index[3], index[4], index[5], index[6], index[7]);
+ for (a=0; a<8; ++a) {
+ if (buf[strlen(buf)-1] == '/') {
+ buf[strlen(buf)-1] = 0;
+ }
+ }
+ for (a = 0; a < strlen(buf); ++a) {
+ if (isspace(buf[a])) {
+ buf[a] = 0;
+ }
+ }
+ output_static(buf);
+ }
+ else
+ {
+ lprintf(9, "Suspicious request. Ignoring.");
+ hprintf("HTTP/1.1 404 Security check failed\r\n");
+ hprintf("Content-Type: text/plain\r\n\r\n");
+ wprintf("You have sent a malformed or invalid request.\r\n");
+ end_burst();
+ }
+ goto SKIP_ALL_THIS_CRAP; /* Don't try to connect * /
+ }
+ }*/
+
+
/*
* Wraps a Citadel server command in an AJAX transaction.
*/
}
}
-/**
- * \brief Detects a 'mobile' user agent
- */
-int is_mobile_ua(char *user_agent) {
- if (strstr(user_agent,"iPhone OS") != NULL) {
- return 1;
- } else if (strstr(user_agent,"Windows CE") != NULL) {
- return 1;
- } else if (strstr(user_agent,"SymbianOS") != NULL) {
- return 1;
- } else if (strstr(user_agent, "Opera Mobi") != NULL) {
- return 1;
- } else if (strstr(user_agent, "Firefox/2.0.0 Opera 9.51 Beta") != NULL) {
- /* For some reason a new install of Opera 9.51beta decided to spoof. */
- return 1;
- }
- return 0;
+
+
+void ReadPostData(void)
+{
+ const char *content_end = NULL;
+ int body_start = 0;
+ wcsession *WCC = WC;
+ StrBuf *content = NULL;
+
+ content = NewStrBuf();
+
+ StrBufPrintf(content,
+ "Content-type: %s\n"
+ "Content-length: %ld\n\n",
+ ChrPtr(WCC->Hdr->ContentType),
+ WCC->Hdr->ContentLength);
+/*
+ hprintf("Content-type: %s\n"
+ "Content-length: %d\n\n",
+ ContentType, ContentLength);
+*/
+ body_start = StrLength(content);
+
+ /** Read the entire input data at once. */
+ client_read_to(&WCC->Hdr->http_sock,
+ content,
+ WCC->Hdr->ReadBuf, &WCC->Hdr->Pos,
+ WCC->Hdr->ContentLength,
+ SLEEPING);
+
+ if (!strncasecmp(ChrPtr(WCC->Hdr->ContentType), "application/x-www-form-urlencoded", 33)) {
+ StrBufCutLeft(content, body_start);
+ ParseURLParams(content);
+ } else if (!strncasecmp(ChrPtr(WCC->Hdr->ContentType), "multipart", 9)) {
+ content_end = ChrPtr(content) +
+ WCC->Hdr->ContentLength +
+ body_start;
+ mime_parser(ChrPtr(content), content_end, *upload_handler, NULL, NULL, NULL, 0);
+ }
+ FreeStrBuf(&content);
}
/*
* Entry point for WebCit transaction
*/
-void session_loop(StrBuf *ReqLine,
- StrBuf *ReadBuf,
- const char **Pos)
+void session_loop(void)
{
+ int Flags = 0;
+ int xhttp;
StrBuf *Buf;
- const char *pch, *pchs, *pche;
- void *vLine;
- char action[1024];
- char arg[8][128];
- size_t sizes[10];
- char *index[10];
+
char buf[SIZ];
- int a, nBackDots, nEmpty;
- int ContentLength = 0;
- StrBuf *ContentType = NULL;
- StrBuf *UrlLine = NULL;
- StrBuf *content = NULL;
- const char *content_end = NULL;
- StrBuf *browser_host = NULL;
- char user_agent[256];
- int body_start = 0;
- int is_static = 0;
- int n_static = 0;
- int len = 0;
- void *vHandler;
- WebcitHandler *Handler;
- struct timeval tx_start;
- struct timeval tx_finish;
/*
* We stuff these with the values coming from the client cookies,
* so we can use them to reconnect a timed out session if we have to.
*/
- StrBuf *c_username;
- StrBuf *c_password;
- StrBuf *c_roomname;
- char c_httpauth_string[SIZ];
- StrBuf *c_httpauth_user;
- StrBuf *c_httpauth_pass;
wcsession *WCC;
- gettimeofday(&tx_start, NULL); /* start a stopwatch for performance timing */
Buf = NewStrBuf();
- c_username = NewStrBuf();
- c_password = NewStrBuf();
- c_roomname = NewStrBuf();
- safestrncpy(c_httpauth_string, "", sizeof c_httpauth_string);
- c_httpauth_user = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_USER));
- c_httpauth_pass = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_PASS));
WCC= WC;
WCC->upload = NULL;
WCC->is_mobile = 0;
WCC->trailing_javascript = NewStrBuf();
- WCC->nWildfireHeaders = 0;
-
- /** Figure out the action */
+ WCC->Hdr->nWildfireHeaders = 0;
+ if (WCC->Hdr->Handler != NULL)
+ Flags = WCC->Hdr->Handler->Flags; /* so we can temporarily add our own... */
+ /** Figure out the action * /
index[0] = action;
sizes[0] = sizeof action;
for (a=1; a<9; a++)
}
nBackDots = 0;
nEmpty = 0;
- for ( a = 0; a < 9; ++a)
- {
- extract_token(index[a], ChrPtr(ReqLine), a + 1, '/', sizes[a]);
- if (strstr(index[a], "?")) *strstr(index[a], "?") = 0;
- if (strstr(index[a], "&")) *strstr(index[a], "&") = 0;
- if (strstr(index[a], " ")) *strstr(index[a], " ") = 0;
- if ((index[a][0] == '.') && (index[a][1] == '.'))
- nBackDots++;
- if (index[a][0] == '\0')
- nEmpty++;
- }
-
-
- if (GetHash(WCC->headers, HKEY("COOKIE"), &vLine) &&
- (vLine != NULL)){
- cookie_to_stuff((StrBuf *)vLine, NULL,
- c_username,
- c_password,
- c_roomname);
- }
- if (GetHash(WCC->headers, HKEY("AUTHORIZATION"), &vLine) &&
- (vLine!=NULL)) {
- StrBufDecodeBase64((StrBuf*)vLine);
- StrBufExtract_token(c_httpauth_user, (StrBuf*)vLine, 0, ':');
- StrBufExtract_token(c_httpauth_pass, (StrBuf*)vLine, 1, ':');
- }
- if (GetHash(WCC->headers, HKEY("CONTENT-LENGTH"), &vLine) &&
- (vLine!=NULL)) {
- ContentLength = StrToi((StrBuf*)vLine);
- }
- if (GetHash(WCC->headers, HKEY("CONTENT-TYPE"), &vLine) &&
- (vLine!=NULL)) {
- ContentType = (StrBuf*)vLine;
- }
- if (GetHash(WCC->headers, HKEY("USER-AGENT"), &vLine) &&
- (vLine!=NULL)) {
- safestrncpy(user_agent, ChrPtr((StrBuf*)vLine), sizeof user_agent);
-#ifdef TECH_PREVIEW
- if ((WCC->is_mobile < 0) && is_mobile_ua(&buf[12])) {
- WCC->is_mobile = 1;
- }
- else {
- WCC->is_mobile = 0;
- }
-#endif
- }
- if ((follow_xff) &&
- GetHash(WCC->headers, HKEY("X-FORWARDED-HOST"), &vLine) &&
- (vLine != NULL)) {
- WCC->http_host = (StrBuf*)vLine;
- }
- if ((StrLength(WCC->http_host) == 0) &&
- GetHash(WCC->headers, HKEY("HOST"), &vLine) &&
- (vLine!=NULL)) {
- WCC->http_host = (StrBuf*)vLine;
- }
-
- if (GetHash(WCC->headers, HKEY("X-FORWARDED-FOR"), &vLine) &&
- (vLine!=NULL)) {
- browser_host = (StrBuf*) vLine;
-
- while (StrBufNum_tokens(browser_host, ',') > 1) {
- StrBufRemove_token(browser_host, 0, ',');
- }
- StrBufTrim(browser_host);
- }
-
- if (ContentLength > 0) {
- content = NewStrBuf();
- StrBufPrintf(content, "Content-type: %s\n"
- "Content-length: %d\n\n",
- ChrPtr(ContentType), ContentLength);
/*
- hprintf("Content-type: %s\n"
- "Content-length: %d\n\n",
- ContentType, ContentLength);
+ for ( a = 0; a < 9; ++a)
+ {
+ extract_token(index[a], ChrPtr(ReqLine), a + 1, '/', sizes[a]);
+ if (strstr(index[a], "?")) *strstr(index[a], "?") = 0;
+ if (strstr(index[a], "&")) *strstr(index[a], "&") = 0;
+ if (strstr(index[a], " ")) *strstr(index[a], " ") = 0;
+ if ((index[a][0] == '.') && (index[a][1] == '.'))
+ nBackDots++;
+ if (index[a][0] == '\0')
+ nEmpty++;
+ }
*/
- body_start = StrLength(content);
-
- /** Read the entire input data at once. */
- client_read_to(&WCC->http_sock,
- content,
- ReadBuf, Pos,
- ContentLength,
- SLEEPING);
-
- if (!strncasecmp(ChrPtr(ContentType), "application/x-www-form-urlencoded", 33)) {
- StrBufCutLeft(content, body_start);
- ParseURLParams(content);
- } else if (!strncasecmp(ChrPtr(ContentType), "multipart", 9)) {
- content_end = ChrPtr(content) + ContentLength + body_start;
- mime_parser(ChrPtr(content), content_end, *upload_handler, NULL, NULL, NULL, 0);
- }
- } else {
- content = NULL;
+ if (WCC->Hdr->ContentLength > 0) {
+ ReadPostData();
}
- /* make a note of where we are in case the user wants to save it */
- WCC->this_page = NewStrBufDup(ReqLine);
- StrBufRemove_token(WCC->this_page, 2, ' ');
- StrBufRemove_token(WCC->this_page, 0, ' ');
-
/* If there are variables in the URL, we must grab them now */
- UrlLine = NewStrBufDup(ReqLine);
- len = StrLength(UrlLine);
- pch = pchs = ChrPtr(UrlLine);
- pche = pchs + len;
- while (pch < pche) {
- if ((*pch == '?') || (*pch == '&')) {
- StrBufCutLeft(UrlLine, pch - pchs + 1);
- ParseURLParams(UrlLine);
- break;
- }
- pch ++;
- }
- FreeStrBuf(&UrlLine);
-
- /* If it's a "force 404" situation then display the error and bail. */
- if (!strcmp(action, "404")) {
- hprintf("HTTP/1.1 404 Not found\r\n");
- hprintf("Content-Type: text/plain\r\n");
- wprintf("Not found\r\n");
- end_burst();
- goto SKIP_ALL_THIS_CRAP;
- }
-
- /* Static content can be sent without connecting to Citadel. */
- is_static = 0;
- for (a=0; a<ndirs && ! is_static; ++a) {
- if (!strcasecmp(action, (char*)static_content_dirs[a])) { /* map web to disk location */
- is_static = 1;
- n_static = a;
- }
- }
- if (is_static) {
- if (nBackDots < 2)
- {
- snprintf(buf, sizeof buf, "%s/%s/%s/%s/%s/%s/%s/%s",
- static_dirs[n_static],
- index[1], index[2], index[3], index[4], index[5], index[6], index[7]);
- for (a=0; a<8; ++a) {
- if (buf[strlen(buf)-1] == '/') {
- buf[strlen(buf)-1] = 0;
- }
- }
- for (a = 0; a < strlen(buf); ++a) {
- if (isspace(buf[a])) {
- buf[a] = 0;
- }
- }
- output_static(buf);
- }
- else
- {
- lprintf(9, "Suspicious request. Ignoring.");
- hprintf("HTTP/1.1 404 Security check failed\r\n");
- hprintf("Content-Type: text/plain\r\n\r\n");
- wprintf("You have sent a malformed or invalid request.\r\n");
- end_burst();
- }
- goto SKIP_ALL_THIS_CRAP; /* Don't try to connect */
- }
+ if (WCC->Hdr->PlainArgs != NULL)
+ ParseURLParams(WCC->Hdr->PlainArgs);
/* If the client sent a nonce that is incorrect, kill the request. */
if (havebstr("nonce")) {
* connection now.
*/
if (!WCC->connected) {
- if (WCC->ReadBuf == NULL)
- WCC->ReadBuf = NewStrBuf();
- if (!strcasecmp(ctdlhost, "uds")) {
- /* unix domain socket */
- snprintf(buf, SIZ, "%s/citadel.socket", ctdlport);
- WCC->serv_sock = uds_connectsock(buf);
- }
- else {
- /* tcp socket */
- WCC->serv_sock = tcp_connectsock(ctdlhost, ctdlport);
- }
-
- if (WCC->serv_sock < 0) {
- do_logout();
- FreeStrBuf(&WCC->ReadBuf);
+ if (GetConnected ())
goto SKIP_ALL_THIS_CRAP;
- }
- else {
- WCC->connected = 1;
- serv_getln(buf, sizeof buf); /* get the server greeting */
-
- /* Are there too many users already logged in? */
- if (!strncmp(buf, "571", 3)) {
- wprintf(_("This server is already serving its maximum number of users and cannot accept any additional logins at this time. Please try again later or contact your system administrator."));
- end_burst();
- end_webcit_session();
- goto SKIP_ALL_THIS_CRAP;
- }
-
- /*
- * From what host is our user connecting? Go with
- * the host at the other end of the HTTP socket,
- * unless we are following X-Forwarded-For: headers
- * and such a header has already turned up something.
- */
- if ( (!follow_xff) || (StrLength(browser_host) == 0) ) {
- if (browser_host == NULL) {
- browser_host = NewStrBuf();
- Put(WCC->headers, HKEY("FreeMeWithTheOtherHeaders"),
- browser_host, HFreeStrBuf);
- }
- locate_host(browser_host, WCC->http_sock);
- }
- if (WCC->serv_info == NULL)
- WCC->serv_info = get_serv_info(browser_host, user_agent);
- if (WCC->serv_info == NULL){
- begin_burst();
- wprintf(_("Received unexpected answer from Citadel "
- "server; bailing out."));
- hprintf("HTTP/1.1 200 OK\r\n");
- hprintf("Content-type: text/plain; charset=utf-8\r\n");
- end_burst();
- end_webcit_session();
- goto SKIP_ALL_THIS_CRAP;
- }
- if (WCC->serv_info->serv_rev_level < MINIMUM_CIT_VERSION) {
- begin_burst();
- wprintf(_("You are connected to a Citadel "
- "server running Citadel %d.%02d. \n"
- "In order to run this version of WebCit "
- "you must also have Citadel %d.%02d or"
- " newer.\n\n\n"),
- WCC->serv_info->serv_rev_level / 100,
- WCC->serv_info->serv_rev_level % 100,
- MINIMUM_CIT_VERSION / 100,
- MINIMUM_CIT_VERSION % 100
- );
- hprintf("HTTP/1.1 200 OK\r\n");
- hprintf("Content-type: text/plain; charset=utf-8\r\n");
- end_burst();
- end_webcit_session();
- goto SKIP_ALL_THIS_CRAP;
- }
- }
}
- /*
- * Functions which can be performed without logging in
- */
- if (!strcasecmp(action, "listsub")) {
- do_listsub();
- goto SKIP_ALL_THIS_CRAP;
- }
- if (!strcasecmp(action, "freebusy")) {
- do_freebusy(ChrPtr(ReqLine));
- goto SKIP_ALL_THIS_CRAP;
- }
/*
* If we're not logged in, but we have HTTP Authentication data,
* try logging in to Citadel using that.
*/
if ((!WCC->logged_in)
- && (StrLength(c_httpauth_user) > 0)
- && (StrLength(c_httpauth_pass) > 0))
+ && (StrLength(WCC->Hdr->c_username) > 0)
+ && (StrLength(WCC->Hdr->c_password) > 0))
{
FlushStrBuf(Buf);
- serv_printf("USER %s", ChrPtr(c_httpauth_user));
+ serv_printf("USER %s", ChrPtr(WCC->Hdr->c_username));
StrBuf_ServGetln(Buf);
if (GetServerStatus(Buf, NULL) == 3) {
- serv_printf("PASS %s", ChrPtr(c_httpauth_pass));
+ serv_printf("PASS %s", ChrPtr(WCC->Hdr->c_password));
StrBuf_ServGetln(Buf);
if (GetServerStatus(Buf, NULL) == 2) {
- become_logged_in(c_httpauth_user,
- c_httpauth_pass, Buf);
- if (WCC->httpauth_user == NULL)
- WCC->httpauth_user = NewStrBufDup(c_httpauth_user);
- else {
- FlushStrBuf(WCC->httpauth_user);
- StrBufAppendBuf(WCC->httpauth_user, c_httpauth_user, 0);
- }
- if (WCC->httpauth_pass == NULL)
- WCC->httpauth_pass = NewStrBufDup(c_httpauth_pass);
- else {
- FlushStrBuf(WCC->httpauth_pass);
- StrBufAppendBuf(WCC->httpauth_pass, c_httpauth_pass, 0);
- }
+ become_logged_in(WCC->Hdr->c_username,
+ WCC->Hdr->c_password, Buf);
} else {
/* Should only display when password is wrong */
authorization_required(&buf[4]);
}
}
- /* This needs to run early */
-#ifdef TECH_PREVIEW
- if (!strcasecmp(action, "rss")) {
- display_rss(sbstr("room"));
- goto SKIP_ALL_THIS_CRAP;
- }
-#endif
-
- /*
- * The GroupDAV stuff relies on HTTP authentication instead of
- * our session's authentication.
- */
- if (!strncasecmp(action, "groupdav", 8)) {
- groupdav_main(WCC->headers,
- ReqLine,
- ContentType, /* do GroupDAV methods */
- ContentLength, content, body_start);
- if (!WCC->logged_in) {
- WCC->killthis = 1; /* If not logged in, don't */
- } /* keep the session active */
- goto SKIP_ALL_THIS_CRAP;
- }
-
-
- /*
- * Automatically send requests with any method other than GET or
- * POST to the GroupDAV code as well.
- */
- if ((WCC->eReqType != eGET) &&
- (WCC->eReqType != ePOST) &&
- (WCC->eReqType != eHEAD)) {
- groupdav_main(WCC->headers, ReqLine,
- ContentType, /** do GroupDAV methods */
- ContentLength, content, body_start);
- if (!WCC->logged_in) {
- WCC->killthis = 1; /** If not logged in, don't */
- } /** keep the session active */
- goto SKIP_ALL_THIS_CRAP;
- }
+ xhttp = (WCC->Hdr->eReqType != eGET) &&
+ (WCC->Hdr->eReqType != ePOST) &&
+ (WCC->Hdr->eReqType != eHEAD);
/*
* If we're not logged in, but we have username and password cookies
* supplied by the browser, try using them to log in.
*/
if ((!WCC->logged_in)
- && (StrLength(c_username)>0)
- && (StrLength(c_password)>0)) {
- serv_printf("USER %s", ChrPtr(c_username));
- StrBuf_ServGetln(Buf);
- if (GetServerStatus(Buf, NULL) == 3) {
- serv_printf("PASS %s", ChrPtr(c_password));
- StrBuf_ServGetln(Buf);
- if (GetServerStatus(Buf, NULL) == 2) {
- become_logged_in(c_username, c_password, Buf);
- get_preference("default_header_charset", &WCC->DefaultCharset);
- }
- }
+ && (StrLength(WCC->Hdr->c_username)>0)
+ && (StrLength(WCC->Hdr->c_password)>0)) {
+ ReEstablish_Session();
}
/*
* prior to doing anything else.
*/
if (havebstr("gotofirst")) {
- gotoroom(sbstr("gotofirst")); /* do this quietly to avoid session output! */
+ int ret;
+ ret = gotoroom(sbstr("gotofirst")); /* do this quietly to avoid session output! */
+ if (ret != 0)
+ lprintf(1, "GOTOFIRST: Unable to change to [%s]; Reason: %d\n", bstr("gotofirst"), ret);
}
- /*
- * If we don't have a current room, but a cookie specifying the
- * current room is supplied, make an effort to go there.
- */
- if ((StrLength(WCC->wc_roomname) == 0) && (StrLength(c_roomname) > 0)) {
- serv_printf("GOTO %s", ChrPtr(c_roomname));
- StrBuf_ServGetln(Buf);
- if (GetServerStatus(Buf, NULL) == 2) {
- if (WCC->wc_roomname == NULL) {
- WCC->wc_roomname = NewStrBufDup(c_roomname);
- }
- else {
- FlushStrBuf(WCC->wc_roomname);
- StrBufAppendBuf(WCC->wc_roomname, c_roomname, 0);
- }
- }
- }
-
- GetHash(HandlerHash, action, strlen(action) /* TODO*/, &vHandler),
- Handler = (WebcitHandler*) vHandler;
- if (Handler != NULL) {
- if (!WCC->logged_in && ((Handler->Flags & ANONYMOUS) == 0)) {
+ if (WCC->Hdr->Handler != NULL) {
+ if (!WCC->logged_in && ((WCC->Hdr->Handler->Flags & ANONYMOUS) == 0)) {
display_login(NULL);
}
else {
- if((Handler->Flags & NEED_URL)) {
+/*
+ if((WCC->Hdr->Handler->Flags & NEED_URL)) {
if (WCC->UrlFragment1 == NULL)
WCC->UrlFragment1 = NewStrBuf();
if (WCC->UrlFragment2 == NULL)
StrBufPlain(WCC->UrlFragment3, index[2], -1);
StrBufPlain(WCC->UrlFragment4, index[3], -1);
}
- if ((Handler->Flags & AJAX) != 0)
+*/
+ if ((WCC->Hdr->Handler->Flags & AJAX) != 0)
begin_ajax_response();
- Handler->F();
- if ((Handler->Flags & AJAX) != 0)
+ WCC->Hdr->Handler->F();
+ if ((WCC->Hdr->Handler->Flags & AJAX) != 0)
end_ajax_response();
}
}
WCC->SavePrefsToServer = 0;
}
FreeStrBuf(&Buf);
- FreeStrBuf(&c_username);
- FreeStrBuf(&c_password);
- FreeStrBuf(&c_roomname);
- FreeStrBuf(&c_httpauth_user);
- FreeStrBuf(&c_httpauth_pass);
- FreeStrBuf(&WCC->this_page);
fflush(stdout);
- if (content != NULL) {
- FreeStrBuf(&content);
- content = NULL;
- }
- WCC->http_host = NULL;
-
- /* How long did this transaction take? */
- gettimeofday(&tx_finish, NULL);
-
- lprintf(9, "Transaction completed in %ld.%06ld seconds.\n",
- ((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
- );
+ WCC->Hdr->http_host = NULL;
}
extern char static_local_dir[PATH_MAX];
+
+ /* TODO: integrate this into the static startup logic
+
+ * While we're at it, gracefully handle requests for the
+ * robots.txt and favicon.ico files.
+ * /
+ if ((StrLength(ReqLine) >= 11) &&
+ !strncasecmp(ChrPtr(ReqLine), "/robots.txt", 11)) {
+ StrBufPlain(ReqLine,
+ HKEY("/static/robots.txt"
+ "?force_close_session=yes HTTP/1.1"));
+ Hdr.eReqType = eGET;
+ }
+ else if ((StrLength(ReqLine) >= 11) &&
+ !strncasecmp(ChrPtr(ReqLine), "/favicon.ico", 12)) {
+ StrBufPlain(ReqLine, HKEY("/static/favicon.ico"));
+ Hdr.eReqType = eGET;
+ }
+
+*/
void
InitModule_WEBCIT
(void)
{
char dir[SIZ];
+ WebcitAddUrlHandler(HKEY("404"), do_404, ANONYMOUS|COOKIEUNNEEDED);
+ WebcitAddUrlHandler(HKEY("blank"), blank_page, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC);
+
+ WebcitAddUrlHandler(HKEY("robots.txt"), output_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC);
+ WebcitAddUrlHandler(HKEY("favicon.ico"), output_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC);
+ WebcitAddUrlHandler(HKEY("static"), output_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC);
+ WebcitAddUrlHandler(HKEY("static.local"), output_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC);
+ WebcitAddUrlHandler(HKEY("tinymce"), output_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC);
+
WebcitAddUrlHandler(HKEY("blank"), blank_page, ANONYMOUS);
WebcitAddUrlHandler(HKEY("do_template"), url_do_template, ANONYMOUS);
- WebcitAddUrlHandler(HKEY("sslg"), seconds_since_last_gexp, AJAX);
+ WebcitAddUrlHandler(HKEY("sslg"), seconds_since_last_gexp, AJAX|LOGCHATTY);
WebcitAddUrlHandler(HKEY("ajax_servcmd"), ajax_servcmd, 0);
RegisterConditional(HKEY("COND:IMPMSG"), 0, ConditionalImportantMesage, CTX_NONE);
SessionDetachModule_WEBCIT
(wcsession *sess)
{
- DeleteHash(&sess->urlstrings);
+ DeleteHash(&sess->Hdr->urlstrings);// TODO?
if (sess->upload_length > 0) {
free(sess->upload);
sess->upload_length = 0;
{
FreeStrBuf(&sess->WBuf);
FreeStrBuf(&sess->HBuf);
+ /*
FreeStrBuf(&sess->UrlFragment1);
FreeStrBuf(&sess->UrlFragment2);
FreeStrBuf(&sess->UrlFragment3);
FreeStrBuf(&sess->UrlFragment4);
+ */
FreeStrBuf(&sess->ImportantMsg);
}
} addrbookent;
+
+
+#define AJAX (1<<0)
+#define ANONYMOUS (1<<1)
+#define NEED_URL (1<<2)
+#define XHTTP_COMMANDS (1<<3)
+#define BOGUS (1<<4)
+#define URLNAMESPACE (1<<4)
+#define LOGCHATTY (1<<5)
+#define COOKIEUNNEEDED (1<<6)
+#define ISSTATIC (1<<7)
+#define FORCE_SESSIONCLOSE (1<<8)
+
+
+typedef void (*WebcitHandlerFunc)(void);
+typedef struct _WebcitHandler{
+ WebcitHandlerFunc F;
+ long Flags;
+} WebcitHandler;
+void WebcitAddUrlHandler(const char * UrlString, long UrlSLen, WebcitHandlerFunc F, long Flags);
+
+
+
+
+
+
+
typedef struct _headereval {
ExamineMsgHeaderFunc evaluator;
int Type;
eNONE
};
const char *ReqStrs[eNONE];
+
+
+
+typedef struct _ParsedHttpHdrs {
+ int http_sock; /**< HTTP server socket */
+ const char *Pos;
+ StrBuf *ReadBuf;
+
+ long eReqType; /**< eGET, ePOST.... */
+ const WebcitHandler *Handler;
+
+ int DontNeedAuth;
+ int got_cookie;
+ long ContentLength;
+ time_t if_modified_since;
+ int gzip_ok; /**< Nonzero if Accept-encoding: gzip */
+
+ StrBuf *c_username;
+ StrBuf *c_password;
+ StrBuf *c_roomname;
+ StrBuf *RawCookie;
+ int desired_session;
+
+ StrBuf *ContentType;
+
+ StrBuf *RawLine;/* TODO: freeme */
+ StrBuf *ReqLine;
+ StrBuf *http_host; /**< HTTP Host: header */
+ StrBuf *browser_host;
+ StrBuf *user_agent;
+
+ StrBuf *UrlFragment1; /**< first urlfragment, if NEED_URL is specified by the handler*/
+ StrBuf *UrlFragment2; /**< second urlfragment, if NEED_URL is specified by the handler*/
+ StrBuf *UrlFragment3; /**< third urlfragment, if NEED_URL is specified by the handler*/
+ StrBuf *UrlFragment4; /**< fourth urlfragment, if NEED_URL is specified by the handler*/
+ StrBuf *this_page; /**< URL of current page */
+ StrBuf *PlainArgs; /*TODO: freeme*/
+ HashList *urlstrings; /**< variables passed to webcit in a URL */
+ HashList *HTTPHeaders; /**< the headers the client sent us */
+ int nWildfireHeaders; /**< how many wildfire headers did we already send? */
+} ParsedHttpHdrs;
+
+
/*
* One of these is kept for each active Citadel session.
* HTTP transactions are bound to one at a time.
int nonce; /**< session nonce (to prevent session riding) */
/* Session local Members */
- int http_sock; /**< HTTP server socket */
int serv_sock; /**< Client socket to Citadel server */
StrBuf *ReadBuf; /**< here we keep our stuff while reading linebuffered from the server. */
StrBuf *MigrateReadLineBuf; /**< here we buffer legacy server read stuff */
time_t lastreq; /**< Timestamp of most recent HTTP */
time_t last_pager_check; /**< last time we polled for instant msgs */
ServInfo *serv_info; /**< Iformation about the citserver we're connected to */
+ int is_ajax; /** < are we doing an ajax request? */
/* Request local Members */
- long eReqType; /**< eGET, ePOST.... */
StrBuf *CLineBuf; /**< linebuffering client stuff */
- StrBuf *UrlFragment1; /**< first urlfragment, if NEED_URL is specified by the handler*/
- StrBuf *UrlFragment2; /**< second urlfragment, if NEED_URL is specified by the handler*/
- StrBuf *UrlFragment3; /**< third urlfragment, if NEED_URL is specified by the handler*/
- StrBuf *UrlFragment4; /**< fourth urlfragment, if NEED_URL is specified by the handler*/
+ ParsedHttpHdrs *Hdr;
StrBuf *WBuf; /**< Our output buffer */
StrBuf *HBuf; /**< Our HeaderBuffer */
- StrBuf *this_page; /**< URL of current page */
- HashList *urlstrings; /**< variables passed to webcit in a URL */
- HashList *vars; /**< HTTP variable substitutions for this page */
- HashList *headers; /**< the headers the client sent us */
- StrBuf *http_host; /**< HTTP Host: header */
- int is_ajax; /** < are we doing an ajax request? */
- int gzip_ok; /**< Nonzero if Accept-encoding: gzip */
- int nWildfireHeaders; /**< how many wildfire headers did we already send? */
+ HashList *vars; /**< HTTP variable substitutions for this page */
StrBuf *trailing_javascript; /**< extra javascript to be appended to page */
char ImportantMessage[SIZ]; /**< ??? todo */
StrBuf *ImportantMsg;
};
+
+typedef void (*Header_Evaluator)(StrBuf *Line, ParsedHttpHdrs *hdr);
+
+typedef struct _HttpHeader {
+ Header_Evaluator H;
+ StrBuf *Val;
+ int HaveEvaluator;
+} OneHttpHeader;
+
+
+
/* values for WC->current_iconbar */
enum {
current_iconbar_menu, /* view the icon menue */
extern int is_https;
extern int setup_wizard;
extern char wizard_filename[];
-extern time_t if_modified_since;
extern int follow_xff;
void InitialiseSemaphores(void);
void display_aide_menu(void);
void display_advanced_menu(void);
void slrp_highest(void);
-ServInfo *get_serv_info(StrBuf *, char *);
+ServInfo *get_serv_info(StrBuf *, StrBuf *);
+int GetConnected(void);
void DeleteServInfo(ServInfo **FreeMe);
int uds_connectsock(char *);
int tcp_connectsock(char *, char *);
void output_custom_content_header(const char *ctype);
void wprintf(const char *format,...)__attribute__((__format__(__printf__,1,2)));
void hprintf(const char *format,...)__attribute__((__format__(__printf__,1,2)));
-void output_static(const char *what);
+void output_static(void);
void print_menu_box(char* Title, char *Class, int nLines, ...);
long stresc(char *target, long tSize, char *strbuf, int nbsp, int nolinebreaks);
void confirm_delete_msg(void);
void display_success(char *);
void authorization_required(const char *message);
+int ReEstablish_Session(void);
+
void server_to_text(void);
void save_edit(char *description, char *enter_cmd, int regoto);
void display_edit(char *description, char *check_cmd,
void do_housekeeping(void);
void smart_goto(const StrBuf *);
void worker_entry(void);
-void session_loop(StrBuf *ReqLine,
- StrBuf *ReadBuf,
- const char **Pos);
+void session_loop(void);
size_t wc_strftime(char *s, size_t max, const char *format, const struct tm *tm);
void fmt_time(char *buf, size_t siz, time_t thetime);
void httpdate(char *buf, time_t thetime);
void partstat_as_string(char *buf, icalproperty *attendee);
icalcomponent *ical_encapsulate_subcomponent(icalcomponent *subcomp);
void check_attendee_availability(icalcomponent *supplied_vevent);
-void do_freebusy(const char *req);
int ical_ctdl_is_overlap(
struct icaltimetype t1start,
struct icaltimetype t1end,
typedef void (*IcalCallbackFunc)(icalcomponent *, long, char*, int, struct calview *);
-typedef void (*WebcitHandlerFunc)(void);
-typedef struct _WebcitHandler{
- WebcitHandlerFunc F;
- long Flags;
-} WebcitHandler;
-void WebcitAddUrlHandler(const char * UrlString, long UrlSLen, WebcitHandlerFunc F, long Flags);
-
-#define AJAX (1<<0)
-#define ANONYMOUS (1<<1)
-#define NEED_URL (1<<2)
-#define XHTTP_COMMANDS (1<<3)
-
-
/* These should be empty, but we have them for testing */
#define DEFAULT_HTTPAUTH_USER ""
#define DEFAULT_HTTPAUTH_PASS ""
lprintf(9, "Text domain Charset: %s\n", bind_textdomain_codeset("webcit","UTF8"));
#endif
-
-
-
-
-
-
-
-
-
initialise_modules();
initialize_viewdefs();
initialize_axdefs();
InitModule_WHO
(void)
{
+
+
WebcitAddUrlHandler(HKEY("terminate_session"), _terminate_session, 0);
WebcitAddUrlHandler(HKEY("edit_me"), edit_me, 0);