Summary

Class:CBAM.HTTP.HTTPTextualResponseInfo
Assembly:CBAM.HTTP
File(s):/repo-dir/contents/Source/Code/CBAM.HTTP/Connection.cs
Covered lines:20
Uncovered lines:5
Coverable lines:25
Total lines:251
Line coverage:80%
Branch coverage:66.6%

Coverage History

Metrics

MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage
.cctor()101%0%
.ctor(...)1200.947%0.667%

File(s)

/repo-dir/contents/Source/Code/CBAM.HTTP/Connection.cs

#LineLine coverage
 1/*
 2 * Copyright 2017 Stanislav Muhametsin. All rights Reserved.
 3 *
 4 * Licensed  under the  Apache License,  Version 2.0  (the "License");
 5 * you may not use  this file  except in  compliance with the License.
 6 * You may obtain a copy of the License at
 7 *
 8 *   http://www.apache.org/licenses/LICENSE-2.0
 9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed  under the  License is distributed on an "AS IS" BASIS,
 12 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
 13 * implied.
 14 *
 15 * See the License for the specific language governing permissions and
 16 * limitations under the License.
 17 */
 18using CBAM.Abstractions;
 19using CBAM.HTTP;
 20using System;
 21using System.Collections.Generic;
 22using System.Text;
 23using System.Threading.Tasks;
 24using UtilPack;
 25
 26namespace CBAM.HTTP
 27{
 28   /// <summary>
 29   /// This interface extends <see cref="Connection{TStatement, TStatementInformation, TStatementCreationArgs, TEnumerab
 30   /// </summary>
 31   /// <typeparam name="TRequestMetaData">The type of metadata associated with each request, used in identifying the req
 32   public interface HTTPConnection<TRequestMetaData> : Connection<HTTPStatement<TRequestMetaData>, HTTPStatementInformat
 33   {
 34      /// <summary>
 35      /// Gets the HTTP protocol version used by this <see cref="HTTPConnection{TRequestMetaData}"/>.
 36      /// </summary>
 37      String ProtocolVersion { get; }
 38   }
 39
 40   /// <summary>
 41   /// This interface extends <see cref="ConnectionVendorFunctionality{TStatement, TStatementCreationArgs}"/> to provide
 42   /// Currently, there are none, but there might be some in the future.
 43   /// </summary>
 44   /// <typeparam name="TRequestMetaData">The type of metadata associated with each request, used in identifying the req
 45   public interface HTTPConnectionVendorFunctionality<TRequestMetaData> : ConnectionVendorFunctionality<HTTPStatement<TR
 46   {
 47
 48   }
 49
 50   /// <summary>
 51   /// This is information associated with a single response.
 52   /// </summary>
 53   /// <typeparam name="TRequestMetaData">The type of the metadata of the request that this response is associated with.
 54   public struct HTTPResponseInfo<TRequestMetaData>
 55   {
 56      /// <summary>
 57      /// Creates a new instance of <see cref="HTTPResponseInfo{TRequestMetaData}"/> with given parameters.
 58      /// </summary>
 59      /// <param name="response">The <see cref="HTTPResponse"/>.</param>
 60      /// <param name="metadata">The metadata of the request that <paramref name="response"/> is associated with.</param
 61      /// <exception cref="ArgumentNullException">If <paramref name="response"/> is <c>null</c>.</exception>
 62      public HTTPResponseInfo(
 63         HTTPResponse response,
 64         TRequestMetaData metadata
 65         )
 66      {
 67         this.Response = ArgumentValidator.ValidateNotNull( nameof( response ), response );
 68         this.RequestMetaData = metadata;
 69      }
 70
 71      /// <summary>
 72      /// Gets the <see cref="HTTPResponse"/> of this <see cref="HTTPResponseInfo{TRequestMetaData}"/>.
 73      /// </summary>
 74      /// <value>The <see cref="HTTPResponse"/> of this <see cref="HTTPResponseInfo{TRequestMetaData}"/>.</value>
 75      public HTTPResponse Response { get; }
 76
 77      /// <summary>
 78      /// Gets the metadata of the request that <see cref="Response"/> is associated with.
 79      /// </summary>
 80      /// <value>The metadata of the request that <see cref="Response"/> is associated with.</value>
 81      public TRequestMetaData RequestMetaData { get; }
 82   }
 83
 84   /// <summary>
 85   /// This struct binds together the <see cref="HTTPRequest"/> and metadata.
 86   /// </summary>
 87   /// <typeparam name="TRequestMetaData">The type of metadata of the request. Typically this is <see cref="Guid"/> or <
 88   public struct HTTPRequestInfo<TRequestMetaData>
 89   {
 90      /// <summary>
 91      /// Creates a new instance of <see cref="HTTPRequestInfo{TRequestMetaData}"/> with given parameters.
 92      /// </summary>
 93      /// <param name="request">The <see cref="HTTPRequest"/>. May be <c>null</c>.</param>
 94      /// <param name="metadata">The metadata of the <paramref name="request"/>.</param>
 95      public HTTPRequestInfo(
 96         HTTPRequest request,
 97         TRequestMetaData metadata
 98         )
 99      {
 100         this.Request = request;
 101         this.RequestMetaData = metadata;
 102      }
 103
 104      /// <summary>
 105      /// Gets the <see cref="HTTPRequest"/> of this <see cref="HTTPRequestInfo{TRequestMetaData}"/>.
 106      /// </summary>
 107      /// <value></value>
 108      public HTTPRequest Request { get; }
 109
 110      /// <summary>
 111      /// Gets the metadata of the <see cref="Request"/>.
 112      /// </summary>
 113      /// <value>The metadata of the <see cref="Request"/>.</value>
 114      public TRequestMetaData RequestMetaData { get; }
 115   }
 116
 117   /// <summary>
 118   /// This class is meant to be used in simple situations, when the textual content of the HTTP response is meant to be
 119   /// </summary>
 120   /// <seealso cref="E_CBAM.CreateTextualResponseInfoAsync"/>
 121   public sealed class HTTPTextualResponseInfo
 122   {
 1123      private static readonly Encoding DefaultTextEncoding = new UTF8Encoding( false, false );
 124
 125      /// <summary>
 126      /// Creates a new instance of <see cref="HTTPTextualResponseInfo"/> with given parameters.
 127      /// </summary>
 128      /// <param name="response">The <see cref="HTTPResponse"/>.</param>
 129      /// <param name="content">The content of the <see cref="HTTPResponse"/>, as byte array.</param>
 130      /// <param name="defaultEncoding">The default <see cref="Encoding"/> to use if no encoding can be deduced from <se
 131      /// <exception cref="ArgumentNullException">If <paramref name="response"/> is <c>null</c>.</exception>
 2132      public HTTPTextualResponseInfo(
 2133         HTTPResponse response,
 2134         Byte[] content,
 2135         Encoding defaultEncoding
 2136         )
 137      {
 2138         ArgumentValidator.ValidateNotNull( nameof( response ), response );
 139
 2140         this.Version = response.Version;
 2141         this.StatusCode = response.StatusCode;
 2142         this.Message = response.StatusCodeMessage;
 2143         this.Headers = response.Headers;
 144         String textualContent;
 2145         if ( !content.IsNullOrEmpty() )
 146         {
 147            String cType;
 148            Int32 charsetIndex;
 149            Int32 charsetEndIdx;
 2150            var encoding = response.Headers.TryGetValue( "Content-Type", out var cTypes ) && cTypes.Count > 0 && ( chars
 2151               Encoding.GetEncoding( cType.Substring( charsetIndex + 8, ( ( charsetEndIdx = cType.IndexOf( ';', charsetI
 2152               ( defaultEncoding ?? DefaultTextEncoding );
 2153            textualContent = encoding.GetString( content, 0, content.Length );
 2154         }
 155         else
 156         {
 0157            textualContent = String.Empty;
 158         }
 2159         this.TextualContent = textualContent;
 2160      }
 161
 162      /// <summary>
 163      /// Gets the <see cref="HTTPMessage{TContent, TDictionary, TList}.Version"/> of the <see cref="HTTPResponse"/> thi
 164      /// </summary>
 165      /// <value>The <see cref="HTTPMessage{TContent, TDictionary, TList}.Version"/> of the <see cref="HTTPResponse"/> t
 0166      public String Version { get; }
 167
 168      /// <summary>
 169      /// Gets the <see cref="HTTPResponse.StatusCode"/> of the <see cref="HTTPResponse"/> this <see cref="HTTPTextualRe
 170      /// </summary>
 171      /// <value>The <see cref="HTTPResponse.StatusCode"/> of the <see cref="HTTPResponse"/> this <see cref="HTTPTextual
 0172      public Int32 StatusCode { get; }
 173
 174      /// <summary>
 175      /// Gets the <see cref="HTTPResponse.StatusCodeMessage"/> of the <see cref="HTTPResponse"/> this <see cref="HTTPTe
 176      /// </summary>
 177      /// <value>The <see cref="HTTPResponse.StatusCodeMessage"/> of the <see cref="HTTPResponse"/> this <see cref="HTTP
 0178      public String Message { get; }
 179
 180      /// <summary>
 181      /// Gets the <see cref="HTTPMessage{TContent, TDictionary, TList}.Headers"/> of the <see cref="HTTPResponse"/> thi
 182      /// </summary>
 183      /// <value>the <see cref="HTTPMessage{TContent, TDictionary, TList}.Headers"/> of the <see cref="HTTPResponse"/> t
 0184      public IReadOnlyDictionary<String, IReadOnlyList<String>> Headers { get; }
 185
 186      /// <summary>
 187      /// Gets the deserialized <see cref="HTTPResponseContent"/> as <see cref="String"/>.
 188      /// </summary>
 189      /// <value>The deserialized <see cref="HTTPResponseContent"/> as <see cref="String"/>.</value>
 2190      public String TextualContent { get; }
 191
 192
 193   }
 194
 195}
 196
 197/// <summary>
 198/// This class contains extension methods for types defined in this assembly.
 199/// </summary>
 200public static partial class E_CBAM
 201{
 202   /// <summary>
 203   /// This method will asynchronously receive one <see cref="HTTPTextualResponseInfo"/> from this <see cref="HTTPConnec
 204   /// </summary>
 205   /// <typeparam name="TRequestMetaData">The type of metadata associated with given <see cref="HTTPRequest"/>. Typicall
 206   /// <param name="connection">This <see cref="HTTPConnection{TRequestMetaData}"/>.</param>
 207   /// <param name="request">The <see cref="HTTPRequest"/> to send.</param>
 208   /// <param name="metaData">The metadata of the <paramref name="request"/>.</param>
 209   /// <param name="defaultEncoding">The default encoding to use when deserializing response contents to string. By defa
 210   /// <returns>Potentially asynchronously creates constructed <see cref="HTTPTextualResponseInfo"/>.</returns>
 211   /// <exception cref="NullReferenceException">If this <see cref="HTTPConnection{TRequestMetaData}"/> is <c>null</c>.</
 212   public static Task<HTTPTextualResponseInfo> ReceiveOneTextualResponseAsync<TRequestMetaData>(
 213      this HTTPConnection<TRequestMetaData> connection,
 214      HTTPRequest request,
 215      TRequestMetaData metaData = default,
 216      Encoding defaultEncoding = default
 217      )
 218   {
 219
 220      return connection
 221         .PrepareStatementForExecution( new HTTPRequestInfo<TRequestMetaData>( request, metaData ) )
 222         .Select( async responseInfo => await responseInfo.Response.CreateTextualResponseInfoAsync( defaultEncoding ) )
 223         .FirstAsync();
 224   }
 225
 226   /// <summary>
 227   /// Asynchronously creates <see cref="HTTPTextualResponseInfo"/> from this <see cref="HTTPResponse"/>.
 228   /// </summary>
 229   /// <param name="response">This <see cref="HTTPResponse"/>.</param>
 230   /// <param name="defaultEncoding">The <see cref="Encoding"/> to use if <see cref="HTTPResponse"/> does not contain an
 231   /// <returns>Potentially asynchronously creates constructed <see cref="HTTPTextualResponseInfo"/>.</returns>
 232   /// <exception cref="NullReferenceException">If this <see cref="HTTPResponse"/> is <c>null</c>.</exception>
 233   public static async ValueTask<HTTPTextualResponseInfo> CreateTextualResponseInfoAsync(
 234      this HTTPResponse response,
 235      Encoding defaultEncoding = default
 236      )
 237   {
 238      var content = response.Content;
 239      Byte[] bytes;
 240      if ( content != null )
 241      {
 242         bytes = await content.ReadAllContentAsync();
 243      }
 244      else
 245      {
 246         bytes = null;
 247      }
 248
 249      return new HTTPTextualResponseInfo( response, bytes, defaultEncoding );
 250   }
 251}