<%@ WebHandler Language="C#" Class="ConvertService2" %> /* * (c) Copyright Ascensio System SIA 2010-2015 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation. In accordance with * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect * that Ascensio System SIA expressly excludes the warranty of non-infringement * of any third-party rights. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, * EU, LV-1021. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ using System; using System.Net; using System.Configuration; using System.Web; using System.IO; using System.Text; using System.Xml; using System.Collections.Generic; using System.Threading; using FileConverterUtils2; using log4net; public class ConvertService2 : IHttpAsyncHandler { private readonly ILog _log = LogManager.GetLogger(typeof(ConvertService2)); public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) { TransportClassMainAshx oTransportClassMainAshx = new TransportClassMainAshx(context, cb); ErrorTypes eError = ErrorTypes.NoError; try { _log.Info("Starting process request..."); _log.Info(context.Request.QueryString.ToString()); InputParams oInputParams = new InputParams(); oInputParams.m_sKey = context.Request.QueryString["key"]; oInputParams.m_svKey = context.Request.QueryString["vkey"]; oInputParams.m_sUrl = context.Request.QueryString["url"]; oInputParams.m_sEmbeddedfonts = context.Request.QueryString["embeddedfonts"]; int nIndexSep = oInputParams.m_sUrl.IndexOf(','); if (-1 != nIndexSep) oInputParams.m_sUrl = oInputParams.m_sUrl.Substring(0, nIndexSep); oInputParams.m_sTitle = context.Request.QueryString["title"]; if (string.IsNullOrEmpty(oInputParams.m_sTitle)) oInputParams.m_sTitle = "convert"; oInputParams.m_sFiletype = context.Request.QueryString["filetype"]; oInputParams.m_nOutputtype = FileFormats.FromString(context.Request.QueryString["outputtype"]); oInputParams.m_bAsyncConvert = Convert.ToBoolean(context.Request.QueryString["async"]); oInputParams.m_sCodepage = context.Request.QueryString["codePage"]; oInputParams.m_sDelimiter = context.Request.QueryString["delimiter"]; if (ErrorTypes.NoError == eError) { ITaskResultInterface oTaskResult = TaskResult.NewTaskResult(); TaskResultData oToAdd = new TaskResultData(); oInputParams.m_sKey = "conv_" + oInputParams.m_sKey; oToAdd.sKey = oInputParams.m_sKey; oToAdd.sFormat = oInputParams.m_sFiletype; oToAdd.eStatus = FileStatus.WaitQueue; oToAdd.sTitle = oInputParams.m_sTitle; TransportClass1 oTransportClass1 = new TransportClass1(oTransportClassMainAshx, oTaskResult, new CTaskQueue(), oInputParams); oTaskResult.GetOrCreateBegin(oInputParams.m_sKey, oToAdd, GetOrCreateCallback, oTransportClass1); } } catch(Exception e) { eError = ErrorTypes.Unknown; _log.Error(context.Request.QueryString.ToString()); _log.Error("Exeption: ", e); } finally { if( ErrorTypes.NoError != eError ) WriteOutputCommand(oTransportClassMainAshx, new OutputCommand(null, null, null, eError)); } return new AsyncOperationData(extraData); } public void EndProcessRequest(IAsyncResult result) { } public void ProcessRequest(HttpContext context) { throw new InvalidOperationException(); } public bool IsReusable { get { return false; } } private void WriteOutputCommand(TransportClassMainAshx oTransportClassMainAshx, OutputCommand oOutputCommand) { HttpContext oHttpContext = oTransportClassMainAshx.m_oHttpContext; AsyncCallback fAsyncCallback = oTransportClassMainAshx.m_oAsyncCallback; oHttpContext.Response.ContentType = "text/xml"; oHttpContext.Response.Charset = "UTF-8"; string sXml = ""; if (null != oOutputCommand.m_sFileUrl) sXml += string.Format("{0}", HttpUtility.HtmlEncode(oOutputCommand.m_sFileUrl)); if (null != oOutputCommand.m_sPercent) sXml += string.Format("{0}", oOutputCommand.m_sPercent); if (true == oOutputCommand.m_bIsEndConvert.HasValue) sXml += string.Format("{0}", oOutputCommand.m_bIsEndConvert.Value.ToString()); if (ErrorTypes.NoError != oOutputCommand.m_eError) sXml += string.Format("{0}", Utils.mapAscServerErrorToOldError(oOutputCommand.m_eError).ToString()); sXml += ""; oHttpContext.Response.Write(sXml); fAsyncCallback.Invoke(new AsyncOperationData(null)); } private void GetOrCreateCallback(IAsyncResult ar) { TransportClass1 oTransportClass1 = ar.AsyncState as TransportClass1; try { TaskResultData oTaskResultData; bool bCreate; ErrorTypes eError = oTransportClass1.m_oTaskResult.GetOrCreateEnd(ar, out oTaskResultData, out bCreate); if (ErrorTypes.NoError == eError) { if(bCreate) { InputParams oInputParams = oTransportClass1.m_oInputParams; TaskQueueData oTaskQueueData = new TaskQueueData(oInputParams.m_sKey, oInputParams.m_nOutputtype, "output." + FileFormats.ToString(oInputParams.m_nOutputtype)); oTaskQueueData.m_sFromUrl = oInputParams.m_sUrl; oTaskQueueData.m_sFromFormat = oInputParams.m_sFiletype; if (null != oInputParams.m_sDelimiter && string.Empty != oInputParams.m_sDelimiter) oTaskQueueData.m_nCsvDelimiter = int.Parse(oInputParams.m_sDelimiter); else oTaskQueueData.m_nCsvDelimiter = (int)CsvDelimiter.Comma; if (null != oInputParams.m_sCodepage && string.Empty != oInputParams.m_sCodepage) oTaskQueueData.m_nCsvTxtEncoding = int.Parse(oInputParams.m_sCodepage); else oTaskQueueData.m_nCsvTxtEncoding = Encoding.UTF8.CodePage; if ("true" == oInputParams.m_sEmbeddedfonts) oTaskQueueData.m_bEmbeddedFonts = true; oTransportClass1.m_oTaskQueue.AddTaskBegin(oTaskQueueData, Priority.Low, AddTaskCallback, oTransportClass1); } else CheckStatus(oTransportClass1, oTaskResultData); } else WriteOutputCommand(oTransportClass1, new OutputCommand(null, null, null, eError)); } catch { WriteOutputCommand(oTransportClass1, new OutputCommand(null, null, null, ErrorTypes.Unknown)); } } private void AddTaskCallback(IAsyncResult ar) { TransportClass1 oTransportClass1 = ar.AsyncState as TransportClass1; try { ErrorTypes eError = oTransportClass1.m_oTaskQueue.AddTaskEnd(ar); if (ErrorTypes.NoError == eError) { if (true == oTransportClass1.m_oInputParams.m_bAsyncConvert) WriteOutputCommand(oTransportClass1, new OutputCommand("", "0", false, ErrorTypes.NoError)); else WaitEnd(oTransportClass1); } else WriteOutputCommand(oTransportClass1, new OutputCommand(null, null, null, eError)); } catch { WriteOutputCommand(oTransportClass1, new OutputCommand(null, null, null, ErrorTypes.Unknown)); } } private void CheckStatus(TransportClass1 oTransportClass1, TaskResultData oTaskResultData) { switch (oTaskResultData.eStatus) { case FileStatus.Ok: string sFilename = HttpUtility.UrlEncode("output." + FileFormats.ToString(oTransportClass1.m_oInputParams.m_nOutputtype)); string sPath = HttpUtility.UrlEncode(Path.GetFileNameWithoutExtension(oTransportClass1.m_oInputParams.m_sKey) + "/output." + FileFormats.ToString(oTransportClass1.m_oInputParams.m_nOutputtype)); string sDeletePath = HttpUtility.UrlEncode(Path.GetFileNameWithoutExtension(oTransportClass1.m_oInputParams.m_sKey)); string sSiteUrl = UrlBuilder.UrlWithoutPath(oTransportClass1.m_oHttpContext.Request); string strFileUrl = sSiteUrl + Constants.mc_sResourceServiceUrlRel + sPath + "&nocache=true" +"&deletepath=" + sDeletePath + "&filename=" + sFilename; WriteOutputCommand(oTransportClass1, new OutputCommand(strFileUrl, "100", true, ErrorTypes.NoError)); break; case FileStatus.WaitQueue: if (oTransportClass1.m_oInputParams.m_bAsyncConvert) WriteOutputCommand(oTransportClass1, new OutputCommand("", "0", false, ErrorTypes.NoError)); else WaitEnd(oTransportClass1); break; case FileStatus.Convert: if (oTransportClass1.m_oInputParams.m_bAsyncConvert) WriteOutputCommand(oTransportClass1, new OutputCommand("", oTaskResultData.nStatusInfo.ToString(), false, ErrorTypes.NoError)); else WaitEnd(oTransportClass1); break; case FileStatus.Err: case FileStatus.ErrToReload: AsyncClearCacheOperation oAsyncClearCacheOperation = new AsyncClearCacheOperation(); TransportClass2 oTransportClass2 = new TransportClass2(oTransportClass1, oAsyncClearCacheOperation, (ErrorTypes)oTaskResultData.nStatusInfo); oAsyncClearCacheOperation.ClearCacheBegin(oTransportClass1.m_oInputParams.m_sKey, ClearCacheCallback, oTransportClass2); break; default: WriteOutputCommand(oTransportClass1, new OutputCommand(null, null, null, ErrorTypes.Unknown)); break; } } private void WaitEnd(TransportClass1 oTransportClass1) { try { Timer oTimer = new Timer(WaitEndTimerCallback, oTransportClass1, TimeSpan.FromMilliseconds(-1), TimeSpan.FromMilliseconds(-1)); oTransportClass1.m_oTimer = oTimer; oTimer.Change(TimeSpan.FromMilliseconds(1000), TimeSpan.FromMilliseconds(-1)); } catch { WriteOutputCommand(oTransportClass1, new OutputCommand(null, null, null, ErrorTypes.Unknown)); } } private void WaitEndTimerCallback(Object stateInfo) { TransportClass1 oTransportClass1 = stateInfo as TransportClass1; try { if (null != oTransportClass1.m_oTimer) oTransportClass1.m_oTimer.Dispose(); oTransportClass1.m_oTaskResult.GetBegin(oTransportClass1.m_oInputParams.m_sKey, WaitEndCallback, oTransportClass1); } catch { WriteOutputCommand(oTransportClass1, new OutputCommand(null, null, null, ErrorTypes.Unknown)); } } private void WaitEndCallback(IAsyncResult ar) { TransportClass1 oTransportClass1 = ar.AsyncState as TransportClass1; try { TaskResultData oTaskResultData; ErrorTypes eError = oTransportClass1.m_oTaskResult.GetEnd(ar, out oTaskResultData); if (ErrorTypes.NoError == eError) CheckStatus(oTransportClass1, oTaskResultData); else WriteOutputCommand(oTransportClass1, new OutputCommand(null, null, null, eError)); } catch { WriteOutputCommand(oTransportClass1, new OutputCommand(null, null, null, ErrorTypes.Unknown)); } } private void ClearCacheCallback(IAsyncResult ar) { TransportClass2 oTransportClass2 = ar.AsyncState as TransportClass2; try { ErrorTypes eError = oTransportClass2.m_oAsyncClearCacheOperation.ClearCacheEnd(ar); if (ErrorTypes.NoError == eError) { WriteOutputCommand(oTransportClass2, new OutputCommand(null, null, null, oTransportClass2.m_eError)); } else WriteOutputCommand(oTransportClass2, new OutputCommand(null, null, null, eError)); } catch { WriteOutputCommand(oTransportClass2, new OutputCommand(null, null, null, ErrorTypes.Unknown)); } } private class TransportClass1 : TransportClassMainAshx { public ITaskResultInterface m_oTaskResult; public CTaskQueue m_oTaskQueue; public InputParams m_oInputParams; public Timer m_oTimer; public TransportClass1(TransportClassMainAshx oTransportClassMainAshx, ITaskResultInterface oTaskResult, CTaskQueue oTaskQueue, InputParams oInputParams) : base(oTransportClassMainAshx.m_oHttpContext, oTransportClassMainAshx.m_oAsyncCallback) { m_oTaskResult = oTaskResult; m_oInputParams = oInputParams; m_oTaskQueue = oTaskQueue; m_oTimer = null; } } private class TransportClass2 : TransportClassMainAshx { public AsyncClearCacheOperation m_oAsyncClearCacheOperation; public ErrorTypes m_eError; public TransportClass2(TransportClassMainAshx oTransportClassMainAshx, AsyncClearCacheOperation oAsyncClearCacheOperation, ErrorTypes eError) : base(oTransportClassMainAshx.m_oHttpContext, oTransportClassMainAshx.m_oAsyncCallback) { m_oAsyncClearCacheOperation = oAsyncClearCacheOperation; m_eError = eError; } } private class InputParams { public string m_sKey; public string m_svKey; public string m_sUrl; public string m_sTitle; public string m_sFiletype; public int m_nOutputtype; public bool m_bAsyncConvert; public string m_sEmbeddedfonts; public string m_sCodepage; public string m_sDelimiter; } private class OutputCommand { public string m_sFileUrl; public string m_sPercent; public bool? m_bIsEndConvert; public ErrorTypes m_eError; public OutputCommand(string strFileUrl, string strPercent, bool? bIsEndConvert, ErrorTypes eError) { m_sFileUrl = strFileUrl; m_sPercent = strPercent; m_bIsEndConvert = bIsEndConvert; m_eError = eError; } } }