况洋洋
2025-07-04 0d247bd2a17e0f99f3609774a1ce54ae00857997
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright © 2020 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
 
using System;
using System.Collections.Generic;
 
namespace CefSharp.Handler
{
    /// <summary>
    /// Implement this interface to provide handler implementations. The handler
    /// instance will not be released until all objects related to the context have
    /// been destroyed.
    /// </summary>
    public class RequestContextHandler : IRequestContextHandler
    {
        private readonly IList<KeyValuePair<string, object>> preferences = new List<KeyValuePair<string, object>>();
        private bool requestContextInitialized = false;
        private Action<IRequestContext> onContextInitialziedAction;
 
        /// <summary>
        /// The <see cref="Action{IRequestContext}"/> is executed when the RequestContext has been initialized, after the
        /// preferences/proxy preferences have been set, before OnRequestContextInitialized.
        /// </summary>
        /// <param name="onContextInitialziedAction">action to perform on context initialize</param>
        /// <returns>A <see cref="RequestContextHandler"/> instance allowing you to chain multiple AddPreference calls together </returns>
        /// <remarks>Only a single action reference is maintained, multiple calls will result in the
        /// previous action reference being overriden.</remarks>
        public RequestContextHandler OnInitialize(Action<IRequestContext> onContextInitialziedAction)
        {
            this.onContextInitialziedAction = onContextInitialziedAction;
 
            return this;
        }
 
        /// <summary>
        /// Sets the preferences when the <see cref="IRequestContextHandler.OnRequestContextInitialized(IRequestContext)"/>
        /// method is called. If <paramref name="value"/> is null the  preference will be restored
        /// to its default value. Preferences set via the command-line usually cannot be modified.
        /// </summary>
        /// <param name="name">preference name</param>
        /// <param name="value">preference value</param>
        /// <returns>A <see cref="RequestContextHandler"/> instance allowing you to chain multiple AddPreference calls together </returns>
        public RequestContextHandler SetPreferenceOnContextInitialized(string name, object value)
        {
            if (requestContextInitialized)
            {
                throw new System.Exception("RequestContext has already been initialized, ");
            }
 
            preferences.Add(new KeyValuePair<string, object>(name, value));
 
            return this;
        }
 
        /// <summary>
        /// Sets the proxy preferences when the <see cref="IRequestContextHandler.OnRequestContextInitialized(IRequestContext)"/>
        /// method is called. Proxy set via the command-line usually cannot be modified.
        /// </summary>
        /// <param name="host">proxy host</param>
        /// <param name="port">proxy port</param>
        /// <returns>A <see cref="RequestContextHandler"/> instance allowing you to chain multiple AddPreference calls together </returns>
        public RequestContextHandler SetProxyOnContextInitialized(string host, int? port = null)
        {
            return SetProxyOnContextInitialized(null, host, port);
        }
 
        /// <summary>
        /// Sets the proxy preferences when the <see cref="IRequestContextHandler.OnRequestContextInitialized(IRequestContext)"/>
        /// method is called. Proxy set via the command-line usually cannot be modified.
        /// </summary>
        /// <param name="scheme">is the protocol of the proxy server, and is one of: 'http', 'socks', 'socks4', 'socks5'. Also note that 'socks' is equivalent to 'socks5'.</param>
        /// <param name="host">proxy host</param>
        /// <param name="port">proxy port</param>
        /// <returns>A <see cref="RequestContextHandler"/> instance allowing you to chain multiple AddPreference calls together </returns>
        public RequestContextHandler SetProxyOnContextInitialized(string scheme, string host, int? port)
        {
            if (requestContextInitialized)
            {
                throw new System.Exception("RequestContext has already been initialized, ");
            }
 
            var value = RequestContextExtensions.GetProxyDictionary(scheme, host, port);
 
            preferences.Add(new KeyValuePair<string, object>("proxy", value));
 
            return this;
        }
 
        IResourceRequestHandler IRequestContextHandler.GetResourceRequestHandler(IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
        {
            return GetResourceRequestHandler(browser, frame, request, isNavigation, isDownload, requestInitiator, ref disableDefaultHandling);
        }
 
        /// <summary>
        /// Called on the CEF IO thread before a resource request is initiated.
        /// This method will not be called if the client associated with <paramref name="browser"/> returns a non-NULL value
        /// from <see cref="IRequestHandler.GetResourceRequestHandler"/> for the same request (identified by <see cref="IRequest.Identifier"/>).
        /// </summary>
        /// <param name="browser">represent the source browser of the request, and may be null for requests originating from service workers.</param>
        /// <param name="frame">represent the source frame of the request, and may be null for requests originating from service workers.</param>
        /// <param name="request">represents the request contents and cannot be modified in this callback</param>
        /// <param name="isNavigation">will be true if the resource request is a navigation</param>
        /// <param name="isDownload">will be true if the resource request is a download</param>
        /// <param name="requestInitiator">is the origin (scheme + domain) of the page that initiated the request</param>
        /// <param name="disableDefaultHandling">Set to true to disable default handling of the request, in which case it will need to be handled via <see cref="IResourceRequestHandler.GetResourceHandler(IWebBrowser, IBrowser, IFrame, IRequest)"/> or it will be canceled</param>
        /// <returns>To allow the resource load to proceed with default handling return null. To specify a handler for the resource return a <see cref="IResourceRequestHandler"/> object.</returns>
        protected virtual IResourceRequestHandler GetResourceRequestHandler(IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
        {
            return null;
        }
 
        void IRequestContextHandler.OnRequestContextInitialized(IRequestContext requestContext)
        {
            requestContextInitialized = true;
            string errorMessage;
 
            foreach (var pref in preferences)
            {
                if (!requestContext.SetPreference(pref.Key, pref.Value, out errorMessage))
                {
                    //TODO: Do something if there's an error
                }
            }
 
            onContextInitialziedAction?.Invoke(requestContext);
 
            OnRequestContextInitialized(requestContext);
        }
 
        /// <summary>
        /// Called immediately after the request context has been initialized.
        /// It's important to note this event is fired on a CEF UI thread, which by default is not the same as your application UI
        /// thread.
        /// </summary>
        /// <param name="requestContext">the request context</param>
        protected virtual void OnRequestContextInitialized(IRequestContext requestContext)
        {
 
        }
    }
}