public ServerException(DtpException exception)
            : base(
                $"Remote connection threw an error when executing function \"{exception.FunctionName}\": {exception.Message}", new Exception(exception.Message)
                )
        {
            ServerMessage =
                $"Function name: {exception.FunctionName}\r\nParameters: {(string.IsNullOrEmpty(exception.ParameterInformation) ? "null" : exception.ParameterInformation)}\r\n" +
                exception.StackTrace + "\r\n--------- FINISH SERVER STACK TRACE ---------\r\n";

            var field = typeof(Exception).GetField("_remoteStackTraceString", BindingFlags.NonPublic | BindingFlags.Instance);

            field.SetValue(this, ServerMessage); //change stack trace with a small hack
        }
示例#2
0
        /// <summary>
        ///     Process the received data from a <see cref="DtpFactory" />
        /// </summary>
        /// <param name="data">The data which was given using the <see cref="DtpFactory.SendDataAction" /> delegate</param>
        /// <param name="start">The start position of the byte array</param>
        /// <returns>Returns the response which must get processed in <see cref="DtpFactory.Receive" /></returns>
        public byte[] Receive(byte[] data, int start)
        {
            data = LZF.Decompress(data, start);
            var functionNameLength = BitConverter.ToInt32(data, 16);
            var functionName       = Encoding.UTF8.GetString(data, 20, functionNameLength);

            if (!_procedures.ContainsKey(functionName) && !_functions.ContainsKey(functionName))
            {
                ExceptionOccurred?.Invoke(this,
                                          new UnhandledExceptionEventArgs(
                                              new InvalidOperationException($"Method with name {functionName} not found")));

                var errorResponse = new byte[16 + functionNameLength];
                Array.Copy(DtpFactory.FunctionNotFoundExceptionGuid.ToByteArray(), errorResponse, 16);
                Array.Copy(data, 20, errorResponse, 16, functionNameLength);
                return(errorResponse);
            }

            var parameterCount = BitConverter.ToInt32(data, 20 + functionNameLength);

            var parameterLengths = new List <int>();
            var parameters       = new Dictionary <int, byte[]>();

            for (int i = 0; i < parameterCount; i++)
            {
                parameterLengths.Add(BitConverter.ToInt32(data, 24 + functionNameLength + i * 4));
            }

            var offset = 0;

            for (int i = 0; i < parameterCount; i++)
            {
                var parameterData = new byte[parameterLengths[i]];
                Array.Copy(data, 24 + functionNameLength + parameterCount * 4 + offset, parameterData, 0,
                           parameterData.Length);
                parameters.Add(i, parameterData);
                offset += parameterData.Length;
            }

            var dtpParameters = new DtpParameters(parameters);

            byte[] result = null;

            try
            {
                DtpProcedure procedure;
                if (_procedures.TryGetValue(functionName, out procedure))
                {
                    procedure.Invoke(dtpParameters);
                }
                else
                {
                    DtpFunction function;
                    if (_functions.TryGetValue(functionName, out function))
                    {
                        var returnedObject = function.Invoke(dtpParameters);

                        if (returnedObject != null)
                        {
                            var typeList = new List <Type> {
                                returnedObject.GetType()
                            };
                            Type[] specialTypes;
                            if (_specialTypes.TryGetValue(functionName, out specialTypes))
                            {
                                typeList.AddRange(specialTypes);
                            }

                            result = new Serializer(typeList).Serialize(returnedObject);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                var exception = new DtpException
                {
                    Message              = ex.Message,
                    StackTrace           = ex.StackTrace,
                    FunctionName         = functionName,
                    ParameterInformation = string.Join(", ",
                                                       parameters.Select(x => x.Key + " - " + x.Value.Length + " B").ToArray()),
                    SessionGuid = new Guid(data.Take(16).ToArray())
                };

                var exceptionData = new Serializer(typeof(DtpException)).Serialize(exception);
                var errorResponse = new byte[16 + exceptionData.Length];
                Array.Copy(DtpFactory.ExceptionGuid.ToByteArray(), errorResponse, 16);
                Array.Copy(exceptionData, 0, errorResponse, 16, exceptionData.Length);

                ExceptionOccurred?.Invoke(this, new UnhandledExceptionEventArgs(ex));
                return(LZF.Compress(errorResponse, 0));
            }

            var response = new byte[16 + 4 + (result?.Length ?? 0)];

            //Protocol
            //HEAD  - 16 Bytes      - Guid
            //HEAD  - 4 Bytes       - Response Length
            //DATA  - result.Length - Result Length
            Array.Copy(data, 0, response, 0, 16); //copy guid
            Array.Copy(BitConverter.GetBytes(result?.Length ?? 0), 0, response, 16, 4);
            if (result != null)
            {
                Array.Copy(result, 0, response, 20, result.Length);
            }

            return(LZF.Compress(response, 0));
        }