├── .github
└── FUNDING.yml
├── .gitignore
├── HttpsUtility.sln
├── HttpsUtility
├── Diagnostics
│ ├── AssertionException.cs
│ ├── Debug.cs
│ └── DebugLevel.cs
├── Extensions.cs
├── Https
│ ├── HttpsClientPool.cs
│ └── HttpsResult.cs
├── HttpsUtility.csproj
├── HttpsUtility.projectinfo
├── Lazy.cs
├── ObjectPool.cs
├── Properties
│ └── AssemblyInfo.cs
└── Symbols
│ ├── SimplHttpsClient.Callbacks.cs
│ ├── SimplHttpsClient.Delegates.cs
│ └── SimplHttpsClient.cs
├── LICENSE
└── README.md
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: bitm0de
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### VisualStudio template
3 | ## Ignore Visual Studio temporary files, build results, and
4 | ## files generated by popular Visual Studio add-ons.
5 | ##
6 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
7 |
8 | # User-specific files
9 | *.suo
10 | *.user
11 | *.userosscache
12 | *.sln.docstates
13 |
14 | # User-specific files (MonoDevelop/Xamarin Studio)
15 | *.userprefs
16 |
17 | # Build results
18 | [Dd]ebug/
19 | [Dd]ebugPublic/
20 | [Rr]elease/
21 | [Rr]eleases/
22 | x64/
23 | x86/
24 | bld/
25 | [Bb]in/
26 | [Oo]bj/
27 | [Ll]og/
28 |
29 | # Visual Studio 2015/2017 cache/options directory
30 | .vs/
31 | # Uncomment if you have tasks that create the project's static files in wwwroot
32 | #wwwroot/
33 |
34 | # Visual Studio 2017 auto generated files
35 | Generated\ Files/
36 |
37 | # MSTest test Results
38 | [Tt]est[Rr]esult*/
39 | [Bb]uild[Ll]og.*
40 |
41 | # NUNIT
42 | *.VisualState.xml
43 | TestResult.xml
44 |
45 | # Build Results of an ATL Project
46 | [Dd]ebugPS/
47 | [Rr]eleasePS/
48 | dlldata.c
49 |
50 | # Benchmark Results
51 | BenchmarkDotNet.Artifacts/
52 |
53 | # .NET Core
54 | project.lock.json
55 | project.fragment.lock.json
56 | artifacts/
57 |
58 | # StyleCop
59 | StyleCopReport.xml
60 |
61 | # Files built by Visual Studio
62 | *_i.c
63 | *_p.c
64 | *_i.h
65 | *.ilk
66 | *.meta
67 | *.obj
68 | *.iobj
69 | *.pch
70 | *.pdb
71 | *.ipdb
72 | *.pgc
73 | *.pgd
74 | *.rsp
75 | *.sbr
76 | *.tlb
77 | *.tli
78 | *.tlh
79 | *.tmp
80 | *.tmp_proj
81 | *.log
82 | *.vspscc
83 | *.vssscc
84 | .builds
85 | *.pidb
86 | *.svclog
87 | *.scc
88 |
89 | # Chutzpah Test files
90 | _Chutzpah*
91 |
92 | # Visual C++ cache files
93 | ipch/
94 | *.aps
95 | *.ncb
96 | *.opendb
97 | *.opensdf
98 | *.sdf
99 | *.cachefile
100 | *.VC.db
101 | *.VC.VC.opendb
102 |
103 | # Visual Studio profiler
104 | *.psess
105 | *.vsp
106 | *.vspx
107 | *.sap
108 |
109 | # Visual Studio Trace Files
110 | *.e2e
111 |
112 | # TFS 2012 Local Workspace
113 | $tf/
114 |
115 | # Guidance Automation Toolkit
116 | *.gpState
117 |
118 | # ReSharper is a .NET coding add-in
119 | _ReSharper*/
120 | *.[Rr]e[Ss]harper
121 | *.DotSettings.user
122 |
123 | # JustCode is a .NET coding add-in
124 | .JustCode
125 |
126 | # TeamCity is a build add-in
127 | _TeamCity*
128 |
129 | # DotCover is a Code Coverage Tool
130 | *.dotCover
131 |
132 | # AxoCover is a Code Coverage Tool
133 | .axoCover/*
134 | !.axoCover/settings.json
135 |
136 | # Visual Studio code coverage results
137 | *.coverage
138 | *.coveragexml
139 |
140 | # NCrunch
141 | _NCrunch_*
142 | .*crunch*.local.xml
143 | nCrunchTemp_*
144 |
145 | # MightyMoose
146 | *.mm.*
147 | AutoTest.Net/
148 |
149 | # Web workbench (sass)
150 | .sass-cache/
151 |
152 | # Installshield output folder
153 | [Ee]xpress/
154 |
155 | # DocProject is a documentation generator add-in
156 | DocProject/buildhelp/
157 | DocProject/Help/*.HxT
158 | DocProject/Help/*.HxC
159 | DocProject/Help/*.hhc
160 | DocProject/Help/*.hhk
161 | DocProject/Help/*.hhp
162 | DocProject/Help/Html2
163 | DocProject/Help/html
164 |
165 | # Click-Once directory
166 | publish/
167 |
168 | # Publish Web Output
169 | *.[Pp]ublish.xml
170 | *.azurePubxml
171 | # Note: Comment the next line if you want to checkin your web deploy settings,
172 | # but database connection strings (with potential passwords) will be unencrypted
173 | *.pubxml
174 | *.publishproj
175 |
176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
177 | # checkin your Azure Web App publish settings, but sensitive information contained
178 | # in these scripts will be unencrypted
179 | PublishScripts/
180 |
181 | # NuGet Packages
182 | *.nupkg
183 | # The packages folder can be ignored because of Package Restore
184 | **/[Pp]ackages/*
185 | # except build/, which is used as an MSBuild target.
186 | !**/[Pp]ackages/build/
187 | # Uncomment if necessary however generally it will be regenerated when needed
188 | #!**/[Pp]ackages/repositories.config
189 | # NuGet v3's project.json files produces more ignorable files
190 | *.nuget.props
191 | *.nuget.targets
192 |
193 | # Microsoft Azure Build Output
194 | csx/
195 | *.build.csdef
196 |
197 | # Microsoft Azure Emulator
198 | ecf/
199 | rcf/
200 |
201 | # Windows Store app package directories and files
202 | AppPackages/
203 | BundleArtifacts/
204 | Package.StoreAssociation.xml
205 | _pkginfo.txt
206 | *.appx
207 |
208 | # Visual Studio cache files
209 | # files ending in .cache can be ignored
210 | *.[Cc]ache
211 | # but keep track of directories ending in .cache
212 | !*.[Cc]ache/
213 |
214 | # Others
215 | ClientBin/
216 | ~$*
217 | *~
218 | *.dbmdl
219 | *.dbproj.schemaview
220 | *.jfm
221 | *.pfx
222 | *.publishsettings
223 | orleans.codegen.cs
224 |
225 | # Including strong name files can present a security risk
226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
227 | #*.snk
228 |
229 | # Since there are multiple workflows, uncomment next line to ignore bower_components
230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
231 | #bower_components/
232 |
233 | # RIA/Silverlight projects
234 | Generated_Code/
235 |
236 | # Backup & report files from converting an old project file
237 | # to a newer Visual Studio version. Backup files are not needed,
238 | # because we have git ;-)
239 | _UpgradeReport_Files/
240 | Backup*/
241 | UpgradeLog*.XML
242 | UpgradeLog*.htm
243 | ServiceFabricBackup/
244 | *.rptproj.bak
245 |
246 | # SQL Server files
247 | *.mdf
248 | *.ldf
249 | *.ndf
250 |
251 | # Business Intelligence projects
252 | *.rdl.data
253 | *.bim.layout
254 | *.bim_*.settings
255 | *.rptproj.rsuser
256 |
257 | # Microsoft Fakes
258 | FakesAssemblies/
259 |
260 | # GhostDoc plugin setting file
261 | *.GhostDoc.xml
262 |
263 | # Node.js Tools for Visual Studio
264 | .ntvs_analysis.dat
265 | node_modules/
266 |
267 | # Visual Studio 6 build log
268 | *.plg
269 |
270 | # Visual Studio 6 workspace options file
271 | *.opt
272 |
273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
274 | *.vbw
275 |
276 | # Visual Studio LightSwitch build output
277 | **/*.HTMLClient/GeneratedArtifacts
278 | **/*.DesktopClient/GeneratedArtifacts
279 | **/*.DesktopClient/ModelManifest.xml
280 | **/*.Server/GeneratedArtifacts
281 | **/*.Server/ModelManifest.xml
282 | _Pvt_Extensions
283 |
284 | # Paket dependency manager
285 | .paket/paket.exe
286 | paket-files/
287 |
288 | # FAKE - F# Make
289 | .fake/
290 |
291 | # JetBrains Rider
292 | .idea/
293 | *.sln.iml
294 |
295 | # CodeRush
296 | .cr/
297 |
298 | # Python Tools for Visual Studio (PTVS)
299 | __pycache__/
300 | *.pyc
301 |
302 | # Cake - Uncomment if you are using it
303 | # tools/**
304 | # !tools/packages.config
305 |
306 | # Tabs Studio
307 | *.tss
308 |
309 | # Telerik's JustMock configuration file
310 | *.jmconfig
311 |
312 | # BizTalk build output
313 | *.btp.cs
314 | *.btm.cs
315 | *.odx.cs
316 | *.xsd.cs
317 |
318 | # OpenCover UI analysis results
319 | OpenCover/
320 |
321 | # Azure Stream Analytics local run output
322 | ASALocalRun/
323 |
324 | # MSBuild Binary and Structured Log
325 | *.binlog
326 |
327 | # NVidia Nsight GPU debugger configuration file
328 | *.nvuser
329 |
330 | # MFractors (Xamarin productivity tool) working folder
331 | .mfractor/
332 |
333 |
--------------------------------------------------------------------------------
/HttpsUtility.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 10.00
3 | # Visual Studio 2008
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpsUtility", "HttpsUtility\HttpsUtility.csproj", "{20ABC9C5-BA5D-4C65-94AD-E87EF71FA36A}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {20ABC9C5-BA5D-4C65-94AD-E87EF71FA36A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {20ABC9C5-BA5D-4C65-94AD-E87EF71FA36A}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {20ABC9C5-BA5D-4C65-94AD-E87EF71FA36A}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {20ABC9C5-BA5D-4C65-94AD-E87EF71FA36A}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/HttpsUtility/Diagnostics/AssertionException.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Troy Garner 2019 - Present
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a
5 | * copy of this software and associated documentation files (the "Software"),
6 | * to deal in the Software without restriction, including without limitation
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | * and/or sell copies of the Software, and to permit persons to whom the
9 | * Software is furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 | * IN THE SOFTWARE.
21 | *
22 | */
23 |
24 | using System;
25 |
26 | namespace HttpsUtility.Diagnostics
27 | {
28 | ///
29 | /// Exception class for assertion failures.
30 | ///
31 | [Serializable]
32 | internal class AssertionException : Exception
33 | {
34 | public AssertionException() { }
35 | public AssertionException(string message) : base(message) { }
36 | public AssertionException(string message, Exception inner) : base(message, inner) { }
37 | }
38 | }
--------------------------------------------------------------------------------
/HttpsUtility/Diagnostics/Debug.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Troy Garner 2019 - Present
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a
5 | * copy of this software and associated documentation files (the "Software"),
6 | * to deal in the Software without restriction, including without limitation
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | * and/or sell copies of the Software, and to permit persons to whom the
9 | * Software is furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 | * IN THE SOFTWARE.
21 | *
22 | */
23 |
24 | using System;
25 | using System.Text;
26 | using Crestron.SimplSharp;
27 | using Crestron.SimplSharp.CrestronIO;
28 | using Crestron.SimplSharp.Reflection;
29 |
30 | namespace HttpsUtility.Diagnostics
31 | {
32 | public static class Debug
33 | {
34 | private static bool _enable;
35 | private static readonly CTimer _timer = new CTimer(WriteQueueToDisk, null, Timeout.Infinite, Timeout.Infinite);
36 | private static readonly CCriticalSection _writeLock = new CCriticalSection();
37 | private static readonly CrestronQueue _queue = new CrestronQueue(1024);
38 |
39 | private static readonly AssemblyName _asmName;
40 |
41 | /// Initializes the debug class
42 | static Debug()
43 | {
44 | try
45 | {
46 | _asmName = Assembly.GetExecutingAssembly().GetName();
47 | }
48 | catch (Exception ex)
49 | {
50 | CrestronConsole.PrintLine(ex.Message);
51 | throw;
52 | }
53 | }
54 |
55 | public static DebugLevel Levels { get; set; }
56 |
57 | /// Flag for enabling debug mode
58 | public static bool Enable
59 | {
60 | get { return _enable; }
61 | set
62 | {
63 | _enable = value;
64 | if (_enable)
65 | _timer.Reset(0, 5000);
66 | else
67 | _timer.Stop();
68 | }
69 | }
70 |
71 | private static void WriteQueueToDisk(object _)
72 | {
73 | if (Enable)
74 | {
75 | try
76 | {
77 | if (!_writeLock.TryEnter())
78 | return;
79 |
80 | if (!_queue.IsEmpty)
81 | {
82 | var sb = new StringBuilder(8192);
83 | while (!_queue.IsEmpty)
84 | {
85 | string logItem;
86 | if (_queue.Dequeue(out logItem))
87 | sb.Append(logItem);
88 | }
89 |
90 | using (var sw = new StreamWriter(string.Format("\\User\\Logs\\{0} {1:yyyy-MM-dd}.log", _asmName.Name, DateTime.Now), true))
91 | sw.Write(sb.ToString());
92 | }
93 | }
94 | finally
95 | {
96 | _writeLock.Leave();
97 | }
98 | }
99 | }
100 |
101 | ///
102 | /// Private helper method to return formatted message string prefixed with the assembly identifier.
103 | ///
104 | /// Message to be written
105 | /// Format arguments for the message
106 | private static string InternalFormat(string message, params object[] args)
107 | {
108 | return string.Format("[{0:yyyy-MM-dd HH:mm:ss}] {1}: App{2:00} - {3}", DateTime.Now, string.Format("{0} {1}", _asmName.Name, _asmName.Version),
109 | InitialParametersClass.ApplicationNumber, string.Format(message, args));
110 | }
111 |
112 | ///
113 | /// Private helper method to write formatted message to console prefixed with the assembly identifier.
114 | ///
115 | /// Message to be written
116 | /// Format arguments for the message
117 | private static void InternalWrite(string message, params object[] args)
118 | {
119 | if (Enable)
120 | {
121 | try
122 | {
123 | _writeLock.Enter();
124 | CrestronInvoke.BeginInvoke(_ => _queue.Enqueue(InternalFormat(message, args)));
125 | }
126 | finally
127 | {
128 | _writeLock.Leave();
129 | }
130 | }
131 | }
132 |
133 | ///
134 | /// Writes a raw debug message without a newline.
135 | ///
136 | /// Format message to output
137 | /// Format message string arguments (if applicable)
138 | public static void Write(string message, params object[] args)
139 | {
140 | InternalWrite(message, args);
141 | }
142 |
143 | public static void Write(object obj)
144 | {
145 | Write("{0}", obj);
146 | }
147 |
148 | ///
149 | /// Writes a raw debug message with a newline.
150 | ///
151 | /// Format message to output
152 | /// Format message string arguments (if applicable)
153 | public static void WriteLine(string message, params object[] args)
154 | {
155 | Write("{0}\n", string.Format(message, args));
156 | }
157 |
158 | public static void WriteLine(object obj)
159 | {
160 | WriteLine("{0}", obj);
161 | }
162 |
163 | ///
164 | /// Writes an exception debug message with a newline.
165 | ///
166 | /// Format message to output
167 | /// Format message string arguments (if applicable)
168 | public static void WriteException(string message, params object[] args)
169 | {
170 | if (((int)Levels & (int)DebugLevel.Exception) != 0)
171 | WriteLine("NOTICE: [Exception] {0}", string.Format(message, args));
172 | }
173 |
174 | public static void WriteException(Exception obj)
175 | {
176 | WriteException("{0}", obj);
177 | }
178 |
179 | ///
180 | /// Writes an error debug message with a newline.
181 | ///
182 | /// Format message to output
183 | /// Format message string arguments (if applicable)
184 | public static void WriteError(string message, params object[] args)
185 | {
186 | if (((int)Levels & (int)DebugLevel.Error) != 0)
187 | WriteLine("Error: {0}", string.Format(message, args));
188 | }
189 |
190 | public static void WriteError(object obj)
191 | {
192 | WriteError("{0}", obj);
193 | }
194 |
195 | ///
196 | /// Writes a warning debug message with a newline.
197 | ///
198 | /// Format message to output
199 | /// Format message string arguments (if applicable)
200 | public static void WriteWarning(string message, params object[] args)
201 | {
202 | if (((int)Levels & (int)DebugLevel.Warning) != 0)
203 | WriteLine("Warning: {0}", string.Format(message, args));
204 | }
205 |
206 | public static void WriteWarning(object obj)
207 | {
208 | WriteWarning("{0}", obj);
209 | }
210 |
211 | ///
212 | /// Writes an info debug message with a newline.
213 | ///
214 | /// Format message to output
215 | /// Format message string arguments (if applicable)
216 | public static void WriteInfo(string message, params object[] args)
217 | {
218 | if (((int)Levels & (int)DebugLevel.Info) != 0)
219 | WriteLine("Info: {0}", string.Format(message, args));
220 | }
221 |
222 | public static void WriteInfo(object obj)
223 | {
224 | WriteInfo("{0}", obj);
225 | }
226 |
227 | public static void Assert(Func condition)
228 | {
229 | Assert(condition, null);
230 | }
231 |
232 | public static void Assert(Func condition, string message)
233 | {
234 | if (!condition.Invoke())
235 | throw message != null ? new AssertionException(message) : new AssertionException();
236 | }
237 | }
238 | }
--------------------------------------------------------------------------------
/HttpsUtility/Diagnostics/DebugLevel.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Troy Garner 2019 - Present
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a
5 | * copy of this software and associated documentation files (the "Software"),
6 | * to deal in the Software without restriction, including without limitation
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | * and/or sell copies of the Software, and to permit persons to whom the
9 | * Software is furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 | * IN THE SOFTWARE.
21 | *
22 | */
23 |
24 | using System;
25 |
26 | namespace HttpsUtility.Diagnostics
27 | {
28 | ///
29 | /// Flags to set the debug level verbosity.
30 | ///
31 | [Flags]
32 | public enum DebugLevel
33 | {
34 | Notice = 0,
35 | Info = 1,
36 | Warning = 2,
37 | Error = 4,
38 | Exception = 8,
39 | All = 15
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/HttpsUtility/Extensions.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Troy Garner 2019 - Present
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a
5 | * copy of this software and associated documentation files (the "Software"),
6 | * to deal in the Software without restriction, including without limitation
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | * and/or sell copies of the Software, and to permit persons to whom the
9 | * Software is furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 | * IN THE SOFTWARE.
21 | *
22 | */
23 |
24 | using System;
25 | using System.Collections.Generic;
26 |
27 | namespace HttpsUtility
28 | {
29 | ///
30 | /// Class for generic extension methods
31 | ///
32 | internal static class Extensions
33 | {
34 | ///
35 | /// Returns a null string if input is an empty string.
36 | ///
37 | /// Input string
38 | /// Null if empty, otherwise the input itself
39 | public static string NullIfEmpty(this string input)
40 | {
41 | return input == string.Empty ? null : input;
42 | }
43 |
44 | ///
45 | /// Returns an empty string if input is a null string.
46 | ///
47 | /// Input string
48 | /// Empty string if null, otherwise the input itself
49 | public static string EmptyIfNull(this string input)
50 | {
51 | return input ?? string.Empty;
52 | }
53 |
54 | ///
55 | /// Split an input string into chunks specified by a max length
56 | ///
57 | /// Input string
58 | /// Maximum size of each chunk
59 | /// of strings split up into chunks.
60 | /// Input string is null.
61 | /// Max length is less than 1.
62 | public static IEnumerable SplitIntoChunks(this string input, int maxLength)
63 | {
64 | if (input == null)
65 | throw new ArgumentNullException("input");
66 |
67 | if (maxLength <= 0)
68 | throw new ArgumentException("maxSize must be greater than 0.");
69 |
70 | if (input == string.Empty)
71 | return new[] { string.Empty };
72 |
73 | int n = 0;
74 | List chunks = new List(input.Length / maxLength);
75 | while (n != input.Length)
76 | {
77 | int length = Math.Min(maxLength, input.Length - n);
78 | chunks.Add(input.Substring(n, length));
79 | n += length;
80 | }
81 | return chunks;
82 | }
83 |
84 | ///
85 | /// Check to see if a flags enumeration has a specific flag set.
86 | ///
87 | /// Flags enumeration to check
88 | /// Flag to check for
89 | ///
90 | public static bool HasFlag(this Enum variable, Enum value)
91 | {
92 | if (variable == null)
93 | return false;
94 |
95 | if (value == null)
96 | throw new ArgumentNullException("value");
97 |
98 | // Not as good as the .NET 4 version of this function, but should be good enough
99 | if (!Enum.IsDefined(variable.GetType(), value))
100 | {
101 | throw new ArgumentException(string.Format(
102 | "Enumeration type mismatch. The flag is of type '{0}', was expecting '{1}'.",
103 | value.GetType(), variable.GetType()));
104 | }
105 |
106 | ulong num = Convert.ToUInt64(value);
107 | return (Convert.ToUInt64(variable) & num) == num;
108 | }
109 | }
110 | }
--------------------------------------------------------------------------------
/HttpsUtility/Https/HttpsClientPool.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Troy Garner 2019 - Present
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a
5 | * copy of this software and associated documentation files (the "Software"),
6 | * to deal in the Software without restriction, including without limitation
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | * and/or sell copies of the Software, and to permit persons to whom the
9 | * Software is furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 | * IN THE SOFTWARE.
21 | *
22 | */
23 |
24 | using System;
25 | using System.Collections.Generic;
26 | using System.Text;
27 | using Crestron.SimplSharp.Net.Https;
28 | using HttpsUtility.Diagnostics;
29 |
30 | using ContentSource = Crestron.SimplSharp.Net.Https.ContentSource;
31 | using RequestType = Crestron.SimplSharp.Net.Https.RequestType;
32 |
33 | namespace HttpsUtility.Https
34 | {
35 | public sealed class HttpsClientPool : IDisposable
36 | {
37 | private const int HttpsClientPoolSize = 10;
38 |
39 | private readonly ObjectPool> _httpsClientPool
40 | = new ObjectPool>(HttpsClientPoolSize, HttpsClientPoolSize,
41 | () => new Lazy(() => new HttpsClient {
42 | PeerVerification = false, HostVerification = false,
43 | TimeoutEnabled = true, Timeout = 5, KeepAlive = false
44 | })) { CleanupPoolOnDispose = true };
45 |
46 | private HttpsResult SendRequest(string url, RequestType requestType, IEnumerable> additionalHeaders, string content)
47 | {
48 | var obj = _httpsClientPool.GetFromPool();
49 | var client = obj.Value;
50 |
51 | try
52 | {
53 | Debug.WriteInfo("Making API GET request to endpoint: {0}", url);
54 |
55 | if (client.ProcessBusy)
56 | client.Abort();
57 |
58 | var httpsRequest = new HttpsClientRequest {
59 | RequestType = requestType,
60 | Encoding = Encoding.UTF8,
61 | KeepAlive = false,
62 | };
63 |
64 | if (requestType != RequestType.Get)
65 | {
66 | httpsRequest.ContentSource = ContentSource.ContentString;
67 | httpsRequest.ContentString = content ?? string.Empty;
68 | }
69 |
70 | if (additionalHeaders != null)
71 | {
72 | foreach (var item in additionalHeaders)
73 | httpsRequest.Header.AddHeader(new HttpsHeader(item.Key, item.Value));
74 | }
75 |
76 | httpsRequest.Url.Parse(url);
77 |
78 | HttpsClientResponse httpResponse = client.Dispatch(httpsRequest);
79 | return new HttpsResult(httpResponse.Code, httpResponse.ResponseUrl, httpResponse.ContentString);
80 | }
81 | catch (Exception ex)
82 | {
83 | Debug.WriteException(ex);
84 | }
85 | finally
86 | {
87 | _httpsClientPool.AddToPool(obj);
88 | }
89 |
90 | return null;
91 | }
92 |
93 | public HttpsResult Get(string url)
94 | {
95 | return Get(url, null);
96 | }
97 |
98 | public HttpsResult Get(string url, IEnumerable> additionalHeaders)
99 | {
100 | return SendRequest(url, RequestType.Get, additionalHeaders, null);
101 | }
102 |
103 | public HttpsResult Post(string url, string value)
104 | {
105 | return Post(url, null, value);
106 | }
107 |
108 | public HttpsResult Post(string url, IEnumerable> additionalHeaders, string value)
109 | {
110 | return SendRequest(url, RequestType.Post, additionalHeaders, value);
111 | }
112 |
113 | public HttpsResult Put(string url, string value)
114 | {
115 | return Put(url, null, value);
116 | }
117 |
118 | public HttpsResult Put(string url, IEnumerable> additionalHeaders, string value)
119 | {
120 | return SendRequest(url, RequestType.Put, additionalHeaders, value);
121 | }
122 |
123 | public HttpsResult Delete(string url)
124 | {
125 | return Delete(url, null);
126 | }
127 |
128 | public HttpsResult Delete(string url, string value)
129 | {
130 | return Delete(url, null, value);
131 | }
132 |
133 | public HttpsResult Delete(string url, IEnumerable> additionalHeaders, string value)
134 | {
135 | return SendRequest(url, RequestType.Delete, additionalHeaders, value);
136 | }
137 |
138 | public void Dispose()
139 | {
140 | _httpsClientPool.Dispose();
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/HttpsUtility/Https/HttpsResult.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Troy Garner 2019 - Present
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a
5 | * copy of this software and associated documentation files (the "Software"),
6 | * to deal in the Software without restriction, including without limitation
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | * and/or sell copies of the Software, and to permit persons to whom the
9 | * Software is furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 | * IN THE SOFTWARE.
21 | *
22 | */
23 |
24 | namespace HttpsUtility.Https
25 | {
26 | public class HttpsResult
27 | {
28 | private readonly int _status;
29 | public int Status { get { return _status; } }
30 |
31 | private readonly string _responseUrl;
32 | public string ResponseUrl { get { return _responseUrl; } }
33 |
34 | private readonly string _content;
35 | public string Content { get { return _content; } }
36 |
37 | public HttpsResult(int status, string responseUrl, string content)
38 | {
39 | _status = status;
40 | _responseUrl = responseUrl;
41 | _content = content;
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/HttpsUtility/HttpsUtility.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Release
5 | AnyCPU
6 | 9.0.30729
7 | 2.0
8 | {20ABC9C5-BA5D-4C65-94AD-E87EF71FA36A}
9 | Library
10 | Properties
11 | HttpsUtility
12 | HttpsUtility
13 | {0B4745B0-194B-4BB6-8E21-E9057CA92500};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | WindowsCE
15 | E2BECB1F-8C8C-41ba-B736-9BE7D946A398
16 | 5.0
17 | SmartDeviceProject1
18 | v3.5
19 | Windows CE
20 |
21 |
22 | default
23 |
24 |
25 | .allowedReferenceRelatedFileExtensions
26 | true
27 | full
28 | false
29 | bin\Debug\
30 | DEBUG;TRACE;
31 | prompt
32 | 4
33 | 512
34 | true
35 | true
36 | off
37 |
38 |
39 | .allowedReferenceRelatedFileExtensions
40 | none
41 | true
42 | bin\Release\
43 | prompt
44 | 4
45 | 512
46 | true
47 | true
48 | off
49 |
50 |
51 |
52 |
53 | False
54 | ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll
55 |
56 |
57 | False
58 | ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll
59 |
60 |
61 | False
62 | ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | rem S# preparation will execute after these operations
86 |
87 |
--------------------------------------------------------------------------------
/HttpsUtility/HttpsUtility.projectinfo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bitm0de/HttpsUtility/c9c487947d4b33d40bd63ef4e116ccec2413ac48/HttpsUtility/HttpsUtility.projectinfo
--------------------------------------------------------------------------------
/HttpsUtility/Lazy.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Troy Garner 2019 - Present
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a
5 | * copy of this software and associated documentation files (the "Software"),
6 | * to deal in the Software without restriction, including without limitation
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | * and/or sell copies of the Software, and to permit persons to whom the
9 | * Software is furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 | * IN THE SOFTWARE.
21 | *
22 | */
23 |
24 | using System;
25 | using Crestron.SimplSharp;
26 |
27 | namespace HttpsUtility
28 | {
29 | ///
30 | /// Wrapper for lazy initialization support (before .NET 4.0).
31 | ///
32 | /// Object type to be lazy initialized.
33 | public sealed class Lazy
34 | {
35 | private Box _boxValue;
36 | private volatile bool _initialized;
37 |
38 | [NonSerialized] private readonly Func _valueInitFunc;
39 | [NonSerialized] private readonly CCriticalSection _objLock = new CCriticalSection();
40 |
41 | public bool Initialized
42 | {
43 | get
44 | {
45 | try
46 | {
47 | _objLock.Enter();
48 | return _initialized;
49 | }
50 | finally
51 | {
52 | _objLock.Leave();
53 | }
54 | }
55 | }
56 |
57 | public T Value
58 | {
59 | get
60 | {
61 | if (!_initialized)
62 | {
63 | try
64 | {
65 | _objLock.Enter();
66 | if (!_initialized)
67 | {
68 | _boxValue = new Box(_valueInitFunc());
69 | _initialized = true;
70 | }
71 | }
72 | finally
73 | {
74 | _objLock.Leave();
75 | }
76 | }
77 |
78 | return _boxValue.Value;
79 | }
80 | }
81 |
82 | public Lazy()
83 | : this(() => (T)Activator.CreateInstance(typeof(T))) { }
84 |
85 | public Lazy(Func valueInitFunc)
86 | {
87 | if (valueInitFunc == null)
88 | throw new ArgumentNullException("valueInitFunc");
89 |
90 | _valueInitFunc = valueInitFunc;
91 | }
92 |
93 | public override string ToString()
94 | {
95 | return _initialized ? Value.ToString() : "null";
96 | }
97 |
98 | [Serializable]
99 | private class Box
100 | {
101 | internal readonly T Value;
102 |
103 | internal Box(T value)
104 | {
105 | Value = value;
106 | }
107 | }
108 | }
109 |
110 | ///
111 | /// Non-generic class helper
112 | ///
113 | public sealed class Lazy
114 | {
115 | ///
116 | /// Creates a default instance of the specified type.
117 | ///
118 | /// Object type
119 | /// Lazy instance of the specified type.
120 | /// The new() type constraint is placed on this little factory method
121 | /// as a way to still allow for types that aren't restricted by this limitation
122 | /// to be used by the class
123 | public static Lazy CreateNew()
124 | where T : new()
125 | {
126 | return new Lazy(Activator.CreateInstance);
127 | }
128 | }
129 | }
--------------------------------------------------------------------------------
/HttpsUtility/ObjectPool.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Crestron.SimplSharp;
3 |
4 | namespace HttpsUtility
5 | {
6 | ///
7 | /// An object pool to help with minimizing GC cleanup and re-allocations.
8 | ///
9 | /// Pool object type.
10 | public sealed class ObjectPool : IDisposable
11 | where T : class, new()
12 | {
13 | private readonly CCriticalSection _disposeLock = new CCriticalSection();
14 | private readonly CrestronQueue _objectPool;
15 |
16 | private readonly CEvent _queueAddEvent = new CEvent(false, true);
17 | private readonly CEvent _queueReturnEvent = new CEvent(false, true);
18 | private int _currentCount;
19 | private bool _disposed;
20 |
21 | ///
22 | ///
23 | /// Initializes a new object pool.
24 | ///
25 | public ObjectPool()
26 | : this(64) { }
27 |
28 | ///
29 | ///
30 | /// Initializes a new object pool with a specified initial capacity.
31 | ///
32 | /// Initial pool capacity.
33 | public ObjectPool(int initialCapacity)
34 | : this(initialCapacity, -1, () => new T()) { }
35 |
36 | ///
37 | /// Initializes a new object pool with a specified initial and max capacity.
38 | /// A max capacity of -1 indicates there is no limit.
39 | ///
40 | /// Initial pool capacity.
41 | /// Max pool capacity. A value of -1 means the pool has no maximum.
42 | /// Initialization function
43 | /// Invalid initial or max capacity.
44 | public ObjectPool(int initialCapacity, int maxCapacity, Func initFunc)
45 | {
46 | if (initialCapacity < 1)
47 | throw new ArgumentException("Initial capacity cannot be less than 1.");
48 |
49 | if (maxCapacity < -1 || maxCapacity == 0)
50 | throw new ArgumentException("Max capacity cannot be less than 1, except -1 which indicates no limit.");
51 |
52 | if (maxCapacity != -1 && initialCapacity > maxCapacity)
53 | throw new ArgumentException("Initial capacity cannot be greater than max capacity.");
54 |
55 | MaxCapacity = maxCapacity;
56 | _objectPool = new CrestronQueue(initialCapacity);
57 |
58 | if (initialCapacity > 0)
59 | AddToPool(initialCapacity, initFunc);
60 | }
61 |
62 | ///
63 | /// Max capacity of the object pool.
64 | ///
65 | /// A max capacity of -1 indicates there is no maximum capacity.
66 | public int MaxCapacity { get; private set; }
67 |
68 | ///
69 | /// Determines whether internal objects in the queue are disposed
70 | /// when this object is disposed if this pool is holding IDisposable objects.
71 | ///
72 | public bool CleanupPoolOnDispose { get; set; }
73 |
74 | public void Dispose()
75 | {
76 | Dispose(true);
77 | }
78 |
79 | ///
80 | /// Adds (or returns) an object to the pool.
81 | ///
82 | ///
83 | /// If is -1, the object is enqueued immediately.
84 | public void AddToPool(T obj)
85 | {
86 | var newCount = Interlocked.Increment(ref _currentCount);
87 | if (MaxCapacity != -1 && newCount > MaxCapacity)
88 | _queueReturnEvent.Wait();
89 |
90 | if (_disposed) return;
91 | _objectPool.Enqueue(obj);
92 | _queueAddEvent.Set();
93 | }
94 |
95 | ///
96 | /// Adds a new object to the pool.
97 | ///
98 | /// Initialization function
99 | /// True if object could be added to the pool; otherwise false.
100 | public bool AddToPool(Func initFunc)
101 | {
102 | return AddToPool(1, initFunc);
103 | }
104 |
105 | ///
106 | /// Adds multiple objects to the pool.
107 | ///
108 | /// Number of instantiated objects to add.
109 | /// Initialization function
110 | /// True if objects could be added to the pool; otherwise false.
111 | public bool AddToPool(int count, Func initFunc)
112 | {
113 | for (var i = 0; i < count; i++)
114 | {
115 | if (_disposed || _currentCount == MaxCapacity)
116 | return false;
117 |
118 | Interlocked.Increment(ref _currentCount);
119 | _objectPool.Enqueue(initFunc.Invoke());
120 | _queueAddEvent.Set();
121 | }
122 |
123 | return true;
124 | }
125 |
126 | ///
127 | /// Retrieves an object from the pool.
128 | ///
129 | /// Pool object.
130 | public T GetFromPool()
131 | {
132 | if (_currentCount == 0)
133 | _queueAddEvent.Wait();
134 |
135 | if (_disposed) return null;
136 | Interlocked.Decrement(ref _currentCount);
137 | var obj = _objectPool.Dequeue();
138 | _queueReturnEvent.Set();
139 | return obj;
140 | }
141 |
142 | private void Dispose(bool disposing)
143 | {
144 | _disposed = true;
145 | if (disposing)
146 | {
147 | _queueAddEvent.Set();
148 | _queueReturnEvent.Set();
149 |
150 | if (CleanupPoolOnDispose && typeof(IDisposable).IsAssignableFrom(typeof(T)))
151 | while (!_objectPool.IsEmpty)
152 | ((IDisposable)_objectPool.Dequeue()).Dispose();
153 |
154 | _objectPool.Dispose();
155 | _queueAddEvent.Dispose();
156 | _queueReturnEvent.Dispose();
157 | _disposeLock.Dispose();
158 | }
159 | }
160 | }
161 | }
--------------------------------------------------------------------------------
/HttpsUtility/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | [assembly: AssemblyTitle("HttpsUtility")]
4 | [assembly: AssemblyCompany("")]
5 | [assembly: AssemblyProduct("HttpsUtility")]
6 | [assembly: AssemblyCopyright("Copyright © Troy Garner 2019")]
7 | [assembly: AssemblyVersion("1.0.1.*")]
8 |
9 |
--------------------------------------------------------------------------------
/HttpsUtility/Symbols/SimplHttpsClient.Callbacks.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Troy Garner 2019 - Present
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a
5 | * copy of this software and associated documentation files (the "Software"),
6 | * to deal in the Software without restriction, including without limitation
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | * and/or sell copies of the Software, and to permit persons to whom the
9 | * Software is furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 | * IN THE SOFTWARE.
21 | *
22 | */
23 |
24 | // ReSharper disable UnusedMember.Global
25 |
26 | namespace HttpsUtility.Symbols
27 | {
28 | public sealed partial class SimplHttpsClient
29 | {
30 | public SimplHttpsClientResponseDelegate SimplHttpsClientResponse { get; set; }
31 |
32 | private void OnSimplHttpsClientResponse(int status, string responseUrl, string content, int length)
33 | {
34 | var handler = SimplHttpsClientResponse;
35 | if (handler != null) handler.Invoke((ushort)status, responseUrl.EmptyIfNull(), content.EmptyIfNull(), length);
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/HttpsUtility/Symbols/SimplHttpsClient.Delegates.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Troy Garner 2019 - Present
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a
5 | * copy of this software and associated documentation files (the "Software"),
6 | * to deal in the Software without restriction, including without limitation
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | * and/or sell copies of the Software, and to permit persons to whom the
9 | * Software is furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 | * IN THE SOFTWARE.
21 | *
22 | */
23 |
24 | using Crestron.SimplSharp;
25 |
26 | namespace HttpsUtility.Symbols
27 | {
28 | public delegate void SimplHttpsClientResponseDelegate(ushort status, SimplSharpString responseUrl, SimplSharpString content, int contentLength);
29 | }
--------------------------------------------------------------------------------
/HttpsUtility/Symbols/SimplHttpsClient.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Troy Garner 2019 - Present
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a
5 | * copy of this software and associated documentation files (the "Software"),
6 | * to deal in the Software without restriction, including without limitation
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | * and/or sell copies of the Software, and to permit persons to whom the
9 | * Software is furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 | * IN THE SOFTWARE.
21 | *
22 | */
23 |
24 | using System;
25 | using System.Collections.Generic;
26 | using System.Linq;
27 | using Crestron.SimplSharp;
28 | using Crestron.SimplSharp.Reflection;
29 | using HttpsUtility.Diagnostics;
30 | using HttpsUtility.Https;
31 |
32 | namespace HttpsUtility.Symbols
33 | {
34 | // ReSharper disable once UnusedType.Global
35 | public sealed partial class SimplHttpsClient
36 | {
37 | private readonly string _moduleIdentifier;
38 | private readonly HttpsClientPool _httpsClientPool = new HttpsClientPool();
39 |
40 | public SimplHttpsClient()
41 | {
42 | var asm = Assembly.GetExecutingAssembly().GetName();
43 | _moduleIdentifier = string.Format("{0} {1}", asm.Name, asm.Version.ToString(2));
44 | }
45 |
46 | private static IEnumerable> ParseHeaders(string input)
47 | {
48 | if (string.IsNullOrEmpty(input))
49 | return new KeyValuePair[] { };
50 |
51 | var headerTokens = input.Split('|');
52 | return (from header in headerTokens
53 | let n = header.IndexOf(':')
54 | where n != -1
55 | select new KeyValuePair(
56 | header.Substring(0, n).Trim(),
57 | header.Substring(n + 1).Trim())
58 | ).ToList();
59 | }
60 |
61 | private ushort MakeRequest(Func action)
62 | {
63 | try
64 | {
65 | var response = action.Invoke();
66 | if (response == null)
67 | {
68 | Debug.WriteError("HTTPS response object was null.");
69 | return 0;
70 | }
71 |
72 | // Some HTTP(S) responses will not have a message body.
73 | if (response.Content == null)
74 | {
75 | OnSimplHttpsClientResponse(response.Status, response.ResponseUrl, string.Empty, 0);
76 | }
77 | else
78 | {
79 | foreach (var contentChunk in response.Content.SplitIntoChunks(255))
80 | {
81 | OnSimplHttpsClientResponse(response.Status, response.ResponseUrl, contentChunk, response.Content.Length);
82 | CrestronEnvironment.Sleep(10); // allow a little bit for things to process
83 | }
84 | }
85 |
86 | return (ushort)response.Status;
87 | }
88 | catch (Exception ex)
89 | {
90 | Debug.WriteException(ex);
91 | return 0;
92 | }
93 | }
94 |
95 | public ushort SendGet(string url, string headers)
96 | {
97 | return MakeRequest(() => _httpsClientPool.Get(url, ParseHeaders(headers)));
98 | }
99 |
100 | public ushort SendPost(string url, string headers, string content)
101 | {
102 | return MakeRequest(() => _httpsClientPool.Post(url, ParseHeaders(headers), content.NullIfEmpty()));
103 | }
104 |
105 | public ushort SendPut(string url, string headers, string content)
106 | {
107 | return MakeRequest(() => _httpsClientPool.Put(url, ParseHeaders(headers), content.NullIfEmpty()));
108 | }
109 |
110 | public ushort SendDelete(string url, string headers, string content)
111 | {
112 | return MakeRequest(() => _httpsClientPool.Delete(url, ParseHeaders(headers), content.NullIfEmpty()));
113 | }
114 |
115 | public override string ToString()
116 | {
117 | return _moduleIdentifier;
118 | }
119 | }
120 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Troy Garner
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HttpsUtility
2 | A basic HTTPS utility S# module for general use where simple secure web requests are necessary, but complex chains of requests involving cookies, and response parsing is not. This module was intended for simple functionality only, where a custom solution is not needed.
3 |
4 | [](https://sharptoothcode.com) [](https://github.com/bitm0de/HttpsUtility/releases) [](https://github.com/bitm0de/HttpsUtility/releases) [](https://github.com/bitm0de/HttpsUtility/issues) [](https://github.com/bitm0de/HttpsUtility/blob/master/LICENSE)
5 |
6 | ## Compatibility
7 | | Controller | Supported |
8 | | ----------- | ------------------- |
9 | | MC3 | No Longer Supported |
10 |
11 | ## Information
12 | Multiple headers are supported, the formatting for sending multiple headers to the public functions requires each header to be separated by a `|` character.
13 |
14 | Example:
15 | ```Accept: application/json|Content-Type: application/json```
16 |
17 | ## Generated API (Intended for use by SIMPL+)
18 | ```cs
19 | namespace HttpsUtility.Symbols
20 | {
21 | // note: type can be instantiated from SIMPL+
22 | class SimplHttpsClient
23 | {
24 | // class properties
25 | // RegisterDelegate(obj, SimplHttpsClientResponse, SimplHttpsClientResponseHandler);
26 | // CALLBACK FUNCTION SimplHttpsClientResponseHandler(INTEGER status, STRING responseUrl, STRING content, INTEGER length);
27 | DelegateProperty SimplHttpsClientResponseDelegate SimplHttpsClientResponse(INTEGER status, STRING responseUrl, STRING content, INTEGER length);
28 |
29 | // class methods
30 | INTEGER_FUNCTION SendGet(STRING url, STRING headers);
31 | INTEGER_FUNCTION SendPost(STRING url, STRING headers, STRING content);
32 | INTEGER_FUNCTION SendPut(STRING url, STRING headers, STRING content);
33 | INTEGER_FUNCTION SendDelete(STRING url, STRING headers, STRING content);
34 | STRING_FUNCTION ToString();
35 | SIGNED_LONG_INTEGER_FUNCTION GetHashCode();
36 | }
37 | }
38 | ```
39 |
40 | ## Downloads
41 |
42 | * Note: I have no direct affiliation with "SharptoothCode" anymore due to employment changes. I do still have full control over maintaining this repository however. (Current releases on Github will contain the relevant SIMPL Windows and SIMPL+ module files.)
43 |
44 | Latest release is available on the releases section: https://github.com/bitm0de/HttpsUtility/releases
45 |
--------------------------------------------------------------------------------