/// <summary> /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// The stream the caller should write out the entity data to. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/> /// and any other appropriate properties <i>before</i> calling this method. /// Callers <i>must</i> close and dispose of the request stream when they are done /// writing to it to avoid taking up the connection too long and causing long waits on /// subsequent requests.</para> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch.</para> /// </remarks> Stream IDirectWebRequestHandler.GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { Requires.NotNull(request, "request"); Requires.Support(((IDirectWebRequestHandler)this).CanSupport(options), MessagingStrings.DirectWebRequestOptionsNotSupported); ////ErrorUtilities.VerifySupported(((IDirectWebRequestHandler)this).CanSupport(options), string.Format(MessagingStrings.DirectWebRequestOptionsNotSupported, options, this.GetType().Name)); throw new System.NotImplementedException(); }
/// <summary> /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// The writer the caller should write out the entity data to. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/> /// and any other appropriate properties <i>before</i> calling this method.</para> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch.</para> /// </remarks> public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { ErrorUtilities.VerifyArgumentNotNull(request, "request"); ErrorUtilities.VerifySupported(this.CanSupport(options), MessagingStrings.DirectWebRequestOptionsNotSupported, options, this.GetType().Name); return(GetRequestStreamCore(request, options)); }
/// <summary> /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// The writer the caller should write out the entity data to. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/> /// and any other appropriate properties <i>before</i> calling this method.</para> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch.</para> /// </remarks> public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { ErrorUtilities.VerifyArgumentNotNull(request, "request"); ErrorUtilities.VerifySupported(this.CanSupport(options), MessagingStrings.DirectWebRequestOptionsNotSupported, options, this.GetType().Name); return GetRequestStreamCore(request); }
public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { if (this.Callback == null) { throw new InvalidOperationException("Set the Callback property first."); } return(this.Callback(request)); }
/// <summary> /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// The writer the caller should write out the entity data to. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/> /// and any other appropriate properties <i>before</i> calling this method.</para> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch.</para> /// </remarks> public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { this.EnsureAllowableRequestUri(request.RequestUri, (options & DirectWebRequestOptions.RequireSsl) != 0); this.PrepareRequest(request, true); // Submit the request and get the request stream back. return(this.chainedWebRequestHandler.GetRequestStream(request, options & ~DirectWebRequestOptions.RequireSsl)); }
/// <summary> /// Processes an <see cref="HttpWebRequest"/> and converts the /// <see cref="HttpWebResponse"/> to a <see cref="IncomingWebResponse"/> instance. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns>An instance of <see cref="IncomingWebResponse"/> describing the response.</returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch. The <see cref="WebException.Response"/> /// value, if set, should be Closed before throwing.</para> /// </remarks> public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { // If the request has an entity, the action would have already been processed in GetRequestStream. if (request.Method == "GET") { _action(request); } return(_wrappedHandler.GetResponse(request, options)); }
/// <summary> /// Initiates a POST request and prepares for sending data. /// </summary> /// <param name="request">The HTTP request with information about the remote party to contact.</param> /// <param name="options">The options to apply to this specific web request.</param> /// <returns> /// The stream where the POST entity can be written. /// </returns> private static Stream GetRequestStreamCore(HttpWebRequest request, DirectWebRequestOptions options) { PrepareRequest(request, true); try { return(request.GetRequestStream()); } catch (SocketException ex) { throw ErrorUtilities.Wrap(ex, MessagingStrings.WebRequestFailed, request.RequestUri); } catch (WebException ex) { throw ErrorUtilities.Wrap(ex, MessagingStrings.WebRequestFailed, request.RequestUri); } }
/// <summary> /// Processes an <see cref="HttpWebRequest"/> and converts the /// <see cref="HttpWebResponse"/> to a <see cref="IncomingWebResponse"/> instance. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// An instance of <see cref="IncomingWebResponse"/> describing the response. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch. The <see cref="WebException.Response"/> /// value, if set, should be Closed before throwing.</para> /// </remarks> public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { // This request MAY have already been prepared by GetRequestStream, but // we have no guarantee, so do it just to be safe. PrepareRequest(request, false); try { HttpWebResponse response = (HttpWebResponse)request.GetResponse(); return(new NetworkDirectWebResponse(request.RequestUri, response)); } catch (WebException ex) { HttpWebResponse response = (HttpWebResponse)ex.Response; if (response != null && response.StatusCode == HttpStatusCode.ExpectationFailed && request.ServicePoint.Expect100Continue) { // Some OpenID servers doesn't understand the Expect header and send 417 error back. // If this server just failed from that, alter the ServicePoint for this server // so that we don't send that header again next time (whenever that is). // "Expect: 100-Continue" HTTP header. (see Google Code Issue 72) // We don't want to blindly set all ServicePoints to not use the Expect header // as that would be a security hole allowing any visitor to a web site change // the web site's global behavior when calling that host. request.ServicePoint.Expect100Continue = false; // TODO: investigate that CAS may throw here // An alternative to ServicePoint if we don't have permission to set that, // but we'd have to set it BEFORE each request. ////request.Expect = ""; } if ((options & DirectWebRequestOptions.AcceptAllHttpResponses) != 0 && response != null && response.StatusCode != HttpStatusCode.ExpectationFailed) { return(new NetworkDirectWebResponse(request.RequestUri, response)); } // Be sure to close the response stream to conserve resources and avoid // filling up all our incoming pipes and denying future requests. // If in the future, some callers actually want to read this response // we'll need to figure out how to reliably call Close on exception // responses at all callers. if (response != null) { response.Close(); } throw ErrorUtilities.Wrap(ex, MessagingStrings.ErrorInRequestReplyMessage); } }
public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { // This request MAY have already been prepared by GetRequestStream, but // we have no guarantee, so do it just to be safe. this.PrepareRequest(request, false); // Since we may require SSL for every redirect, we handle each redirect manually // in order to detect and fail if any redirect sends us to an HTTP url. // We COULD allow automatic redirect in the cases where HTTPS is not required, // but our mock request infrastructure can't do redirects on its own either. Uri originalRequestUri = request.RequestUri; int i; for (i = 0; i < this.MaximumRedirections; i++) { this.EnsureAllowableRequestUri(request.RequestUri, (options & DirectWebRequestOptions.RequireSsl) != 0); CachedDirectWebResponse response = this.chainedWebRequestHandler.GetResponse(request, options & ~DirectWebRequestOptions.RequireSsl).GetSnapshot(this.MaximumBytesToRead); if (response.Status == HttpStatusCode.MovedPermanently || response.Status == HttpStatusCode.Redirect || response.Status == HttpStatusCode.RedirectMethod || response.Status == HttpStatusCode.RedirectKeepVerb) { // We have no copy of the post entity stream to repeat on our manually // cloned HttpWebRequest, so we have to bail. ErrorUtilities.VerifyProtocol(request.Method != "POST", MessagingStrings.UntrustedRedirectsOnPOSTNotSupported); Uri redirectUri = new Uri(response.FinalUri, response.Headers[HttpResponseHeader.Location]); request = request.Clone(redirectUri); } else { if (response.FinalUri != request.RequestUri) { // Since we don't automatically follow redirects, there's only one scenario where this // can happen: when the server sends a (non-redirecting) Content-Location header in the response. // It's imperative that we do not trust that header though, so coerce the FinalUri to be // what we just requested. Logger.Http.WarnFormat("The response from {0} included an HTTP header indicating it's the same as {1}, but it's not a redirect so we won't trust that.", request.RequestUri, response.FinalUri); response.FinalUri = request.RequestUri; } return(response); } } throw ErrorUtilities.ThrowProtocol(MessagingStrings.TooManyRedirects, originalRequestUri); }
/// <summary> /// Sends a YADIS HTTP request as part of identifier discovery. /// </summary> /// <param name="requestHandler">The request handler to use to actually submit the request.</param> /// <param name="uri">The URI to GET.</param> /// <param name="requireSsl">Whether only HTTPS URLs should ever be retrieved.</param> /// <param name="acceptTypes">The value of the Accept HTTP header to include in the request.</param> /// <returns>The HTTP response retrieved from the request.</returns> internal static IncomingWebResponse Request(IDirectWebRequestHandler requestHandler, Uri uri, bool requireSsl, params string[] acceptTypes) { Contract.Requires <ArgumentNullException>(requestHandler != null); Contract.Requires <ArgumentNullException>(uri != null); Contract.Ensures(Contract.Result <IncomingWebResponse>() != null); Contract.Ensures(Contract.Result <IncomingWebResponse>().ResponseStream != null); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); request.CachePolicy = IdentifierDiscoveryCachePolicy; if (acceptTypes != null) { request.Accept = string.Join(",", acceptTypes); } DirectWebRequestOptions options = DirectWebRequestOptions.None; if (requireSsl) { options |= DirectWebRequestOptions.RequireSsl; } try { return(requestHandler.GetResponse(request, options)); } catch (ProtocolException ex) { var webException = ex.InnerException as WebException; if (webException != null) { var response = webException.Response as HttpWebResponse; if (response != null && response.IsFromCache) { // We don't want to report error responses from the cache, since the server may have fixed // whatever was causing the problem. So try again with cache disabled. Logger.Messaging.Error("An HTTP error response was obtained from the cache. Retrying with cache disabled.", ex); var nonCachingRequest = request.Clone(); nonCachingRequest.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Reload); return(requestHandler.GetResponse(nonCachingRequest, options)); } } throw; } }
/// <summary> /// Sends a YADIS HTTP request as part of identifier discovery. /// </summary> /// <param name="requestHandler">The request handler to use to actually submit the request.</param> /// <param name="uri">The URI to GET.</param> /// <param name="requireSsl">Whether only HTTPS URLs should ever be retrieved.</param> /// <param name="acceptTypes">The value of the Accept HTTP header to include in the request.</param> /// <returns>The HTTP response retrieved from the request.</returns> internal static DirectWebResponse Request(IDirectWebRequestHandler requestHandler, Uri uri, bool requireSsl, params string[] acceptTypes) { ErrorUtilities.VerifyArgumentNotNull(requestHandler, "requestHandler"); ErrorUtilities.VerifyArgumentNotNull(uri, "uri"); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); request.CachePolicy = IdentifierDiscoveryCachePolicy; if (acceptTypes != null) { request.Accept = string.Join(",", acceptTypes); } DirectWebRequestOptions options = DirectWebRequestOptions.None; if (requireSsl) { options |= DirectWebRequestOptions.RequireSsl; } return(requestHandler.GetResponse(request, options)); }
public DirectWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { ErrorUtilities.VerifyArgumentNotNull(request, "request"); // This request MAY have already been prepared by GetRequestStream, but // we have no guarantee, so do it just to be safe. this.PrepareRequest(request, false); // Since we may require SSL for every redirect, we handle each redirect manually // in order to detect and fail if any redirect sends us to an HTTP url. // We COULD allow automatic redirect in the cases where HTTPS is not required, // but our mock request infrastructure can't do redirects on its own either. Uri originalRequestUri = request.RequestUri; int i; for (i = 0; i < this.MaximumRedirections; i++) { this.EnsureAllowableRequestUri(request.RequestUri, (options & DirectWebRequestOptions.RequireSsl) != 0); CachedDirectWebResponse response = this.chainedWebRequestHandler.GetResponse(request, options & ~DirectWebRequestOptions.RequireSsl).GetSnapshot(this.MaximumBytesToRead); if (response.Status == HttpStatusCode.MovedPermanently || response.Status == HttpStatusCode.Redirect || response.Status == HttpStatusCode.RedirectMethod || response.Status == HttpStatusCode.RedirectKeepVerb) { // We have no copy of the post entity stream to repeat on our manually // cloned HttpWebRequest, so we have to bail. ErrorUtilities.VerifyProtocol(request.Method != "POST", MessagingStrings.UntrustedRedirectsOnPOSTNotSupported); Uri redirectUri = new Uri(response.FinalUri, response.Headers[HttpResponseHeader.Location]); request = request.Clone(redirectUri); } else { return(response); } } throw ErrorUtilities.ThrowProtocol(MessagingStrings.TooManyRedirects, originalRequestUri); }
/// <summary> /// Sends a YADIS HTTP request as part of identifier discovery. /// </summary> /// <param name="requestHandler">The request handler to use to actually submit the request.</param> /// <param name="uri">The URI to GET.</param> /// <param name="requireSsl">Whether only HTTPS URLs should ever be retrieved.</param> /// <param name="acceptTypes">The value of the Accept HTTP header to include in the request.</param> /// <returns>The HTTP response retrieved from the request.</returns> internal static IncomingWebResponse Request(IDirectWebRequestHandler requestHandler, Uri uri, bool requireSsl, params string[] acceptTypes) { Contract.Requires <ArgumentNullException>(requestHandler != null); Contract.Requires <ArgumentNullException>(uri != null); Contract.Ensures(Contract.Result <IncomingWebResponse>() != null); Contract.Ensures(Contract.Result <IncomingWebResponse>().ResponseStream != null); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); request.CachePolicy = IdentifierDiscoveryCachePolicy; if (acceptTypes != null) { request.Accept = string.Join(",", acceptTypes); } DirectWebRequestOptions options = DirectWebRequestOptions.None; if (requireSsl) { options |= DirectWebRequestOptions.RequireSsl; } return(requestHandler.GetResponse(request, options)); }
/// <summary> /// Processes an <see cref="HttpWebRequest"/> and converts the /// <see cref="HttpWebResponse"/> to a <see cref="IncomingWebResponse"/> instance. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// An instance of <see cref="IncomingWebResponse"/> describing the response. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch. The <see cref="WebException.Response"/> /// value, if set, should be Closed before throwing. /// </remarks> IncomingWebResponse IDirectWebRequestHandler.GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { Requires.NotNull(request, "request"); Contract.Ensures(Contract.Result<IncomingWebResponse>() != null); Contract.Ensures(Contract.Result<IncomingWebResponse>().ResponseStream != null); Requires.Support(((IDirectWebRequestHandler)this).CanSupport(options), MessagingStrings.DirectWebRequestOptionsNotSupported); ////ErrorUtilities.VerifySupported(((IDirectWebRequestHandler)this).CanSupport(options), string.Format(MessagingStrings.DirectWebRequestOptionsNotSupported, options, this.GetType().Name)); throw new System.NotImplementedException(); }
public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { if (this.Callback == null) { throw new InvalidOperationException("Set the Callback property first."); } return this.Callback(request); }
/// <summary> /// Processes an <see cref="HttpWebRequest"/> and converts the /// <see cref="HttpWebResponse"/> to a <see cref="IncomingWebResponse"/> instance. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// An instance of <see cref="IncomingWebResponse"/> describing the response. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch. The <see cref="WebException.Response"/> /// value, if set, should be Closed before throwing.</para> /// </remarks> public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { // This request MAY have already been prepared by GetRequestStream, but // we have no guarantee, so do it just to be safe. PrepareRequest(request, false); try { Logger.Http.DebugFormat("HTTP {0} {1}", request.Method, request.RequestUri); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); return(new NetworkDirectWebResponse(request.RequestUri, response)); } catch (WebException ex) { HttpWebResponse response = (HttpWebResponse)ex.Response; if (response != null && response.StatusCode == HttpStatusCode.ExpectationFailed && request.ServicePoint.Expect100Continue) { // Some OpenID servers doesn't understand the Expect header and send 417 error back. // If this server just failed from that, alter the ServicePoint for this server // so that we don't send that header again next time (whenever that is). // "Expect: 100-Continue" HTTP header. (see Google Code Issue 72) // We don't want to blindly set all ServicePoints to not use the Expect header // as that would be a security hole allowing any visitor to a web site change // the web site's global behavior when calling that host. Logger.Http.InfoFormat("HTTP POST to {0} resulted in 417 Expectation Failed. Changing ServicePoint to not use Expect: Continue next time.", request.RequestUri); request.ServicePoint.Expect100Continue = false; // TODO: investigate that CAS may throw here // An alternative to ServicePoint if we don't have permission to set that, // but we'd have to set it BEFORE each request. ////request.Expect = ""; } if ((options & DirectWebRequestOptions.AcceptAllHttpResponses) != 0 && response != null && response.StatusCode != HttpStatusCode.ExpectationFailed) { Logger.Http.InfoFormat("The HTTP error code {0} {1} is being accepted because the {2} flag is set.", (int)response.StatusCode, response.StatusCode, DirectWebRequestOptions.AcceptAllHttpResponses); return(new NetworkDirectWebResponse(request.RequestUri, response)); } if (Logger.Http.IsErrorEnabled) { if (response != null) { using (var reader = new StreamReader(ex.Response.GetResponseStream())) { Logger.Http.ErrorFormat("WebException from {0}: {1}{2}", ex.Response.ResponseUri, Environment.NewLine, reader.ReadToEnd()); } } else { Logger.Http.ErrorFormat("WebException {1} from {0}, no response available.", request.RequestUri, ex.Status); } } // Be sure to close the response stream to conserve resources and avoid // filling up all our incoming pipes and denying future requests. // If in the future, some callers actually want to read this response // we'll need to figure out how to reliably call Close on exception // responses at all callers. if (response != null) { response.Close(); } throw ErrorUtilities.Wrap(ex, MessagingStrings.ErrorInRequestReplyMessage); } }
public bool CanSupport(DirectWebRequestOptions options) { // We support whatever our chained handler supports, plus RequireSsl. return(this.chainedWebRequestHandler.CanSupport(options & ~DirectWebRequestOptions.RequireSsl)); }
/// <summary> /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// The writer the caller should write out the entity data to. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/> /// and any other appropriate properties <i>before</i> calling this method.</para> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch.</para> /// </remarks> public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { ErrorUtilities.VerifyArgumentNotNull(request, "request"); this.EnsureAllowableRequestUri(request.RequestUri, (options & DirectWebRequestOptions.RequireSsl) != 0); this.PrepareRequest(request, true); // Submit the request and get the request stream back. return this.chainedWebRequestHandler.GetRequestStream(request, options & ~DirectWebRequestOptions.RequireSsl); }
/// <summary> /// Processes an <see cref="HttpWebRequest"/> and converts the /// <see cref="HttpWebResponse"/> to a <see cref="IncomingWebResponse"/> instance. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// An instance of <see cref="IncomingWebResponse"/> describing the response. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch. The <see cref="WebException.Response"/> /// value, if set, should be Closed before throwing. /// </remarks> IncomingWebResponse IDirectWebRequestHandler.GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { Requires.NotNull(request, "request"); Contract.Ensures(Contract.Result <IncomingWebResponse>() != null); Contract.Ensures(Contract.Result <IncomingWebResponse>().ResponseStream != null); Requires.Support(((IDirectWebRequestHandler)this).CanSupport(options), MessagingStrings.DirectWebRequestOptionsNotSupported); ////ErrorUtilities.VerifySupported(((IDirectWebRequestHandler)this).CanSupport(options), string.Format(MessagingStrings.DirectWebRequestOptionsNotSupported, options, this.GetType().Name)); throw new System.NotImplementedException(); }
/// <summary> /// Processes an <see cref="HttpWebRequest"/> and converts the /// <see cref="HttpWebResponse"/> to a <see cref="IncomingWebResponse"/> instance. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns>An instance of <see cref="IncomingWebResponse"/> describing the response.</returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch. The <see cref="WebException.Response"/> /// value, if set, should be Closed before throwing.</para> /// </remarks> public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { // If the request has an entity, the action would have already been processed in GetRequestStream. if (request.Method == "GET") { this.action(request); } return this.wrappedHandler.GetResponse(request, options); }
/// <summary> /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// The stream the caller should write out the entity data to. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/> /// and any other appropriate properties <i>before</i> calling this method. /// Callers <i>must</i> close and dispose of the request stream when they are done /// writing to it to avoid taking up the connection too long and causing long waits on /// subsequent requests.</para> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch.</para> /// </remarks> public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { this.action(request); return this.wrappedHandler.GetRequestStream(request, options); }
/// <summary> /// Determines whether this instance can support the specified options. /// </summary> /// <param name="options">The set of options that might be given in a subsequent web request.</param> /// <returns> /// <c>true</c> if this instance can support the specified options; otherwise, <c>false</c>. /// </returns> public bool CanSupport(DirectWebRequestOptions options) { return this.wrappedHandler.CanSupport(options); }
public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { // This request MAY have already been prepared by GetRequestStream, but // we have no guarantee, so do it just to be safe. this.PrepareRequest(request, false); // Since we may require SSL for every redirect, we handle each redirect manually // in order to detect and fail if any redirect sends us to an HTTP url. // We COULD allow automatic redirect in the cases where HTTPS is not required, // but our mock request infrastructure can't do redirects on its own either. Uri originalRequestUri = request.RequestUri; int i; for (i = 0; i < this.MaximumRedirections; i++) { this.EnsureAllowableRequestUri(request.RequestUri, (options & DirectWebRequestOptions.RequireSsl) != 0); CachedDirectWebResponse response = this.chainedWebRequestHandler.GetResponse(request, options & ~DirectWebRequestOptions.RequireSsl).GetSnapshot(this.MaximumBytesToRead); if (response.Status == HttpStatusCode.MovedPermanently || response.Status == HttpStatusCode.Redirect || response.Status == HttpStatusCode.RedirectMethod || response.Status == HttpStatusCode.RedirectKeepVerb) { // We have no copy of the post entity stream to repeat on our manually // cloned HttpWebRequest, so we have to bail. ErrorUtilities.VerifyProtocol(request.Method != "POST", MessagingStrings.UntrustedRedirectsOnPOSTNotSupported); Uri redirectUri = new Uri(response.FinalUri, response.Headers[HttpResponseHeader.Location]); request = request.Clone(redirectUri); } else { if (response.FinalUri != request.RequestUri) { // Since we don't automatically follow redirects, there's only one scenario where this // can happen: when the server sends a (non-redirecting) Content-Location header in the response. // It's imperative that we do not trust that header though, so coerce the FinalUri to be // what we just requested. Logger.Http.WarnFormat("The response from {0} included an HTTP header indicating it's the same as {1}, but it's not a redirect so we won't trust that.", request.RequestUri, response.FinalUri); response.FinalUri = request.RequestUri; } return response; } } throw ErrorUtilities.ThrowProtocol(MessagingStrings.TooManyRedirects, originalRequestUri); }
/// <summary> /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// The writer the caller should write out the entity data to. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/> /// and any other appropriate properties <i>before</i> calling this method.</para> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch.</para> /// </remarks> public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { this.EnsureAllowableRequestUri(request.RequestUri, (options & DirectWebRequestOptions.RequireSsl) != 0); this.PrepareRequest(request, true); // Submit the request and get the request stream back. return this.chainedWebRequestHandler.GetRequestStream(request, options & ~DirectWebRequestOptions.RequireSsl); }
public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { this.postEntity = new MemoryStream(); return this.postEntity; }
public bool CanSupport(DirectWebRequestOptions options) { return options == DirectWebRequestOptions.None; }
/// <summary> /// Determines whether this instance can support the specified options. /// </summary> /// <param name="options">The set of options that might be given in a subsequent web request.</param> /// <returns> /// <c>true</c> if this instance can support the specified options; otherwise, <c>false</c>. /// </returns> bool IDirectWebRequestHandler.CanSupport(DirectWebRequestOptions options) { throw new System.NotImplementedException(); }
/// <summary> /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// The writer the caller should write out the entity data to. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/> /// and any other appropriate properties <i>before</i> calling this method.</para> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch.</para> /// </remarks> public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { return(GetRequestStreamCore(request)); }
public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { return(_webRequestHandler.GetRequestStream(request, options)); }
/// <summary> /// Determines whether this instance can support the specified options. /// </summary> /// <param name="options">The set of options that might be given in a subsequent web request.</param> /// <returns> /// <c>true</c> if this instance can support the specified options; otherwise, <c>false</c>. /// </returns> public bool CanSupport(DirectWebRequestOptions options) { // We support whatever our chained handler supports, plus RequireSsl. return this.chainedWebRequestHandler.CanSupport(options & ~DirectWebRequestOptions.RequireSsl); }
/// <summary> /// Processes an <see cref="HttpWebRequest"/> and converts the /// <see cref="HttpWebResponse"/> to a <see cref="IncomingWebResponse"/> instance. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// An instance of <see cref="IncomingWebResponse"/> describing the response. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch. The <see cref="WebException.Response"/> /// value, if set, should be Closed before throwing.</para> /// </remarks> public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { // This request MAY have already been prepared by GetRequestStream, but // we have no guarantee, so do it just to be safe. PrepareRequest(request, false); try { Logger.Http.DebugFormat("HTTP {0} {1}", request.Method, request.RequestUri); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); return new NetworkDirectWebResponse(request.RequestUri, response); } catch (WebException ex) { HttpWebResponse response = (HttpWebResponse)ex.Response; if (response != null && response.StatusCode == HttpStatusCode.ExpectationFailed && request.ServicePoint.Expect100Continue) { // Some OpenID servers doesn't understand the Expect header and send 417 error back. // If this server just failed from that, alter the ServicePoint for this server // so that we don't send that header again next time (whenever that is). // "Expect: 100-Continue" HTTP header. (see Google Code Issue 72) // We don't want to blindly set all ServicePoints to not use the Expect header // as that would be a security hole allowing any visitor to a web site change // the web site's global behavior when calling that host. Logger.Http.InfoFormat("HTTP POST to {0} resulted in 417 Expectation Failed. Changing ServicePoint to not use Expect: Continue next time.", request.RequestUri); request.ServicePoint.Expect100Continue = false; // TODO: investigate that CAS may throw here // An alternative to ServicePoint if we don't have permission to set that, // but we'd have to set it BEFORE each request. ////request.Expect = ""; } if ((options & DirectWebRequestOptions.AcceptAllHttpResponses) != 0 && response != null && response.StatusCode != HttpStatusCode.ExpectationFailed) { Logger.Http.InfoFormat("The HTTP error code {0} {1} is being accepted because the {2} flag is set.", (int)response.StatusCode, response.StatusCode, DirectWebRequestOptions.AcceptAllHttpResponses); return new NetworkDirectWebResponse(request.RequestUri, response); } if (Logger.Http.IsErrorEnabled) { if (response != null) { using (var reader = new StreamReader(ex.Response.GetResponseStream())) { Logger.Http.ErrorFormat("WebException from {0}: {1}{2}", ex.Response.ResponseUri, Environment.NewLine, reader.ReadToEnd()); } } else { Logger.Http.ErrorFormat("WebException {1} from {0}, no response available.", request.RequestUri, ex.Status); } } // Be sure to close the response stream to conserve resources and avoid // filling up all our incoming pipes and denying future requests. // If in the future, some callers actually want to read this response // we'll need to figure out how to reliably call Close on exception // responses at all callers. if (response != null) { response.Close(); } throw ErrorUtilities.Wrap(ex, MessagingStrings.ErrorInRequestReplyMessage); } }
public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { ErrorUtilities.VerifyArgumentNotNull(request, "request"); // This request MAY have already been prepared by GetRequestStream, but // we have no guarantee, so do it just to be safe. this.PrepareRequest(request, false); // Since we may require SSL for every redirect, we handle each redirect manually // in order to detect and fail if any redirect sends us to an HTTP url. // We COULD allow automatic redirect in the cases where HTTPS is not required, // but our mock request infrastructure can't do redirects on its own either. Uri originalRequestUri = request.RequestUri; int i; for (i = 0; i < this.MaximumRedirections; i++) { this.EnsureAllowableRequestUri(request.RequestUri, (options & DirectWebRequestOptions.RequireSsl) != 0); CachedDirectWebResponse response = this.chainedWebRequestHandler.GetResponse(request, options & ~DirectWebRequestOptions.RequireSsl).GetSnapshot(this.MaximumBytesToRead); if (response.Status == HttpStatusCode.MovedPermanently || response.Status == HttpStatusCode.Redirect || response.Status == HttpStatusCode.RedirectMethod || response.Status == HttpStatusCode.RedirectKeepVerb) { // We have no copy of the post entity stream to repeat on our manually // cloned HttpWebRequest, so we have to bail. ErrorUtilities.VerifyProtocol(request.Method != "POST", MessagingStrings.UntrustedRedirectsOnPOSTNotSupported); Uri redirectUri = new Uri(response.FinalUri, response.Headers[HttpResponseHeader.Location]); request = request.Clone(redirectUri); } else { return response; } } throw ErrorUtilities.ThrowProtocol(MessagingStrings.TooManyRedirects, originalRequestUri); }
/// <summary> /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// The writer the caller should write out the entity data to. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/> /// and any other appropriate properties <i>before</i> calling this method.</para> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch.</para> /// </remarks> public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { return GetRequestStreamCore(request); }
public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { return(_webRequestHandler.GetResponse(request, options)); }
/// <summary> /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity. /// </summary> /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param> /// <param name="options">The options to apply to this web request.</param> /// <returns> /// The stream the caller should write out the entity data to. /// </returns> /// <exception cref="ProtocolException">Thrown for any network error.</exception> /// <remarks> /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/> /// and any other appropriate properties <i>before</i> calling this method. /// Callers <i>must</i> close and dispose of the request stream when they are done /// writing to it to avoid taking up the connection too long and causing long waits on /// subsequent requests.</para> /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a /// <see cref="ProtocolException"/> to abstract away the transport and provide /// a single exception type for hosts to catch.</para> /// </remarks> public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { _action(request); return(_wrappedHandler.GetRequestStream(request, options)); }
public bool CanSupport(DirectWebRequestOptions options) { return((options & ~SupportedOptions) == 0); }
public bool CanSupport(DirectWebRequestOptions options) { return true; }
public bool CanSupport(DirectWebRequestOptions options) { return (options & ~SupportedOptions) == 0; }
/// <summary> /// Determines whether this instance can support the specified options. /// </summary> /// <param name="options">The set of options that might be given in a subsequent web request.</param> /// <returns> /// <c>true</c> if this instance can support the specified options; otherwise, <c>false</c>. /// </returns> public bool CanSupport(DirectWebRequestOptions options) { return(_wrappedHandler.CanSupport(options)); }
public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { this.postEntity = new MemoryStream(); return(this.postEntity); }
public bool CanSupport(DirectWebRequestOptions options) { return(true); }