Beispiel #1
0
eNextState POP3C_GetOneMessageIDState(pop3aggr *RecvMsg)
{
	AsyncIO *IO = &RecvMsg->IO;
#if 0
	int rc;
	rc = TestValidateHash(RecvMsg->MsgNumbers);
	if (rc != 0)
		EVP3CCS_syslog(LOG_DEBUG, "Hash Invalid: %d\n", rc);
#endif

	POP3C_DBG_READ();
	if (!POP3C_OK) return eTerminateConnection;
	RecvMsg->CurrMsg->MsgUIDL =
		NewStrBufPlain(NULL, StrLength(RecvMsg->IO.IOBuf));
	RecvMsg->CurrMsg->MsgUID =
		NewStrBufPlain(NULL, StrLength(RecvMsg->IO.IOBuf) * 2);

	StrBufExtract_token(RecvMsg->CurrMsg->MsgUIDL,
			    RecvMsg->IO.IOBuf, 2, ' ');

	StrBufPrintf(RecvMsg->CurrMsg->MsgUID,
		     "pop3/%s/%s:%s@%s",
		     ChrPtr(RecvMsg->RoomName),
		     ChrPtr(RecvMsg->CurrMsg->MsgUIDL),
		     RecvMsg->IO.ConnectMe->User,
		     RecvMsg->IO.ConnectMe->Host);
	RecvMsg->State --;
	return eSendReply;
}
Beispiel #2
0
NodeConf *NewNode(StrBuf *SerializedNode)
{
	NodeConf *Node;

	if (StrLength(SerializedNode) < 8) 
		return NULL; /** we need at least 4 pipes and some other text so its invalid. */
	Node = (NodeConf *) malloc(sizeof(NodeConf));
	Node->DeleteMe = 0;
	Node->NodeName=NewStrBuf();
	StrBufExtract_token(Node->NodeName, SerializedNode, 0, '|');
	Node->Secret=NewStrBuf();
	StrBufExtract_token(Node->Secret, SerializedNode, 1, '|');
	Node->Host=NewStrBuf();
	StrBufExtract_token(Node->Host, SerializedNode, 2, '|');
	Node->Port=NewStrBuf();
	StrBufExtract_token(Node->Port, SerializedNode, 3, '|');
	return Node;
}
Beispiel #3
0
// display the picture (icon, photo, whatever) associated with the current room
void display_roompic(void) {
	off_t bytes;
	StrBuf *Buf = NewStrBuf();
	serv_printf("DLRI");
	StrBuf_ServGetln(Buf);
	if (GetServerStatus(Buf, NULL) == 6) {
		StrBufCutLeft(Buf, 4);
		bytes = StrBufExtract_long(Buf, 0, '|');
		StrBuf *content_type = NewStrBuf();
		StrBufExtract_token(content_type, Buf, 3, '|');
		WC->WBuf = NewStrBuf();
		StrBuf_ServGetBLOBBuffered(WC->WBuf, bytes);
		http_transmit_thing(ChrPtr(content_type), 0);
		FreeStrBuf(&content_type);
	}
	else {
		output_error_pic("", "");
	}
	FreeStrBuf(&Buf);
}
Beispiel #4
0
/*
 * Display a list of all pages in a Wiki room (template callback)
 */
void tmplput_display_wiki_pagelist(StrBuf *Target, WCTemplputParams *TP)
{
	StrBuf *Buf;
	int row = 0;

	if (!IsEmptyStr(bstr("query"))) {
		serv_printf("MSGS SEARCH|%s||4", bstr("query"));	/* search-reduced list */
	}
	else {
		serv_printf("MSGS ALL|||4");				/* full list */
	}

	Buf = NewStrBuf();
	StrBuf_ServGetln(Buf);
	if (GetServerStatus(Buf, NULL) == 1) {
		StrBuf *pagetitle = NewStrBuf();

		wc_printf("<table class=\"wiki_pagelist_background\">");
		wc_printf("<th>%s</th>", _("Page title"));

		while((StrBuf_ServGetln(Buf) >= 0) && strcmp(ChrPtr(Buf), "000")) {
			StrBufExtract_token(pagetitle, Buf, 1, '|');

			if (!bmstrcasestr((char *)ChrPtr(pagetitle), "_HISTORY_")) {	/* no history pages */
				wc_printf("<tr bgcolor=\"%s\">", ((row%2) ? "#FFFFFF" : "#DDDDDD"));
				wc_printf("<td><a href=\"wiki?page=");
				urlescputs(ChrPtr(pagetitle));
				wc_printf("\">");
				escputs(ChrPtr(pagetitle));
				wc_printf("</a></td>");
				wc_printf("</tr>\n");
				++row;
			}
		}
		wc_printf("</table>\n");
		FreeStrBuf(&pagetitle);
	}

	FreeStrBuf(&Buf);
}
Beispiel #5
0
/*
 * Display the revision history for a wiki page (template callback)
 */
void tmplput_display_wiki_history(StrBuf *Target, WCTemplputParams *TP)
{
	char pagename[128];
	StrBuf *Buf;
	int row = 0;

	safestrncpy(pagename, bstr("page"), sizeof pagename);
	str_wiki_index(pagename);

	serv_printf("WIKI history|%s", pagename);
	Buf = NewStrBuf();
	StrBuf_ServGetln(Buf);
	if (GetServerStatus(Buf, NULL) == 1) {

		time_t rev_date;
		char rev_date_displayed[64];
		StrBuf *rev_uuid = NewStrBuf();
		StrBuf *author = NewStrBuf();
		StrBuf *node = NewStrBuf();

		wc_printf("<table class=\"wiki_history_background\">");

		wc_printf("<th>%s</th>", _("Date"));
		wc_printf("<th>%s</th>", _("Author"));

		while((StrBuf_ServGetln(Buf) >= 0) &&  strcmp(ChrPtr(Buf), "000")) {

			rev_date = extract_long(ChrPtr(Buf), 1);
			webcit_fmt_date(rev_date_displayed, sizeof rev_date_displayed, rev_date, DATEFMT_FULL);
			StrBufExtract_token(author, Buf, 2, '|');

			wc_printf("<tr bgcolor=\"%s\">", ((row%2) ? "#FFFFFF" : "#DDDDDD"));
			wc_printf("<td>%s</td><td>", rev_date_displayed);
			if (!strcasecmp(ChrPtr(node), (char *)WC->serv_info->serv_nodename)) {
				escputs(ChrPtr(author));
				wc_printf(" @ ");
				escputs(ChrPtr(node));
			}
			else {
				wc_printf("<a href=\"showuser?who=");
				urlescputs(ChrPtr(author));
				wc_printf("\">");
				escputs(ChrPtr(author));
				wc_printf("</a>");
			}
			wc_printf("</td>");

			if (row == 0) {
				wc_printf("<td><a href=\"wiki?page=%s", bstr("page"));
				wc_printf("?go="); urlescputs(ChrPtr(WC->CurRoom.name));
				wc_printf("\">%s</a></td>", _("(show)"));
				wc_printf("<td>(%s)</td>", _("Current version"));
			}

			else {
				wc_printf("<td><a href=\"wiki?page=%s?rev=%s",
					bstr("page"),
					ChrPtr(rev_uuid)
				);
				wc_printf("?go="); urlescputs(ChrPtr(WC->CurRoom.name));
				wc_printf("\">%s</a></td>", _("(show)"));
				wc_printf("<td><a href=\"javascript:GetLoggedInFirst(encodeURIComponent('wiki?page=%s?rev=%s?revert=1'))\">%s</a></td>",
					bstr("page"),
					ChrPtr(rev_uuid),
					_("(revert)")
				);
			}
			wc_printf("</tr>\n");

			/* Extract all fields except the author and date after displaying the row.  This
			 * is deliberate, because the timestamp reflects when the diff was written, not
			 * when the version which it reflects was written.  Similarly, the name associated
			 * with each diff is the author who created the newer version of the page that
			 * made the diff happen.
			 */
			StrBufExtract_token(rev_uuid, Buf, 0, '|');
			StrBufExtract_token(node, Buf, 3, '|');
			++row;
		}

		wc_printf("</table>\n");
		FreeStrBuf(&author);
		FreeStrBuf(&node);
		FreeStrBuf(&rev_uuid);
	}
	else {
		wc_printf("%s", ChrPtr(Buf));
	}

	FreeStrBuf(&Buf);
}
Beispiel #6
0
/*
 * The pathname is always going to take one of two formats:
 * [/groupdav/]room_name/euid	(GroupDAV)
 * [/groupdav/]room_name		(webcal)
 */
void dav_put(void) 
{
	wcsession *WCC = WC;
	StrBuf *dav_roomname;
	StrBuf *dav_uid;
	long new_msgnum = (-2L);
	long old_msgnum = (-1L);
	char buf[SIZ];
	int n = 0;

	if (StrBufNum_tokens(WCC->Hdr->HR.ReqLine, '/') < 2) {
		hprintf("HTTP/1.1 404 not found\r\n");
		dav_common_headers();
		hprintf("Content-Type: text/plain\r\n");
		begin_burst();
		wc_printf("The object you requested was not found.\r\n");
		end_burst();
		return;
	}

	dav_roomname = NewStrBuf();;
	dav_uid = NewStrBuf();;
	StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');
	StrBufExtract_token(dav_uid, WCC->Hdr->HR.ReqLine, 1, '/');
	if ((!strcasecmp(ChrPtr(dav_uid), "ics")) || 
	    (!strcasecmp(ChrPtr(dav_uid), "calendar.ics"))) {
		FlushStrBuf(dav_uid);
	}

	/* Go to the correct room. */
	if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
		gotoroom(dav_roomname);
	}
	if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
		hprintf("HTTP/1.1 404 not found\r\n");
		dav_common_headers();
		hprintf("Content-Type: text/plain\r\n");
		begin_burst();
		wc_printf("There is no folder called \"%s\" on this server.\r\n",
			ChrPtr(dav_roomname));
		end_burst();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);		
		return;
	}

	/*
	 * If an HTTP If-Match: header is present, the client is attempting
	 * to replace an existing item.  We have to check to see if the
	 * message number associated with the supplied uid matches what the
	 * client is expecting.  If not, the server probably contains a newer
	 * version, so we fail...
	 */
	if (StrLength(WCC->Hdr->HR.dav_ifmatch) > 0) {
		syslog(LOG_DEBUG, "dav_ifmatch: %s\n", ChrPtr(WCC->Hdr->HR.dav_ifmatch));
		old_msgnum = locate_message_by_uid(ChrPtr(dav_uid));
		syslog(LOG_DEBUG, "old_msgnum:  %ld\n", old_msgnum);
		if (StrTol(WCC->Hdr->HR.dav_ifmatch) != old_msgnum) {
			hprintf("HTTP/1.1 412 Precondition Failed\r\n");
			syslog(LOG_INFO, "HTTP/1.1 412 Precondition Failed (ifmatch=%ld, old_msgnum=%ld)\r\n",
				StrTol(WCC->Hdr->HR.dav_ifmatch), old_msgnum);
			dav_common_headers();
			
			end_burst();
			FreeStrBuf(&dav_roomname);
			FreeStrBuf(&dav_uid);
			return;
		}
	}

	/** PUT on the collection itself uploads an ICS of the entire collection.
	 */
	if (StrLength(dav_uid) == 0) {
		dav_put_bigics();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);
		return;
	}

	/*
	 * We are cleared for upload!  We use the new calling syntax for ENT0
	 * which allows a confirmation to be sent back to us.  That's how we
	 * extract the message ID.
	 */
	serv_puts("ENT0 1|||4|||1|");
	serv_getln(buf, sizeof buf);
	if (buf[0] != '8') {
		hprintf("HTTP/1.1 502 Bad Gateway\r\n");
		dav_common_headers();
		hprintf("Content-type: text/plain\r\n");
		begin_burst();
		wc_printf("%s\r\n", &buf[4]);
		end_burst();
		return;
	}

	/* Send the content to the Citadel server */
	//serv_printf("Content-type: %s\n\n", WCC->upload_content_type);
	serv_putbuf(WCC->upload);
	serv_puts("\n000");

	/* Fetch the reply from the Citadel server */
	n = 0;
	FlushStrBuf(dav_uid);
	while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
		switch(n++) {
		case 0: 
			new_msgnum = atol(buf);
			break;
		case 1:	
			syslog(LOG_DEBUG, "new_msgnum=%ld (%s)\n", new_msgnum, buf);
			break;
		case 2: 
			StrBufAppendBufPlain(dav_uid, buf, -1, 0);
			break;
		default:
			break;
		}
	}

	/* Tell the client what happened. */

	/* Citadel failed in some way? */
	if (new_msgnum < 0L) {
		hprintf("HTTP/1.1 502 Bad Gateway\r\n");
		dav_common_headers();
		hprintf("Content-type: text/plain\r\n");
		begin_burst();
		wc_printf("new_msgnum is %ld\r\n"
			"\r\n", new_msgnum);
		end_burst();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);
		return;
	}

	/* We created this item for the first time. */
	if (old_msgnum < 0L) {
	        char escaped_uid[1024];
		hprintf("HTTP/1.1 201 Created\r\n");
		syslog(LOG_DEBUG, "HTTP/1.1 201 Created\r\n");
		dav_common_headers();
		hprintf("etag: \"%ld\"\r\n", new_msgnum);
		hprintf("Location: ");
		dav_identify_hosthdr();
		hprintf("/groupdav/");/* TODO */
		hurlescputs(ChrPtr(dav_roomname));
	        euid_escapize(escaped_uid, ChrPtr(dav_uid));
	        hprintf("/%s\r\n", escaped_uid);
		end_burst();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);
		return;
	}

	/* We modified an existing item. */
	hprintf("HTTP/1.1 204 No Content\r\n");
	syslog(LOG_DEBUG, "HTTP/1.1 204 No Content\r\n");
	dav_common_headers();
	hprintf("Etag: \"%ld\"\r\n", new_msgnum);
	/* The item we replaced has probably already been deleted by
	 * the Citadel server, but we'll do this anyway, just in case.
	 */
	serv_printf("DELE %ld", old_msgnum);
	serv_getln(buf, sizeof buf);
	begin_burst();
	end_burst();
	FreeStrBuf(&dav_roomname);
	FreeStrBuf(&dav_uid);
	return;
}
Beispiel #7
0
/*
 * The pathname is always going to be /groupdav/room_name/euid
 */
void dav_delete(void) 
{
	wcsession *WCC = WC;
	char dav_uid[SIZ];
	long dav_msgnum = (-1);
	char buf[SIZ];
	int n = 0;
	StrBuf *dav_roomname = NewStrBuf();
	
	/* Now extract the message euid */
	n = StrBufNum_tokens(WCC->Hdr->HR.ReqLine, '/');
	extract_token(dav_uid, ChrPtr(WCC->Hdr->HR.ReqLine), n-1, '/', sizeof dav_uid);
	StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');

	///* What's left is the room name.  Remove trailing slashes. */
	//len = StrLength(WCC->Hdr->HR.ReqLine);
	//if ((len > 0) && (ChrPtr(WCC->Hdr->HR.ReqLinee)[len-1] == '/')) {
	//	StrBufCutRight(WCC->Hdr->HR.ReqLine, 1);
	//}
	//StrBufCutLeft(WCC->Hdr->HR.ReqLine, 1);

	/* Go to the correct room. */
	if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
		gotoroom(dav_roomname);
	}
	if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
		hprintf("HTTP/1.1 404 not found\r\n");
		dav_common_headers();
		hprintf("Content-Length: 0\r\n\r\n");
		begin_burst();
		end_burst();
		FreeStrBuf(&dav_roomname);
		return;
	}

	dav_msgnum = locate_message_by_uid(dav_uid);

	/*
	 * If no item exists with the requested uid ... simple error.
	 */
	if (dav_msgnum < 0L) {
		hprintf("HTTP/1.1 404 Not Found\r\n");
		dav_common_headers();
		hprintf("Content-Length: 0\r\n\r\n");
		begin_burst();
		end_burst();
		FreeStrBuf(&dav_roomname);
		return;
	}

	/*
	 * It's there ... check the ETag and make sure it matches
	 * the message number.
	 */
	if (StrLength(WCC->Hdr->HR.dav_ifmatch) > 0) {
		if (StrTol(WCC->Hdr->HR.dav_ifmatch) != dav_msgnum) {
			hprintf("HTTP/1.1 412 Precondition Failed\r\n");
			dav_common_headers();
			hprintf("Content-Length: 0\r\n\r\n");
			begin_burst();
			end_burst();
			FreeStrBuf(&dav_roomname);
			return;
		}
	}

	/*
	 * Ok, attempt to delete the item.
	 */
	serv_printf("DELE %ld", dav_msgnum);
	serv_getln(buf, sizeof buf);
	if (buf[0] == '2') {
		hprintf("HTTP/1.1 204 No Content\r\n");	/* success */
		dav_common_headers();
		hprintf("Content-Length: 0\r\n\r\n");
		begin_burst();
		end_burst();
	}
	else {
		hprintf("HTTP/1.1 403 Forbidden\r\n");	/* access denied */
		dav_common_headers();
		hprintf("Content-Length: 0\r\n\r\n");
		begin_burst();
		end_burst();
	}
	FreeStrBuf(&dav_roomname);
	return;
}
Beispiel #8
0
/*
 * The pathname is always going to be /groupdav/room_name/msg_num
 */
void dav_options(void)
{
	wcsession *WCC = WC;
	StrBuf *dav_roomname;
	StrBuf *dav_uid;
	long dav_msgnum = (-1);
	char datestring[256];
	time_t now;

	now = time(NULL);
	http_datestring(datestring, sizeof datestring, now);

	dav_roomname = NewStrBuf();
	dav_uid = NewStrBuf();
	StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');
	StrBufExtract_token(dav_uid, WCC->Hdr->HR.ReqLine, 1, '/');

	syslog(LOG_DEBUG, "\033[35m%s (logged_in=%d)\033[0m", ChrPtr(WCC->Hdr->HR.ReqLine), WC->logged_in);
	/*
	 * If the room name is blank, the client is doing an OPTIONS on the root.
	 */
	if (StrLength(dav_roomname) == 0) {
		syslog(LOG_DEBUG, "\033[36mOPTIONS requested for root\033[0m");
		hprintf("HTTP/1.1 200 OK\r\n");
		dav_common_headers();
		hprintf("Date: %s\r\n", datestring);
		hprintf("DAV: 1\r\n");
		hprintf("Allow: OPTIONS, PROPFIND\r\n");
		hprintf("\r\n");
		begin_burst();
		end_burst();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);
		return;
	}

	/* Go to the correct room. */
	if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
		gotoroom(dav_roomname);
	}

	if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
		syslog(LOG_DEBUG, "\033[36mOPTIONS requested for invalid item\033[0m");
		hprintf("HTTP/1.1 404 not found\r\n");
		dav_common_headers();
		hprintf("Date: %s\r\n", datestring);
		hprintf(
			"Content-Type: text/plain\r\n");
		begin_burst();
		wc_printf(
			"There is no folder called \"%s\" on this server.\r\n",
			ChrPtr(dav_roomname)
		);
		end_burst();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);
		return;
	}

	/* If dav_uid is non-empty, client is requesting an OPTIONS on
	 * a specific item in the room.
	 */
	if (StrLength(dav_uid) != 0) {
		syslog(LOG_DEBUG, "\033[36mOPTIONS requested for specific item\033[0m");
		dav_msgnum = locate_message_by_uid(ChrPtr(dav_uid));
		if (dav_msgnum < 0) {
			hprintf("HTTP/1.1 404 not found\r\n");
			dav_common_headers();
			hprintf("Content-Type: text/plain\r\n");
			begin_burst();
			wc_printf(
				"Object \"%s\" was not found in the \"%s\" folder.\r\n",
				ChrPtr(dav_uid),
				ChrPtr(dav_roomname)
			);
			FreeStrBuf(&dav_roomname);
			FreeStrBuf(&dav_uid);
			end_burst();return;
		}

		hprintf("HTTP/1.1 200 OK\r\n");
		dav_common_headers();
		hprintf("Date: %s\r\n", datestring);
		hprintf("DAV: 1\r\n");
		hprintf("Allow: OPTIONS, PROPFIND, GET, PUT, DELETE\r\n");
		
		begin_burst();
		end_burst();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);
		return;
	}

	FreeStrBuf(&dav_roomname);
	FreeStrBuf(&dav_uid);

	/*
	 * We got to this point, which means that the client is requesting
	 * an OPTIONS on the room itself.
	 */
	syslog(LOG_DEBUG, "\033[36mOPTIONS requested for room '%s' (%slogged in)\033[0m",
		ChrPtr(WC->CurRoom.name),
		((WC->logged_in) ? "" : "not ")
	);
	hprintf("HTTP/1.1 200 OK\r\n");
	dav_common_headers();
	hprintf("Date: %s\r\n", datestring);

	/*
	 * Offer CalDAV (RFC 4791) if this is a calendar room
	 */
	if ( (WC->CurRoom.view == VIEW_CALENDAR) || (WC->CurRoom.view == VIEW_CALBRIEF) ) {
		hprintf("DAV: 1, calendar-access\r\n");
		syslog(LOG_DEBUG, "\033[36mDAV: 1, calendar-access\033[0m");
	}
	else {
		hprintf("DAV: 1\r\n");
		syslog(LOG_DEBUG, "\033[36mDAV: 1\033[0m");
	}

	hprintf("Allow: OPTIONS, PROPFIND, GET, PUT, REPORT\r\n");
	begin_burst();
	end_burst();
}
Beispiel #9
0
/*
 * Read in the request
 */
int ReadHTTPRequest (ParsedHttpHdrs *Hdr)
{
	const char *pch, *pchs, *pche;
	OneHttpHeader *pHdr;
	StrBuf *Line, *LastLine, *HeaderName;
	int nLine = 0;
	void *vF;
	int isbogus = 0;

	HeaderName = NewStrBuf();
	LastLine = NULL;
	do {
		nLine ++;
		Line = NewStrBufPlain(NULL, SIZ / 4);

		if (ClientGetLine(Hdr, Line) < 0) return 1;

		if (StrLength(Line) == 0) {
			FreeStrBuf(&Line);
			continue;
		}
		if (nLine == 1) {
			Hdr->HTTPHeaders = NewHash(1, NULL);
			pHdr = (OneHttpHeader*) malloc(sizeof(OneHttpHeader));
			memset(pHdr, 0, sizeof(OneHttpHeader));
			pHdr->Val = Line;
			Put(Hdr->HTTPHeaders, HKEY("GET /"), pHdr, DestroyHttpHeaderHandler);
			if (verbose || strstr(ChrPtr(Line), "sslg") == NULL)
				syslog(LOG_DEBUG, "%s", ChrPtr(Line));
			isbogus = ReadHttpSubject(Hdr, Line, HeaderName);
			if (isbogus) break;
			continue;
		}

		/* Do we need to Unfold? */
		if ((LastLine != NULL) && 
		    (isspace(*ChrPtr(Line)))) {
			pch = pchs = ChrPtr(Line);
			pche = pchs + StrLength(Line);
			while (isspace(*pch) && (pch < pche))
				pch ++;
			StrBufCutLeft(Line, pch - pchs);
			StrBufAppendBuf(LastLine, Line, 0);

			FreeStrBuf(&Line);
			continue;
		}

		StrBufSanitizeAscii(Line, (char)0xa7);
		StrBufExtract_token(HeaderName, Line, 0, ':');

		pchs = ChrPtr(Line);
		pche = pchs + StrLength(Line);
		pch = pchs + StrLength(HeaderName) + 1;
		pche = pchs + StrLength(Line);
		while ((pch < pche) && isspace(*pch))
			pch ++;
		StrBufCutLeft(Line, pch - pchs);

		StrBufUpCase(HeaderName);

		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 (Line != NULL);

	FreeStrBuf(&HeaderName);

	return isbogus;
}
Beispiel #10
0
int ReadHttpSubject(ParsedHttpHdrs *Hdr, StrBuf *Line, StrBuf *Buf)
{
	const char *Args;
	void *vLine, *vHandler;
	const char *Pos = NULL;

	Hdr->HR.ReqLine = Line;
	/* The requesttype... GET, POST... */
	StrBufExtract_token(Buf, Hdr->HR.ReqLine, 0, ' ');
	if (GetHash(HttpReqTypes, SKEY(Buf), &vLine) &&
	    (vLine != NULL))
	{
		Hdr->HR.eReqType = *(long*)vLine;
	}
	else {
		Hdr->HR.eReqType = eGET;
		return 1;
	}
	StrBufCutLeft(Hdr->HR.ReqLine, StrLength(Buf) + 1);

	/* the HTTP Version... */
	StrBufExtract_token(Buf, Hdr->HR.ReqLine, 1, ' ');
	StrBufCutRight(Hdr->HR.ReqLine, StrLength(Buf) + 1);
	
	if (StrLength(Buf) == 0) {
		Hdr->HR.eReqType = eGET;
		return 1;
	}

	StrBufAppendBuf(Hdr->this_page, Hdr->HR.ReqLine, 0);

	/* chop Filename / query arguments */
	Args = strchr(ChrPtr(Hdr->HR.ReqLine), '?');
	if (Args == NULL) /* whe're not that picky about params... TODO: this will spoil '&' in filenames.*/
		Args = strchr(ChrPtr(Hdr->HR.ReqLine), '&');
	if (Args != NULL) {
		Args ++; /* skip the ? */
		StrBufPlain(Hdr->PlainArgs, 
			    Args, 
			    StrLength(Hdr->HR.ReqLine) -
			    (Args - ChrPtr(Hdr->HR.ReqLine)));
		StrBufCutAt(Hdr->HR.ReqLine, 0, Args - 1);
	} /* 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->HR.ReqLine, &Pos, '/');
	do {
		StrBufExtract_NextToken(Buf, Hdr->HR.ReqLine, &Pos, '/');

		GetHash(HandlerHash, SKEY(Buf), &vHandler),
		Hdr->HR.Handler = (WebcitHandler*) vHandler;
		if (Hdr->HR.Handler == NULL)
			break;
		/*
		 * 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 ((Hdr->HR.Handler->Flags & URLNAMESPACE) != 0)
			continue;
		break;
	} while (1);
	/* remove the handlername from the URL */
	if ((Pos != NULL) && (Pos != StrBufNOTNULL)){
		StrBufCutLeft(Hdr->HR.ReqLine, 
			      Pos - ChrPtr(Hdr->HR.ReqLine));
	}

	if (Hdr->HR.Handler != NULL) {
		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 {
		/* 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?failvisibly=1 HTTP/1.0", ChrPtr(Buf));
		if (verbose) syslog(LOG_DEBUG, "Replacing with: %s", ChrPtr(NewLine));
		return_value = ReadHttpSubject(Hdr, NewLine, Buf);
		FreeStrBuf(&NewLine);
		return return_value;
	}

	return 0;
}