PageRenderTime 23ms CodeModel.GetById 13ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/WCFWebApi/src/System.Net.Http/System/Net/Http/HttpRequestMessage.cs

#
C# | 230 lines | 185 code | 34 blank | 11 comment | 35 complexity | 98581a83e5dcbd2f7477f2e70b901df8 MD5 | raw file
  1using System.Diagnostics.CodeAnalysis;
  2using System.Net.Http.Headers;
  3using System.Text;
  4using System.Threading;
  5using System.Collections.Generic;
  6
  7namespace System.Net.Http
  8{
  9    public class HttpRequestMessage : IDisposable
 10    {
 11        private const int messageAlreadySent = 1; // signals that this message was already sent. 
 12        private const int messageNotYetSent = 0;
 13
 14        // If this field is 0 (default), then the message wasn't sent by an HttpClient instance yet. If the field
 15        // value is 'messageSent', then the message was already sent and should not be sent again.
 16        private int sendStatus;
 17
 18        private HttpMethod method;
 19        private Uri requestUri;
 20        private HttpRequestHeaders headers;
 21        private Version version;
 22        private HttpContent content;
 23        private bool disposed;
 24        private IDictionary<String, Object> properties;
 25
 26        public Version Version
 27        {
 28            get { return version; }
 29            set
 30            {
 31                if (value == null)
 32                {
 33                    throw new ArgumentNullException("value");
 34                }
 35                CheckDisposed();
 36
 37                version = value;
 38            }
 39        }
 40
 41        public HttpContent Content
 42        {
 43            get { return content; }
 44            set
 45            {
 46                CheckDisposed();
 47
 48                if (Logging.On)
 49                {
 50                    if (value == null)
 51                    {
 52                        Logging.PrintInfo(Logging.Http, this, SR.net_http_log_content_null);
 53                    }
 54                    else
 55                    {
 56                        Logging.Associate(Logging.Http, this, value);
 57                    }
 58                }
 59
 60                // It's OK to set a 'null' content, even if the method is POST/PUT. We don't want to artificially
 61                // prevent scenarios by being to strict.
 62                content = value;
 63            }
 64        }
 65
 66        public HttpMethod Method
 67        {
 68            get { return method; }
 69            set
 70            {
 71                if (value == null)
 72                {
 73                    throw new ArgumentNullException("value");
 74                }
 75                CheckDisposed();
 76
 77                method = value;
 78            }
 79        }
 80
 81        public Uri RequestUri
 82        {
 83            get { return requestUri; }
 84            set
 85            {
 86                if ((value != null) && (value.IsAbsoluteUri) && (!HttpUtilities.IsHttpUri(value)))
 87                {
 88                    throw new ArgumentException(SR.net_http_client_http_baseaddress_required, "value");
 89                }
 90                CheckDisposed();
 91
 92                // It's OK to set 'null'. HttpClient will add the 'BaseAddress'. If there is no 'BaseAddress'
 93                // sending this message will throw.
 94                requestUri = value;
 95            }
 96        }
 97
 98        public HttpRequestHeaders Headers
 99        {
100            get
101            {
102                if (headers == null)
103                {
104                    headers = new HttpRequestHeaders();
105                }
106                return headers;
107            }
108        }
109
110        public IDictionary<String, Object> Properties
111        {
112            get
113            {
114                if (properties == null)
115                {
116                    properties = new Dictionary<String, Object>();
117                }
118                return properties;
119            }
120        }
121
122        public HttpRequestMessage()
123            : this(HttpMethod.Get, (Uri)null)
124        {
125        }
126
127        public HttpRequestMessage(HttpMethod method, Uri requestUri)
128        {
129            if (Logging.On) Logging.Enter(Logging.Http, this, ".ctor", "Method: " + method + ", Uri: '" + requestUri + "'");
130            InitializeValues(method, requestUri);
131            if (Logging.On) Logging.Exit(Logging.Http, this, ".ctor", null);
132        }
133
134        [SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads",
135            Justification = "It is OK to provide 'null' values. A Uri instance is created from 'requestUri' if it is != null.")]
136        public HttpRequestMessage(HttpMethod method, string requestUri)
137        {
138            if (Logging.On) Logging.Enter(Logging.Http, this, ".ctor", "Method: " + method + ", Uri: '" + requestUri + "'");
139
140            // It's OK to have a 'null' request Uri. If HttpClient is used, the 'BaseAddress' will be added.
141            // If there is no 'BaseAddress', sending this request message will throw.
142            // Note that we also allow the string to be empty: null and empty should be considered equivalent.
143            if (string.IsNullOrEmpty(requestUri))
144            {
145                InitializeValues(method, null);
146            }
147            else
148            {
149                InitializeValues(method, new Uri(requestUri, UriKind.RelativeOrAbsolute));
150            }
151
152            if (Logging.On) Logging.Exit(Logging.Http, this, ".ctor", null);
153        }
154
155        public override string ToString()
156        {
157            StringBuilder sb = new StringBuilder();
158
159            sb.Append("Method: ");
160            sb.Append(method);
161
162            sb.Append(", RequestUri: '");
163            sb.Append(requestUri == null ? "<null>" : requestUri.ToString());
164
165            sb.Append("', Version: ");
166            sb.Append(version);
167
168            sb.Append(", Content: ");
169            sb.Append(content == null ? "<null>" : content.GetType().FullName);
170
171            sb.Append(", Headers:\r\n");
172            sb.Append(HeaderUtilities.DumpHeaders(headers, content == null ? null : content.Headers));
173
174            return sb.ToString();
175        }
176
177        private void InitializeValues(HttpMethod method, Uri requestUri)
178        {
179            if (method == null)
180            {
181                throw new ArgumentNullException("method");
182            }
183            if ((requestUri != null) && (requestUri.IsAbsoluteUri) && (!HttpUtilities.IsHttpUri(requestUri)))
184            {
185                throw new ArgumentException(SR.net_http_client_http_baseaddress_required, "requestUri");
186            }
187
188            this.method = method;
189            this.requestUri = requestUri;
190            this.version = HttpUtilities.DefaultVersion;
191        }
192
193        internal bool MarkAsSent()
194        {
195            return Interlocked.Exchange(ref sendStatus, messageAlreadySent) == messageNotYetSent;
196        }
197
198        #region IDisposable Members
199
200        protected virtual void Dispose(bool disposing)
201        {
202            // The reason for this type to implement IDisposable is that it contains instances of types that implement
203            // IDisposable (content). 
204            if (disposing && !disposed)
205            {
206                disposed = true;
207                if (content != null)
208                {
209                    content.Dispose();
210                }
211            }
212        }
213
214        public void Dispose()
215        {
216            Dispose(true);
217            GC.SuppressFinalize(this);
218        }
219
220        #endregion
221
222        private void CheckDisposed()
223        {
224            if (disposed)
225            {
226                throw new ObjectDisposedException(this.GetType().FullName);
227            }
228        }
229    }
230}