Skip to content

Commit 8d7675a

Browse files
miya789mjcheetham
andcommitted
http: CurlCookie as a separate file
based on the review Co-authored-by: Matthew John Cheetham <[email protected]>
1 parent b74f9ab commit 8d7675a

File tree

2 files changed

+84
-76
lines changed

2 files changed

+84
-76
lines changed

src/shared/Core/CurlCookie.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Net;
4+
using GitCredentialManager;
5+
6+
namespace CurlCookie
7+
{
8+
public class CurlCookieParser
9+
{
10+
private readonly ITrace _trace;
11+
12+
public CurlCookieParser(ITrace trace)
13+
{
14+
_trace = trace;
15+
}
16+
17+
public IList<Cookie> Parse(string content)
18+
{
19+
if (string.IsNullOrWhiteSpace(content))
20+
{
21+
return Array.Empty<Cookie>();
22+
}
23+
24+
const string HttpOnlyPrefix = "#HttpOnly_";
25+
26+
var cookies = new List<Cookie>();
27+
28+
// Parse the cookie file content
29+
var lines = content.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
30+
foreach (var line in lines)
31+
{
32+
var parts = line.Split(new[] { '\t' }, StringSplitOptions.None);
33+
if (parts.Length >= 7 && (!parts[0].StartsWith("#") || parts[0].StartsWith(HttpOnlyPrefix)))
34+
{
35+
var domain = parts[0].StartsWith(HttpOnlyPrefix) ? parts[0].Substring(HttpOnlyPrefix.Length) : parts[0];
36+
var includeSubdomains = parts[1] == "TRUE";
37+
if (!includeSubdomains)
38+
{
39+
domain = domain.TrimStart('.');
40+
}
41+
var path = parts[2] == "" ? "/" : parts[2];
42+
var secureOnly = parts[3].Equals("TRUE", StringComparison.OrdinalIgnoreCase);
43+
var expires = ParseExpires(parts[4]);
44+
var name = parts[5];
45+
var value = parts[6];
46+
47+
cookies.Add(new Cookie()
48+
{
49+
Domain = domain,
50+
Path = path,
51+
Expires = expires,
52+
HttpOnly = true,
53+
Secure = secureOnly,
54+
Name = name,
55+
Value = value,
56+
});
57+
}
58+
else
59+
{
60+
_trace.WriteLine($"Invalid cookie line: {line}");
61+
}
62+
}
63+
64+
return cookies;
65+
}
66+
67+
private static DateTime ParseExpires(string expires)
68+
{
69+
#if NETFRAMEWORK
70+
DateTime epoch = new DateTime(1970, 01, 01, 0, 0, 0, DateTimeKind.Utc);
71+
#else
72+
DateTime epoch = DateTime.UnixEpoch;
73+
#endif
74+
75+
if (long.TryParse(expires, out long i))
76+
{
77+
return epoch.AddSeconds(i);
78+
}
79+
80+
return epoch;
81+
}
82+
}
83+
}

src/shared/Core/HttpClientFactory.cs

Lines changed: 1 addition & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Net.Http.Headers;
88
using System.Net.Security;
99
using System.Security.Cryptography.X509Certificates;
10+
using CurlCookie;
1011

1112
namespace GitCredentialManager
1213
{
@@ -328,81 +329,5 @@ public bool TryCreateProxy(out IWebProxy proxy)
328329
proxy = null;
329330
return false;
330331
}
331-
332-
public class CurlCookieParser
333-
{
334-
private readonly ITrace _trace;
335-
336-
public CurlCookieParser(ITrace trace)
337-
{
338-
_trace = trace;
339-
}
340-
341-
public IList<Cookie> Parse(string content)
342-
{
343-
if (string.IsNullOrWhiteSpace(content))
344-
{
345-
return Array.Empty<Cookie>();
346-
}
347-
348-
const string HttpOnlyPrefix = "#HttpOnly_";
349-
350-
var cookies = new List<Cookie>();
351-
352-
// Parse the cookie file content
353-
var lines = content.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
354-
foreach (var line in lines)
355-
{
356-
var parts = line.Split(new[] { '\t' }, StringSplitOptions.None);
357-
if (parts.Length >= 7 && (!parts[0].StartsWith("#") || parts[0].StartsWith(HttpOnlyPrefix)))
358-
{
359-
var domain = parts[0].StartsWith(HttpOnlyPrefix) ? parts[0].Substring(HttpOnlyPrefix.Length) : parts[0];
360-
var includeSubdomains = parts[1] == "TRUE";
361-
if (!includeSubdomains)
362-
{
363-
domain = domain.TrimStart('.');
364-
}
365-
var path = parts[2] == "" ? "/" : parts[2];
366-
var secureOnly = parts[3].Equals("TRUE", StringComparison.OrdinalIgnoreCase);
367-
var expires = ParseExpires(parts[4]);
368-
var name = parts[5];
369-
var value = parts[6];
370-
371-
cookies.Add(new Cookie()
372-
{
373-
Domain = domain,
374-
Path = path,
375-
Expires = expires,
376-
HttpOnly = true,
377-
Secure = secureOnly,
378-
Name = name,
379-
Value = value,
380-
});
381-
}
382-
else
383-
{
384-
_trace.WriteLine($"Invalid cookie line: {line}");
385-
}
386-
}
387-
388-
return cookies;
389-
}
390-
391-
private static DateTime ParseExpires(string expires)
392-
{
393-
#if NETFRAMEWORK
394-
DateTime epoch = new DateTime(1970, 01, 01, 0, 0, 0, DateTimeKind.Utc);
395-
#else
396-
DateTime epoch = DateTime.UnixEpoch;
397-
#endif
398-
399-
if (long.TryParse(expires, out long i))
400-
{
401-
return epoch.AddSeconds(i);
402-
}
403-
404-
return epoch;
405-
}
406-
}
407332
}
408333
}

0 commit comments

Comments
 (0)