コード例 #1
0
        internal static void SerializeBody(IShippingApiRequest request, StreamWriter writer, ISession session)
        {
            switch (request.ContentType)
            {
            case "application/json":
                var serializer = new JsonSerializer()
                {
                    ContractResolver = new ShippingApiContractResolver()
                };
                serializer.Error += delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
                {
                    // only log an error once
                    if (args.CurrentObject == args.ErrorContext.OriginalObject)
                    {
                        session.LogError(String.Format("Deserialization error at path {0}: {1}", args.ErrorContext.Path, args.ErrorContext.Error));
                    }
                    if (!session.ThrowExceptions)
                    {
                        args.ErrorContext.Handled = true;
                    }
                };
                ((ShippingApiContractResolver)serializer.ContractResolver).Registry = session.SerializationRegistry;
                serializer.NullValueHandling = NullValueHandling.Ignore;
                serializer.Formatting        = Formatting.Indented;
                serializer.Serialize(writer, request);
                writer.Flush();
                return;

            case "application/x-www-form-urlencoded":
                bool isFirst = true;

                foreach (var propertyInfo in request.GetType().GetProperties())
                {
                    foreach (object attribute in propertyInfo.GetCustomAttributes(true))
                    {
                        if (attribute is JsonPropertyAttribute)
                        {
                            if (!isFirst)
                            {
                                writer.WriteLine(); isFirst = false;
                            }
                            writer.Write(((JsonPropertyAttribute)attribute).PropertyName);
                            writer.Write('=');
                            writer.Write((string)propertyInfo.GetValue(request));
                        }
                    }
                }
                writer.Flush();

                return;

            default:
                session.LogConfigError("Unrecognized request content type:" + request.ContentType);
                throw new InvalidOperationException("Unrecognized request content type:" + request.ContentType);
            }
        }
        /// <summary>
        /// Call the shipping API for given request object.
        /// </summary>
        /// <returns>The call.</returns>
        /// <param name="request">Request.</param>
        /// <param name="session">Session.</param>
        public ShippingApiResponse Call(IShippingApiRequest request, ISession session)
        {
            MethodInfo method;
            MethodInfo generic;

            if (request != null)
            {
                session.LogDebug("Mock - calling method");
                switch (Verb)
                {
                case HttpVerb.DELETE:
                    method  = typeof(WebMethod).GetMethod("DeleteWithBodySync");
                    generic = method.MakeGenericMethod(new Type[] { ResponseType, request.GetType() });
                    return((ShippingApiResponse)generic.Invoke(null, new object[] { UriRegex, request, session }));

                case HttpVerb.POST:
                    method  = typeof(WebMethod).GetMethod("PostSync");
                    generic = method.MakeGenericMethod(new Type[] { ResponseType, request.GetType() });
                    return((ShippingApiResponse)generic.Invoke(null, new object[] { UriRegex, request, session }));

                case HttpVerb.PUT:
                    method  = typeof(WebMethod).GetMethod("PutSync");
                    generic = method.MakeGenericMethod(new Type[] { ResponseType, request.GetType() });
                    return((ShippingApiResponse)generic.Invoke(null, new object[] { UriRegex, request, session }));

                default:
                    throw new Exception("Attempt to GET with a body");
                }
            }
            else
            {
                switch (Verb)
                {
                case HttpVerb.DELETE:
                    method  = typeof(WebMethod).GetMethod("DeleteSync");
                    generic = method.MakeGenericMethod(new Type[] { ResponseType, request.GetType() });
                    return((ShippingApiResponse)generic.Invoke(null, new object[] { UriRegex, request, session }));

                case HttpVerb.GET:
                    method  = typeof(WebMethod).GetMethod("GetSync");
                    generic = method.MakeGenericMethod(new Type[] { ResponseType, request.GetType() });
                    return((ShippingApiResponse)generic.Invoke(null, new object[] { UriRegex, request, session }));

                default:
                    throw new Exception(String.Format("Attempt to {0} without a body", Verb.ToString()));
                }
            }
        }
コード例 #3
0
        internal static void SerializeBody(IShippingApiRequest request, StreamWriter writer, ISession session)
        {
            switch (request.ContentType)
            {
            case "application/json":
                var serializer = new JsonSerializer()
                {
                    ContractResolver = new ShippingApiContractResolver()
                };
                ((ShippingApiContractResolver)serializer.ContractResolver).Registry = session.SerializationRegistry;
                serializer.NullValueHandling = NullValueHandling.Ignore;
                serializer.Formatting        = Formatting.Indented;
                serializer.Serialize(writer, request);
                writer.Flush();
                return;

            case "application/x-www-form-urlencoded":
                bool isFirst = true;

                foreach (var propertyInfo in request.GetType().GetProperties())
                {
                    foreach (object attribute in propertyInfo.GetCustomAttributes(true))
                    {
                        if (attribute is JsonPropertyAttribute)
                        {
                            if (!isFirst)
                            {
                                writer.WriteLine(); isFirst = false;
                            }
                            writer.Write(((JsonPropertyAttribute)attribute).PropertyName);
                            writer.Write('=');
                            writer.Write((string)propertyInfo.GetValue(request));
                        }
                    }
                }
                writer.Flush();

                return;

            default:
                session.LogConfigError("Unrecognized request content type:" + request.ContentType);
                throw new InvalidOperationException("Unrecognized request content type:" + request.ContentType);
            }
        }
コード例 #4
0
        /// <summary>
        /// Full path to the recording file
        /// </summary>
        /// <param name="request"></param>
        /// <param name="resource"></param>
        /// <param name="session"></param>
        /// <returns></returns>
        public static string RecordingFullPath(IShippingApiRequest request, string resource, ISession session)
        {
            string        dirname    = session.RecordPath;
            StringBuilder uriBuilder = new StringBuilder(resource);

            ShippingApiRequest.SubstitueResourceParameters(request, uriBuilder);

            string fullPath = (dirname + uriBuilder.ToString().ToLower() + @"\")
                              .Replace('?', Path.DirectorySeparatorChar)
                              .Replace('&', Path.DirectorySeparatorChar)
                              .Replace('/', Path.DirectorySeparatorChar)
                              .Replace('=', '-');
            string fileName = "default";

            if (session == null)
            {
                session = Globals.DefaultSession;
            }

            foreach (var h in request.GetHeaders())
            {
                if (h.Item3.ToLower().Equals("authorization"))
                {
                    if (fileName.Equals("default"))
                    {
                        fileName = h.Item2.Substring(0, 8).ToLower();
                    }
                }
                if (h.Item1.Name.ToLower().Equals("x-pb-transactionid"))
                {
                    fileName = h.Item2.ToLower();
                }
            }
            fileName += request.RecordingSuffix;
            fileName += ".http";
            return(fullPath + Path.DirectorySeparatorChar + fileName);
        }
コード例 #5
0
        /// <summary>
        /// Full path to the recording file
        /// </summary>
        /// <param name="request"></param>
        /// <param name="resource"></param>
        /// <param name="session"></param>
        /// <returns></returns>
        public static string RecordingFullPath(IShippingApiRequest request, string resource, ISession session)
        {
#pragma warning disable CS0618
            var dirname = session.RecordPath;
#pragma warning restore CS0618
            var uriBuilder = new StringBuilder(resource);
            ShippingApiRequest.SubstitueResourceParameters(request, uriBuilder);
            var pathBuilder   = new StringBuilder("/");
            var uriComponents = uriBuilder.ToString().Split('/');
            for (int i = 1; i < Math.Min(3, uriComponents.Length); i++)
            {
                pathBuilder.Append(uriComponents[i]);
                pathBuilder.Append(Path.DirectorySeparatorChar);
            }
            var fileNameBuilder = new StringBuilder();
            for (int i = 3; i < uriComponents.Length; i++)
            {
                fileNameBuilder.Append(uriComponents[i]);
                fileNameBuilder.Append('_');
            }
            var    s        = fileNameBuilder.ToString().ToLower();
            string fileName = "";
            if (s.Length > 0)
            {
                fileName = s.Substring(0, s.Length - 1)
                           .Replace('?', '-')
                           .Replace('&', '-')
                           .Replace('=', '.');
            }

            // At this point
            // dirname is base directory
            // pathBuilder.ToString() is the relative path based on 2 levels of uri path
            // fileName is the name built from the remaining uri path and any parameters
            return(dirname + pathBuilder.ToString() + fileName + request.RecordingSuffix + ".txt");
        }
        /// <summary>
        /// Request the specified mimeStream, methods and session.
        /// </summary>
        /// <returns>The request.</returns>
        /// <param name="mimeStream">MIME stream.</param>
        /// <param name="methods">Methods.</param>
        /// <param name="session">Session.</param>
        public static ShippingApiMethodRequest Request(MimeStream mimeStream, List <ShippingApiMethod> methods, ISession session)
        {
            mimeStream.ReadHeaders(); // reads http headers as well

            Dictionary <string, string> headers = new Dictionary <string, string>();

            foreach (var h in mimeStream.Headers.Keys)
            {
                StringBuilder sb    = new StringBuilder();
                bool          first = true;
                foreach (var s in mimeStream.Headers[h])
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        sb.Append(';');
                    }
                    sb.Append(s);
                }
                headers.Add(h, sb.ToString());
            }

            var    firstLine = mimeStream.FirstLine.Split(' ');
            var    verb      = firstLine[0];
            string pattern   = "(?<file>/[a-zA-Z0-9/]+)(\\?(?<parameters>.*))*";
            var    urlRegex  = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant | RegexOptions.Compiled);
            var    match     = urlRegex.Match(firstLine[1]);

            if (!match.Success)
            {
                throw new Exception("Could not parse URI");
            }
            var uri        = match.Groups[urlRegex.GroupNumberFromName("file")].Value;
            var parameters = match.Groups[urlRegex.GroupNumberFromName("parameters")].Value;

            var requestParameters = new Dictionary <string, string>();

            if (parameters != null && !parameters.Equals(""))
            {
                var p1 = parameters.Split('&');
                foreach (var p2 in p1)
                {
                    var h = p2.Split('=');
                    requestParameters[h[0]] = h[1];
                }
            }

            var deserializer = new JsonSerializer();

            deserializer.Error           += DeserializationError;
            deserializer.ContractResolver = new ShippingApiContractResolver();
            if (session.TraceWriter != null)
            {
                deserializer.TraceWriter = session.TraceWriter;
            }

            foreach (var method in methods)
            {
                if (method.Verb.ToString() != verb)
                {
                    continue;
                }
                var re = new Regex(method.UriRegex, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant | RegexOptions.Compiled);
                var m  = re.Match(uri);
                if (m.Success)
                {
                    IShippingApiRequest request = null;
                    // create the request
                    using (var reader = new StreamReader(mimeStream))
                    {
                        ((ShippingApiContractResolver)deserializer.ContractResolver).Registry = session.SerializationRegistry;
                        // if wrapped create wrapper object
                        if (method.RequestInterface != null)
                        {
                            var    obj         = deserializer.Deserialize(reader, method.RequestType);
                            Type[] typeArgs    = { obj.GetType() };
                            var    wrapperType = session.SerializationRegistry.GetWrapperFor(method.RequestInterface).MakeGenericType(typeArgs);
                            request = (IShippingApiRequest)Activator.CreateInstance(wrapperType, obj);
                        }
                        else
                        {
                            request = (IShippingApiRequest)deserializer.Deserialize(reader, method.RequestType);
                        }
                    }

                    // set params in the URI
                    for (int g = 0; g < m.Groups.Count; g++)
                    {
                        var paramName = re.GroupNameFromNumber(g);
                        // set property of the request matching capture name
                        if (!Regex.IsMatch(paramName, "^\\d+$"))
                        {
                            PropertyInfo prop = method.RequestType.GetProperty("paramName");
                            prop.SetValue(request, match.Groups[g].Value, null);
                        }
                    }

                    // query properties
                    ShippingApiRequest.ProcessRequestAttributes <ShippingApiQueryAttribute>(request,
                                                                                            (a, s, v, p) => {
                        // p is prop name
                        if (requestParameters.ContainsKey(s))
                        {
                            PropertyInfo prop = request.GetType().GetProperty(p);
                            //TODO: better handling of JSON encoding
                            var sb = new StringBuilder(requestParameters[s]).Replace("\"", "\\\"").Append("\"");
                            sb.Insert(0, "\"");
                            var tx = new StringReader(sb.ToString());
                            var o  = deserializer.Deserialize(tx, prop.PropertyType);
                            prop.SetValue(request, o);
                        }
                    }
                                                                                            );

                    // header properties
                    ShippingApiRequest.ProcessRequestAttributes <ShippingApiHeaderAttribute>(request,
                                                                                             (a, s, v, p) => {
                        foreach (var h in headers)
                        {
                            if (h.Key.ToLower() == s.ToLower())
                            {
                                PropertyInfo prop = request.GetType().GetProperty(p);
                                var sb            = new StringBuilder(h.Value).Replace("\"", "\\\"").Append("\"");
                                sb.Insert(0, "\"");
                                var tx = new StringReader(sb.ToString());
                                var o  = deserializer.Deserialize(tx, prop.PropertyType);
                                prop.SetValue(request, o);
                                break;
                            }
                        }
                    }
                                                                                             );
                    return(new ShippingApiMethodRequest()
                    {
                        Method = method, Request = request
                    });
                }
            }
            return(null);
        }