summaryrefslogtreecommitdiff
path: root/external/aspnetwebstack/src/System.Web.Http/HttpConfiguration.cs
blob: 01de9049c7ae7cb3b421741c8cb3cdf0877f51d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.

using System.Collections.Concurrent;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http.Dependencies;
using System.Web.Http.Filters;
using System.Web.Http.ModelBinding;
using System.Web.Http.Services;

namespace System.Web.Http
{
    /// <summary>
    /// Configuration of <see cref="HttpServer"/> instances.
    /// </summary>
    public class HttpConfiguration : IDisposable
    {
        private readonly HttpRouteCollection _routes;
        private readonly ConcurrentDictionary<object, object> _properties = new ConcurrentDictionary<object, object>();
        private readonly MediaTypeFormatterCollection _formatters = DefaultFormatters();
        private readonly Collection<DelegatingHandler> _messageHandlers = new Collection<DelegatingHandler>();
        private readonly HttpFilterCollection _filters = new HttpFilterCollection();

        private IDependencyResolver _dependencyResolver = EmptyResolver.Instance;
        private bool _disposed;

        /// <summary>
        /// Initializes a new instance of the <see cref="HttpConfiguration"/> class.
        /// </summary>
        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope",
            Justification = "The route collection is disposed as part of this class.")]
        public HttpConfiguration()
            : this(new HttpRouteCollection(String.Empty))
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="HttpConfiguration"/> class.
        /// </summary>
        /// <param name="routes">The <see cref="HttpRouteCollection"/> to associate with this instance.</param>
        public HttpConfiguration(HttpRouteCollection routes)
        {
            if (routes == null)
            {
                throw Error.ArgumentNull("routes");
            }

            _routes = routes;
            Services = new DefaultServices(this);
        }

        /// <summary>
        /// Gets the list of filters that apply to all requests served using this HttpConfiguration instance.
        /// </summary>
        public HttpFilterCollection Filters
        {
            get { return _filters; }
        }

        /// <summary>
        /// Gets an ordered list of <see cref="DelegatingHandler"/> instances to be invoked as an
        /// <see cref="HttpRequestMessage"/> travels up the stack and an <see cref="HttpResponseMessage"/> travels down in
        /// stack in return. The handlers are invoked in a bottom-up fashion in the incoming path and top-down in the outgoing 
        /// path. That is, the last entry is called first for an incoming request message but invoked last for an outgoing 
        /// response message.
        /// </summary>
        /// <value>
        /// The message handler collection.
        /// </value>
        public Collection<DelegatingHandler> MessageHandlers
        {
            get { return _messageHandlers; }
        }

        /// <summary>
        /// Gets the <see cref="HttpRouteCollection"/> associated with this <see cref="HttpServer"/> instance.
        /// </summary>
        /// <value>
        /// The <see cref="HttpRouteCollection"/>.
        /// </value>
        public HttpRouteCollection Routes
        {
            get { return _routes; }
        }

        /// <summary>
        /// Gets the properties associated with this instance.
        /// </summary>
        public ConcurrentDictionary<object, object> Properties
        {
            get { return _properties; }
        }

        /// <summary>
        /// Gets the root virtual path. The <see cref="VirtualPathRoot"/> property always returns 
        /// "/" as the first character of the returned value.
        /// </summary>
        public string VirtualPathRoot
        {
            get { return _routes.VirtualPathRoot; }
        }

        /// <summary>
        /// Gets or sets the dependency resolver associated with this <see cref="HttpConfiguration"/>.
        /// </summary>
        public IDependencyResolver DependencyResolver
        {
            get { return _dependencyResolver; }
            set
            {
                if (value == null)
                {
                    throw Error.PropertyNull();
                }

                _dependencyResolver = value;
            }
        }

        /// <summary>
        /// Gets the container of default services associated with this <see cref="HttpConfiguration"/>.
        /// Only supports the list of service types documented on <see cref="DefaultServices"/>. For general
        /// purpose types, please use <see cref="DependencyResolver"/>.
        /// </summary>
        public DefaultServices Services { get; internal set; }

        /// <summary>
        /// Gets or sets a value indicating whether error details should be included in error messages.
        /// </summary>
        public IncludeErrorDetailPolicy IncludeErrorDetailPolicy { get; set; }

        /// <summary>
        /// Gets the media type formatters.
        /// </summary>
        public MediaTypeFormatterCollection Formatters
        {
            get { return _formatters; }
        }

        private static MediaTypeFormatterCollection DefaultFormatters()
        {
            var formatters = new MediaTypeFormatterCollection();

            // Basic FormUrlFormatter does not support binding to a T. 
            // Use our JQuery formatter instead.
            formatters.Add(new JQueryMvcFormUrlEncodedFormatter());

            return formatters;
        }

        internal bool ShouldIncludeErrorDetail(HttpRequestMessage request)
        {
            switch (IncludeErrorDetailPolicy)
            {
                case IncludeErrorDetailPolicy.LocalOnly:
                    Uri requestUri = request.RequestUri;
                    return requestUri.IsAbsoluteUri && requestUri.IsLoopback;

                case IncludeErrorDetailPolicy.Always:
                    return true;

                case IncludeErrorDetailPolicy.Never:
                default:
                    return false;
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                _disposed = true;
                if (disposing)
                {
                    _routes.Dispose();
                    Services.Dispose();
                    DependencyResolver.Dispose();
                }
            }
        }
    }
}