<commit_before>﻿/*
Copyright 2013 Google Inc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using Google.Apis.Logging;
using Google.Apis.Testing;

namespace Google.Apis.Http
{
    /// <summary>
    /// A message handler which contains the main logic of our HTTP requests. It contains a list of 
    /// <see cref="IHttpUnsuccessfulResponseHandler"/>s for handling abnormal responses, a list of 
    /// <see cref="IHttpExceptionHandler"/>s for handling exception in a request and a list of 
    /// <see cref="IHttpExecuteInterceptor"/>s for intercepting a request before it has been sent to the server.
    /// It also contains important properties like number of tries, follow redirect, etc.
    /// </summary>
    public class ConfigurableMessageHandler : DelegatingHandler
    {
        /// <summary>The class logger.</summary>
        private static readonly ILogger Logger = ApplicationContext.Logger.ForType<ConfigurableMessageHandler>();

        /// <summary>Maximum allowed number of tries.</summary>
        [VisibleForTestOnly]
        public const int MaxAllowedNumTries = 20;

        /// <summary>The current API version of this client library.</summary>
        private static readonly string ApiVersion = Google.Apis.Util.Utilities.GetLibraryVersion();

        /// <summary>The User-Agent suffix header which contains the <see cref="ApiVersion"/>.</summary>
        private static readonly string UserAgentSuffix = "google-api-dotnet-client/" + ApiVersion + " (gzip)";

        #region IHttpUnsuccessfulResponseHandler, IHttpExceptionHandler and IHttpExecuteInterceptor lists

        #region Lock objects

        // The following lock objects are used to lock the list of handlers and interceptors in order to be able to
        // iterate over them from several threads and to keep this class thread-safe.
        private readonly object unsuccessfulResponseHandlersLock = new object();
        private readonly object exceptionHandlersLock = new object();
        private readonly object executeInterceptorsLock = new object();

        #endregion

        /// <summary>A list of <see cref="IHttpUnsuccessfulResponseHandler"/>.</summary>
        private readonly IList<IHttpUnsuccessfulResponseHandler> unsuccessfulResponseHandlers =
            new List<IHttpUnsuccessfulResponseHandler>();

        /// <summary>A list of <see cref="IHttpExceptionHandler"/>.</summary>
        private readonly IList<IHttpExceptionHandler> exceptionHandlers =
            new List<IHttpExceptionHandler>();

        /// <summary>A list of <see cref="IHttpExecuteInterceptor"/>.</summary>
        private readonly IList<IHttpExecuteInterceptor> executeInterceptors =
            new List<IHttpExecuteInterceptor>();

        /// <summary>
        /// Gets a copied list of <see cref="IHttpUnsuccessfulResponseHandler"/>.
        /// <remarks>
        /// Since version 1.10, the return value had been changed from <c>IList</c> to <c>IEnumerable</c> in order to
        /// keep this class thread-safe. The returned list is also a copied version of the handlers. More info is
        /// available on <a href="https://github.com/google/google-api-dotnet-client/issues/592">Issue 592</a>.
        /// </remarks>
        /// </summary>
        public IEnumerable<IHttpUnsuccessfulResponseHandler> UnsuccessfulResponseHandlers
        {
            get
            {
                lock (unsuccessfulResponseHandlersLock)
                {
                    return unsuccessfulResponseHandlers.ToList();
                }
            }
        }

        /// <summary>Adds the specified handler to the list of unsuccessful response handlers.</summary>
        public void AddUnsuccessfulResponseHandler(IHttpUnsuccessfulResponseHandler handler)
        {
            lock (unsuccessfulResponseHandlersLock)
            {
                unsuccessfulResponseHandlers.Add(handler);
            }
        }

        /// <summary>Removes the specified handler from the list of unsuccessful response handlers.</summary>
        public void RemoveUnsuccessfulResponseHandler(IHttpUnsuccessfulResponseHandler handler)
        {
            lock (unsuccessfulResponseHandlersLock)
            {
                unsuccessfulResponseHandlers.Remove(handler);
            }
        }

        /// <summary>
        /// Gets a list of <see cref="IHttpExceptionHandler"/>.
        /// <remarks>
        /// Since version 1.10, the return value had been changed from <c>IList</c> to <c>IEnumerable</c> in order to
        /// keep this class thread-safe. The returned list is also a copied version of the handlers. More info is
        /// available on <a href="https://github.com/google/google-api-dotnet-client/issues/592">Issue 592</a>.
        /// </remarks>
        /// </summary>
        public IEnumerable<IHttpExceptionHandler> ExceptionHandlers
        {
            get
            {
                lock (exceptionHandlersLock)
                {
                    return exceptionHandlers.ToList();
                }
            }
        }

        /// <summary>Adds the specified handler to the list of exception handlers.</summary>
        public void AddExceptionHandler(IHttpExceptionHandler handler)
        {
            lock (exceptionHandlersLock)
            {
                exceptionHandlers.Add(handler);
            }
        }

        /// <summary>Removes the specified handler from the list of exception handlers.</summary>
        public void RemoveExceptionHandler(IHttpExceptionHandler handler)
        {
            lock (exceptionHandlersLock)
            {
                exceptionHandlers.Remove(handler);
            }
        }

        /// <summary>
        /// Gets a list of <see cref="IHttpExecuteInterceptor"/>.
        /// <remarks>
        /// Since version 1.10, the return value had been changed from <c>IList</c> to <c>IEnumerable</c> in order to
        /// keep this class thread-safe. The returned list is also a copied version of the interceptors. More info is
        /// available on <a href="https://github.com/google/google-api-dotnet-client/issues/592">Issue 592</a>.
        /// </remarks>
        /// </summary>
        public IEnumerable<IHttpExecuteInterceptor> ExecuteInterceptors
        {
            get
            {
                lock (executeInterceptorsLock)
                {
                    return executeInterceptors.ToList();
                }
            }
        }

        /// <summary>Adds the specified interceptor to the list of execute interceptors.</summary>
        public void AddExecuteInterceptor(IHttpExecuteInterceptor interceptor)
        {
            lock (executeInterceptorsLock)
            {
                executeInterceptors.Add(interceptor);
            }
        }

        /// <summary>Removes the specified interceptor from the list of execute interceptors.</summary>
        public void RemoveExecuteInterceptor(IHttpExecuteInterceptor interceptor)
        {
            lock (executeInterceptorsLock)
            {
                executeInterceptors.Remove(interceptor);
            }
        }<commit_msg>Improve comments of the enumerable getters<commit_after>﻿/*
Copyright 2013 Google Inc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using Google.Apis.Logging;
using Google.Apis.Testing;

namespace Google.Apis.Http
{
    /// <summary>
    /// A message handler which contains the main logic of our HTTP requests. It contains a list of 
    /// <see cref="IHttpUnsuccessfulResponseHandler"/>s for handling abnormal responses, a list of 
    /// <see cref="IHttpExceptionHandler"/>s for handling exception in a request and a list of 
    /// <see cref="IHttpExecuteInterceptor"/>s for intercepting a request before it has been sent to the server.
    /// It also contains important properties like number of tries, follow redirect, etc.
    /// </summary>
    public class ConfigurableMessageHandler : DelegatingHandler
    {
        /// <summary>The class logger.</summary>
        private static readonly ILogger Logger = ApplicationContext.Logger.ForType<ConfigurableMessageHandler>();

        /// <summary>Maximum allowed number of tries.</summary>
        [VisibleForTestOnly]
        public const int MaxAllowedNumTries = 20;

        /// <summary>The current API version of this client library.</summary>
        private static readonly string ApiVersion = Google.Apis.Util.Utilities.GetLibraryVersion();

        /// <summary>The User-Agent suffix header which contains the <see cref="ApiVersion"/>.</summary>
        private static readonly string UserAgentSuffix = "google-api-dotnet-client/" + ApiVersion + " (gzip)";

        #region IHttpUnsuccessfulResponseHandler, IHttpExceptionHandler and IHttpExecuteInterceptor lists

        #region Lock objects

        // The following lock objects are used to lock the list of handlers and interceptors in order to be able to
        // iterate over them from several threads and to keep this class thread-safe.
        private readonly object unsuccessfulResponseHandlersLock = new object();
        private readonly object exceptionHandlersLock = new object();
        private readonly object executeInterceptorsLock = new object();

        #endregion

        /// <summary>A list of <see cref="IHttpUnsuccessfulResponseHandler"/>.</summary>
        private readonly IList<IHttpUnsuccessfulResponseHandler> unsuccessfulResponseHandlers =
            new List<IHttpUnsuccessfulResponseHandler>();

        /// <summary>A list of <see cref="IHttpExceptionHandler"/>.</summary>
        private readonly IList<IHttpExceptionHandler> exceptionHandlers =
            new List<IHttpExceptionHandler>();

        /// <summary>A list of <see cref="IHttpExecuteInterceptor"/>.</summary>
        private readonly IList<IHttpExecuteInterceptor> executeInterceptors =
            new List<IHttpExecuteInterceptor>();

        /// <summary>
        /// Gets a snapshot of <see cref="IHttpUnsuccessfulResponseHandler"/>s associated with this instance's handlers.
        /// <remarks>
        /// Since version 1.10, the return value had been changed from <c>IList</c> to <c>IEnumerable</c> in order to
        /// keep this class thread-safe. The returned enumerable is a snapshot version of the handlers. More info is
        /// available on <a href="https://github.com/google/google-api-dotnet-client/issues/592">Issue 592</a>.
        /// </remarks>
        /// </summary>
        public IEnumerable<IHttpUnsuccessfulResponseHandler> UnsuccessfulResponseHandlers
        {
            get
            {
                lock (unsuccessfulResponseHandlersLock)
                {
                    return unsuccessfulResponseHandlers.ToList();
                }
            }
        }

        /// <summary>Adds the specified handler to the list of unsuccessful response handlers.</summary>
        public void AddUnsuccessfulResponseHandler(IHttpUnsuccessfulResponseHandler handler)
        {
            lock (unsuccessfulResponseHandlersLock)
            {
                unsuccessfulResponseHandlers.Add(handler);
            }
        }

        /// <summary>Removes the specified handler from the list of unsuccessful response handlers.</summary>
        public void RemoveUnsuccessfulResponseHandler(IHttpUnsuccessfulResponseHandler handler)
        {
            lock (unsuccessfulResponseHandlersLock)
            {
                unsuccessfulResponseHandlers.Remove(handler);
            }
        }

        /// <summary>
        /// Gets a snapshot of <see cref="IHttpExceptionHandler"/>s associated with this instance's handlers.
        /// <remarks>
        /// Since version 1.10, the return value had been changed from <c>IList</c> to <c>IEnumerable</c> in order to
        /// keep this class thread-safe. The returned enumerable is a snapshot version of the handlers. More info is
        /// available on <a href="https://github.com/google/google-api-dotnet-client/issues/592">Issue 592</a>.
        /// </remarks>
        /// </summary>
        public IEnumerable<IHttpExceptionHandler> ExceptionHandlers
        {
            get
            {
                lock (exceptionHandlersLock)
                {
                    return exceptionHandlers.ToList();
                }
            }
        }

        /// <summary>Adds the specified handler to the list of exception handlers.</summary>
        public void AddExceptionHandler(IHttpExceptionHandler handler)
        {
            lock (exceptionHandlersLock)
            {
                exceptionHandlers.Add(handler);
            }
        }

        /// <summary>Removes the specified handler from the list of exception handlers.</summary>
        public void RemoveExceptionHandler(IHttpExceptionHandler handler)
        {
            lock (exceptionHandlersLock)
            {
                exceptionHandlers.Remove(handler);
            }
        }

        /// <summary>
        /// Gets a snapshot of <see cref="IHttpExecuteInterceptor"/>s associated with this instance's interceptors.
        /// <remarks>
        /// Since version 1.10, the return value had been changed from <c>IList</c> to <c>IEnumerable</c> in order to
        /// keep this class thread-safe. The returned enumerable is a snapshot version of the interceptors. More info
        /// is available on <a href="https://github.com/google/google-api-dotnet-client/issues/592">Issue 592</a>.
        /// </remarks>
        /// </summary>
        public IEnumerable<IHttpExecuteInterceptor> ExecuteInterceptors
        {
            get
            {
                lock (executeInterceptorsLock)
                {
                    return executeInterceptors.ToList();
                }
            }
        }

        /// <summary>Adds the specified interceptor to the list of execute interceptors.</summary>
        public void AddExecuteInterceptor(IHttpExecuteInterceptor interceptor)
        {
            lock (executeInterceptorsLock)
            {
                executeInterceptors.Add(interceptor);
            }
        }

        /// <summary>Removes the specified interceptor from the list of execute interceptors.</summary>
        public void RemoveExecuteInterceptor(IHttpExecuteInterceptor interceptor)
        {
            lock (executeInterceptorsLock)
            {
                executeInterceptors.Remove(interceptor);
            }
        }
{'fraction_non_alphanumeric': 0.08605228009921771, 'fraction_numerical': 0.004706480951472365, 'mean_word_length': 2.3222057891400802, 'pattern_counts': {'":': 0, '<': 159, '<?xml version=': 0, '>': 159, 'https://': 6, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3225171', 'n_tokens_mistral': 3845, 'n_tokens_neox': 3718, 'n_words': 1206}