FxCop fixes.
[dotnetoauth.git] / src / DotNetOpenAuth / XrdsPublisher.cs
blobf0971a3cf773dfe9025848594ca41dea72231807
1 //-----------------------------------------------------------------------
2 // <copyright file="XrdsPublisher.cs" company="Andrew Arnott">
3 // Copyright (c) Andrew Arnott. All rights reserved.
4 // </copyright>
5 //-----------------------------------------------------------------------
7 namespace DotNetOpenAuth {
8 using System;
9 using System.Collections.Generic;
10 using System.ComponentModel;
11 using System.Diagnostics.CodeAnalysis;
12 using System.Text;
13 using System.Web;
14 using System.Web.UI;
15 using System.Web.UI.WebControls;
16 using DotNetOpenAuth.Messaging;
17 using DotNetOpenAuth.Yadis;
19 /// <summary>
20 /// The locations the YADIS protocol describes can contain a reference
21 /// to an XRDS document.
22 /// </summary>
23 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xrds", Justification = "Correct spelling")]
24 [Flags]
25 public enum XrdsUrlLocations {
26 /// <summary>
27 /// Indicates XRDS document referencing from an HTTP protocol header (outside the HTML).
28 /// </summary>
29 HttpHeader = 0x1,
31 /// <summary>
32 /// Indicates XRDS document referencing from within an HTML page's &lt;HEAD&gt; tag.
33 /// </summary>
34 HtmlMeta = 0x2,
36 /// <summary>
37 /// Indicates XRDS document referencing in both HTTP headers and HTML HEAD tags.
38 /// </summary>
39 Both = 0x3,
42 /// <summary>
43 /// An ASP.NET control that advertises an XRDS document and even responds to specially
44 /// crafted requests to retrieve it.
45 /// </summary>
46 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xrds", Justification = "Correct spelling")]
47 [DefaultProperty("XrdsLocation")]
48 [ToolboxData("<{0}:XrdsPublisher runat=server></{0}:XrdsPublisher>")]
49 public class XrdsPublisher : Control {
50 /// <summary>
51 /// The view state key to ues for storing the value of the <see cref="XrdsUrl"/> property.
52 /// </summary>
53 private const string XrdsUrlViewStateKey = "XrdsUrl";
55 /// <summary>
56 /// The default value for the <see cref="XrdsAdvertisement"/> property.
57 /// </summary>
58 private const XrdsUrlLocations XrdsAdvertisementDefault = XrdsUrlLocations.HttpHeader;
60 /// <summary>
61 /// The view state key to ues for storing the value of the <see cref="XrdsAdvertisement"/> property.
62 /// </summary>
63 private const string XrdsAdvertisementViewStateKey = "XrdsAdvertisement";
65 /// <summary>
66 /// The default value for the <see cref="XrdsAutoAnswer"/> property.
67 /// </summary>
68 private const bool XrdsAutoAnswerDefault = true;
70 /// <summary>
71 /// The view state key to ues for storing the value of the <see cref="XrdsAutoAnswer"/> property.
72 /// </summary>
73 private const string XrdsAutoAnswerViewStateKey = "XrdsAutoAnswer";
75 /// <summary>
76 /// The default value for the <see cref="Enabled"/> property.
77 /// </summary>
78 private const bool EnabledDefault = true;
80 /// <summary>
81 /// The view state key to ues for storing the value of the <see cref="Enabled"/> property.
82 /// </summary>
83 private const string EnabledViewStateKey = "Enabled";
85 #region Properties
87 /// <summary>
88 /// Gets or sets the location of the XRDS document.
89 /// </summary>
90 [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Property grid")]
91 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xrds", Justification = "Correct spelling")]
92 [Category("Behavior"), Bindable(true)]
93 public string XrdsUrl {
94 get {
95 return (string)ViewState[XrdsUrlViewStateKey];
98 set {
99 UriUtil.ValidateResolvableUrl(Page, DesignMode, value);
100 ViewState[XrdsUrlViewStateKey] = value;
104 /// <summary>
105 /// Gets or sets where the XRDS document URL is advertised in the web response.
106 /// </summary>
107 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xrds", Justification = "Correct spelling")]
108 [Category("Behavior"), DefaultValue(XrdsAdvertisementDefault), Bindable(true)]
109 [Description("Where the XRDS document URL is advertised in the web response.")]
110 public XrdsUrlLocations XrdsAdvertisement {
111 get {
112 return ViewState[XrdsAdvertisementViewStateKey] == null ?
113 XrdsAdvertisementDefault : (XrdsUrlLocations)ViewState[XrdsAdvertisementViewStateKey];
116 set {
117 ViewState[XrdsAdvertisementViewStateKey] = value;
121 /// <summary>
122 /// Gets or sets a value indicating whether a specially crafted YADIS
123 /// search for an XRDS document is immediately answered by this control.
124 /// </summary>
125 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xrds", Justification = "Correct spelling")]
126 [Category("Behavior"), DefaultValue(XrdsAutoAnswerDefault), Bindable(true)]
127 [Description("Whether XRDS requests should be immediately answered with the XRDS document if it is served by this web application.")]
128 public bool XrdsAutoAnswer {
129 get {
130 return ViewState[XrdsAutoAnswerViewStateKey] == null ?
131 XrdsAutoAnswerDefault : (bool)ViewState[XrdsAutoAnswerViewStateKey];
134 set {
135 ViewState[XrdsAutoAnswerViewStateKey] = value;
139 /// <summary>
140 /// Gets or sets a value indicating whether the XRDS document is advertised.
141 /// </summary>
142 [Category("Behavior"), DefaultValue(EnabledDefault)]
143 public bool Enabled {
144 get {
145 return ViewState[EnabledViewStateKey] == null ?
146 EnabledDefault : (bool)ViewState[EnabledViewStateKey];
149 set {
150 ViewState[EnabledViewStateKey] = value;
154 #endregion
156 /// <summary>
157 /// Detects YADIS requests for the XRDS document and responds immediately
158 /// if <see cref="XrdsAutoAnswer"/> is true.
159 /// </summary>
160 /// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
161 protected override void OnLoad(EventArgs e) {
162 base.OnLoad(e);
164 if (!this.Enabled) {
165 return;
168 if (!this.Page.IsPostBack) {
169 if (this.XrdsAutoAnswer && !string.IsNullOrEmpty(this.XrdsUrl) &&
170 this.XrdsUrl.StartsWith("~/", StringComparison.Ordinal)) {
171 // Check for the presence of an accept types header that is looking
172 // for the XRDS document specifically.
173 if (this.Page.Request.AcceptTypes != null && Array.IndexOf(this.Page.Request.AcceptTypes, ContentTypes.Xrds) >= 0) {
174 // Respond to the caller immediately with an XRDS document
175 // and avoid sending the whole web page's contents to the
176 // client since it isn't interested anyway.
177 // We do NOT simply send a 301 redirect here because that would
178 // alter the Claimed Identifier.
179 this.Page.Server.Transfer(this.XrdsUrl);
185 /// <summary>
186 /// Renders the HTTP Header and/or HTML HEAD tags.
187 /// </summary>
188 /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param>
189 protected override void Render(HtmlTextWriter writer) {
190 if (this.Enabled && this.Visible && !string.IsNullOrEmpty(this.XrdsUrl)) {
191 Uri xrdsAddress = new Uri(MessagingUtilities.GetRequestUrlFromContext(), Page.Response.ApplyAppPathModifier(this.XrdsUrl));
192 if ((this.XrdsAdvertisement & XrdsUrlLocations.HttpHeader) != 0) {
193 Page.Response.AddHeader(Yadis.Yadis.HeaderName, xrdsAddress.AbsoluteUri);
195 if ((this.XrdsAdvertisement & XrdsUrlLocations.HtmlMeta) != 0) {
196 writer.WriteBeginTag("meta");
197 writer.WriteAttribute("http-equiv", Yadis.Yadis.HeaderName);
198 writer.WriteAttribute("content", xrdsAddress.AbsoluteUri);
199 writer.Write("/>");
200 writer.WriteLine();