/// <summary> /// Submits a direct request message to some remote party and blocks waiting for an immediately reply. /// </summary> /// <param name="request">The request message.</param> /// <returns>The response message, or null if the response did not carry a message.</returns> /// <remarks> /// Typically a deriving channel will override <see cref="CreateHttpRequest"/> to customize this method's /// behavior. However in non-HTTP frameworks, such as unit test mocks, it may be appropriate to override /// this method to eliminate all use of an HTTP transport. /// </remarks> protected virtual IProtocolMessage RequestInternal(IDirectedProtocolMessage request) { HttpWebRequest webRequest = this.CreateHttpRequest(request); IDictionary <string, string> responseFields; using (DirectWebResponse response = this.GetDirectResponse(webRequest)) { if (response.ResponseStream == null) { return(null); } responseFields = this.ReadFromResponseInternal(response); } IDirectResponseProtocolMessage responseMessage = this.MessageFactory.GetNewResponseMessage(request, responseFields); if (responseMessage == null) { return(null); } var responseSerializer = MessageSerializer.Get(responseMessage.GetType()); responseSerializer.Deserialize(responseFields, responseMessage); return(responseMessage); }
/// <summary> /// Prepares to send a request to the Service Provider as the payload of a POST request. /// </summary> /// <param name="requestMessage">The message to be transmitted to the ServiceProvider.</param> /// <returns>The web request ready to send.</returns> /// <remarks> /// This method is simply a standard HTTP POST request with the message parts serialized to the POST entity /// with the application/x-www-form-urlencoded content type /// This method satisfies OAuth 1.0 section 5.2, item #2 and OpenID 2.0 section 4.1.2. /// </remarks> protected virtual HttpWebRequest InitializeRequestAsPost(IDirectedProtocolMessage requestMessage) { ErrorUtilities.VerifyArgumentNotNull(requestMessage, "requestMessage"); var serializer = MessageSerializer.Get(requestMessage.GetType()); var fields = serializer.Serialize(requestMessage); HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(requestMessage.Recipient); httpRequest.CachePolicy = this.CachePolicy; httpRequest.Method = "POST"; httpRequest.ContentType = "application/x-www-form-urlencoded"; httpRequest.Headers[HttpRequestHeader.ContentEncoding] = PostEntityEncoding.WebName; string requestBody = MessagingUtilities.CreateQueryString(fields); byte[] requestBytes = PostEntityEncoding.GetBytes(requestBody); httpRequest.ContentLength = requestBytes.Length; Stream requestStream = this.WebRequestHandler.GetRequestStream(httpRequest); try { requestStream.Write(requestBytes, 0, requestBytes.Length); } finally { // We need to be sure to close the request stream... // unless it is a MemoryStream, which is a clue that we're in // a mock stream situation and closing it would preclude reading it later. if (!(requestStream is MemoryStream)) { requestStream.Dispose(); } } return(httpRequest); }
/// <summary> /// Serializes the <see cref="DataBag"/> instance to a buffer. /// </summary> /// <param name="message">The message.</param> /// <returns>The buffer containing the serialized data.</returns> protected override byte[] SerializeCore(T message) { var fields = MessageSerializer.Get(message.GetType()).Serialize(MessageDescriptions.GetAccessor(message)); string value = MessagingUtilities.CreateQueryString(fields); return(Encoding.UTF8.GetBytes(value)); }
/// <summary> /// Deserializes the <see cref="DataBag"/> instance from a buffer. /// </summary> /// <param name="message">The message instance to initialize with data from the buffer.</param> /// <param name="data">The data buffer.</param> protected override void DeserializeCore(T message, byte[] data) { string value = Encoding.UTF8.GetString(data); // Deserialize into message newly created instance. var serializer = MessageSerializer.Get(message.GetType()); var fields = MessageDescriptions.GetAccessor(message); serializer.Deserialize(QueryHelpers.ParseQuery(value).ToDictionary(), fields); }
/// <summary> /// Prepares to send a request to the Service Provider as the query string in a GET request. /// </summary> /// <param name="requestMessage">The message to be transmitted to the ServiceProvider.</param> /// <returns>The web request ready to send.</returns> /// <remarks> /// This method is simply a standard HTTP Get request with the message parts serialized to the query string. /// This method satisfies OAuth 1.0 section 5.2, item #3. /// </remarks> protected virtual HttpWebRequest InitializeRequestAsGet(IDirectedProtocolMessage requestMessage) { ErrorUtilities.VerifyArgumentNotNull(requestMessage, "requestMessage"); var serializer = MessageSerializer.Get(requestMessage.GetType()); var fields = serializer.Serialize(requestMessage); UriBuilder builder = new UriBuilder(requestMessage.Recipient); MessagingUtilities.AppendQueryArgs(builder, fields); HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(builder.Uri); return(httpRequest); }
/// <summary> /// Queues an indirect message for transmittal via the user agent. /// </summary> /// <param name="message">The message to send.</param> /// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns> protected virtual UserAgentResponse SendIndirectMessage(IDirectedProtocolMessage message) { ErrorUtilities.VerifyArgumentNotNull(message, "message"); var serializer = MessageSerializer.Get(message.GetType()); var fields = serializer.Serialize(message); // First try creating a 301 redirect, and fallback to a form POST // if the message is too big. UserAgentResponse response = this.Create301RedirectResponse(message, fields); if (response.Headers[HttpResponseHeader.Location].Length > indirectMessageGetToPostThreshold) { response = this.CreateFormPostResponse(message, fields); } return(response); }
/// <summary> /// Deserializes a dictionary of values into a message. /// </summary> /// <param name="fields">The dictionary of values that were read from an HTTP request or response.</param> /// <param name="recipient">Information about where the message was been directed. Null for direct response messages.</param> /// <returns>The deserialized message, or null if no message could be recognized in the provided data.</returns> protected virtual IProtocolMessage Receive(Dictionary <string, string> fields, MessageReceivingEndpoint recipient) { ErrorUtilities.VerifyArgumentNotNull(fields, "fields"); IProtocolMessage message = this.MessageFactory.GetNewRequestMessage(recipient, fields); // If there was no data, or we couldn't recognize it as a message, abort. if (message == null) { return(null); } // We have a message! Assemble it. var serializer = MessageSerializer.Get(message.GetType()); serializer.Deserialize(fields, message); return(message); }