/// <summary>
        /// Writes the given API response to the given HTTP context's response.
        /// </summary>
        /// <param name="context">The HTTP context whose response should be written to.</param>
        /// <param name="request">The de-serialized API request that generated the current response. May be null.</param>
        /// <param name="response">The API response to write.</param>
        /// <param name="knownTypes">A collection of known types that may exist in the response object graph.</param>
        public virtual void WriteResponse(HttpContextBase context, ApiRequest request, ApiResponse response, IEnumerable<Type> knownTypes)
        {
            string json = response.ToJson(knownTypes);
            json = Regex.Replace(json, "({)?(,)?\"__type\":\".*?\"(})?(,)?", new MatchEvaluator(TypeIdentifiersEvaluator));

            if (context.AcceptsGZip() && request != null && request.GetType().GetCustomAttributes(typeof(GZipAttribute), true).Length > 0)
            {
                context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
                context.Response.AddHeader("content-encoding", "gzip");
            }

            context.Response.ContentType = "application/json";
            context.Response.Write(json);
        }
        /// <summary>
        /// Reads a request from the given HTTP context into the given concrete type.
        /// </summary>
        /// <param name="context">The HTTP context to read the request from.</param>
        /// <param name="requestType">The concrete request type to de-serialize.</param>
        /// <param name="response">The API response to modify of something goes wrong.</param>
        /// <returns>An <see cref="ApiRequest"/>.</returns>
        public virtual ApiRequest ReadRequest(HttpContextBase context, Type requestType, ApiResponse response)
        {
            ApiRequest request = null;

            if (context.Request.InputStream != null && context.Request.InputStream.Length > 0)
            {
                request = (ApiRequest)new DataContractBinaryPlistSerializer(requestType).ReadObject(context.Request.InputStream);
            }
            else
            {
                request = (ApiRequest)Activator.CreateInstance(requestType);
            }

            return request;
        }
Beispiel #3
0
        public virtual void ProcessRequest(HttpContextBase context)
        {
            ApiRequest request = null;
            MatchedRoute route = null;
            ApiResponse response = new ApiResponse();
            Type[] knownTypes = new Type[0];

            if (RequestPassesSslCheck(context))
            {
                try
                {
                    route = this.GetRequestRoute(context);
                    request = this.GetRequestReader(context, route, readers).ReadRequest(context, route.RouteType, response);

                    // Permitted?
                    IPermission failedOn;
                    if (context.EnsurePermitted(route.RouteType, out failedOn))
                    {
                        knownTypes = route.RouteType.GetCustomAttributes(typeof(KnownTypeAttribute), true)
                            .Cast<KnownTypeAttribute>()
                            .Select(a => a.Type)
                            .ToArray();

                        ApiResult valid = request.Validate();

                        if (valid.Success)
                        {
                            // Do it.
                            ApiActionResult result = request.Do();
                            response.Success = result.Success;
                            response.Reason = result.Reason;
                            response.Value = result.Value;
                        }
                        else
                        {
                            response.Success = false;
                            response.Reason = valid.Reason;
                        }
                    }
                    else
                    {
                        response.Success = false;
                        response.Reason = "Access denied.";
                        response.Allowed = false;
                        response.StatusCode = 401;
                    }
                }
                catch (InvalidRequestTypeException ex)
                {
                    response.Success = false;
                    response.Reason = ex.Message;
                    response.StatusCode = 400;
                }
                catch (Exception ex)
                {
                    response.Success = false;
                    response.StatusCode = 500;

                    if (context.Request.IsLocal)
                    {
                        response.Reason = String.Concat(ex.Message, "\n", ex.StackTrace);
                    }
                    else
                    {
                        response.Reason = "An internal server error occurred while processing your request.";
                    }
                }
            }
            else
            {
                response.Success = false;
                response.Reason = "A secure connection is required when making this request.";
                response.StatusCode = 403;
            }

            string id = context.Request.Headers["X-Request-Id"];
            id = !String.IsNullOrEmpty(id) ? id : "0";

            context.Response.AppendHeader("X-Response-Id", id);
            context.Response.StatusCode = response.StatusCode;

            this.GetResponseWriter(context, route, writers).WriteResponse(context, request, response, knownTypes);
        }
 /// <summary>
 /// Writes the given API response to the given HTTP context's response.
 /// </summary>
 /// <param name="context">The HTTP context whose response should be written to.</param>
 /// <param name="request">The de-serialized API request that generated the current response. May be null.</param>
 /// <param name="response">The API response to write.</param>
 /// <param name="knownTypes">A collection of known types that may exist in the response object graph.</param>
 public virtual void WriteResponse(HttpContextBase context, ApiRequest request, ApiResponse response, IEnumerable<Type> knownTypes)
 {
     context.Response.ContentType = "application/x-bplist";
     new DataContractBinaryPlistSerializer(response.GetType()).WriteObject(context.Response.OutputStream, response);
 }