Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
T
Titanium-Web-Proxy
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Titanium-Web-Proxy
Commits
1a2a9546
Commit
1a2a9546
authored
Oct 13, 2019
by
Honfika
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Header improvements (part 1)
parent
5497aa64
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
74 additions
and
36 deletions
+74
-36
ExceptionHandler.cs
src/Titanium.Web.Proxy/ExceptionHandler.cs
+1
-1
StringExtensions.cs
src/Titanium.Web.Proxy/Extensions/StringExtensions.cs
+5
-0
HttpHelper.cs
src/Titanium.Web.Proxy/Helpers/HttpHelper.cs
+2
-0
HttpWriter.cs
src/Titanium.Web.Proxy/Helpers/HttpWriter.cs
+3
-3
HttpWebClient.cs
src/Titanium.Web.Proxy/Http/HttpWebClient.cs
+4
-3
Request.cs
src/Titanium.Web.Proxy/Http/Request.cs
+20
-12
Response.cs
src/Titanium.Web.Proxy/Http/Response.cs
+23
-6
ProxyAuthorizationHandler.cs
src/Titanium.Web.Proxy/ProxyAuthorizationHandler.cs
+14
-9
ProxyConstants.cs
src/Titanium.Web.Proxy/Shared/ProxyConstants.cs
+0
-1
CustomBufferedStream.cs
....Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs
+2
-1
No files found.
src/Titanium.Web.Proxy/ExceptionHandler.cs
View file @
1a2a9546
using
System
;
using
System
;
namespace
Titanium.Web.Proxy
namespace
Titanium.Web.Proxy
{
{
...
...
src/Titanium.Web.Proxy/Extensions/StringExtensions.cs
View file @
1a2a9546
...
@@ -10,6 +10,11 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -10,6 +10,11 @@ namespace Titanium.Web.Proxy.Extensions
return
str
.
Equals
(
value
,
StringComparison
.
CurrentCultureIgnoreCase
);
return
str
.
Equals
(
value
,
StringComparison
.
CurrentCultureIgnoreCase
);
}
}
internal
static
bool
EqualsIgnoreCase
(
this
ReadOnlySpan
<
char
>
str
,
ReadOnlySpan
<
char
>
value
)
{
return
str
.
Equals
(
value
,
StringComparison
.
CurrentCultureIgnoreCase
);
}
internal
static
bool
ContainsIgnoreCase
(
this
string
str
,
string
value
)
internal
static
bool
ContainsIgnoreCase
(
this
string
str
,
string
value
)
{
{
return
CultureInfo
.
CurrentCulture
.
CompareInfo
.
IndexOf
(
str
,
value
,
CompareOptions
.
IgnoreCase
)
>=
0
;
return
CultureInfo
.
CurrentCulture
.
CompareInfo
.
IndexOf
(
str
,
value
,
CompareOptions
.
IgnoreCase
)
>=
0
;
...
...
src/Titanium.Web.Proxy/Helpers/HttpHelper.cs
View file @
1a2a9546
...
@@ -16,6 +16,8 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -16,6 +16,8 @@ namespace Titanium.Web.Proxy.Helpers
{
{
private
static
readonly
Encoding
defaultEncoding
=
Encoding
.
GetEncoding
(
"ISO-8859-1"
);
private
static
readonly
Encoding
defaultEncoding
=
Encoding
.
GetEncoding
(
"ISO-8859-1"
);
public
static
Encoding
HeaderEncoding
=>
defaultEncoding
;
/// <summary>
/// <summary>
/// Gets the character encoding of request/response from content-type header
/// Gets the character encoding of request/response from content-type header
/// </summary>
/// </summary>
...
...
src/Titanium.Web.Proxy/Helpers/HttpWriter.cs
View file @
1a2a9546
...
@@ -18,7 +18,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -18,7 +18,7 @@ namespace Titanium.Web.Proxy.Helpers
private
static
readonly
byte
[]
newLine
=
ProxyConstants
.
NewLineBytes
;
private
static
readonly
byte
[]
newLine
=
ProxyConstants
.
NewLineBytes
;
private
static
readonly
Encoding
encoder
=
Encoding
.
ASCII
;
private
static
Encoding
encoding
=>
HttpHelper
.
HeaderEncoding
;
internal
HttpWriter
(
Stream
stream
,
IBufferPool
bufferPool
)
internal
HttpWriter
(
Stream
stream
,
IBufferPool
bufferPool
)
{
{
...
@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy.Helpers
var
buffer
=
bufferPool
.
GetBuffer
();
var
buffer
=
bufferPool
.
GetBuffer
();
try
try
{
{
int
idx
=
encod
er
.
GetBytes
(
value
,
0
,
charCount
,
buffer
,
0
);
int
idx
=
encod
ing
.
GetBytes
(
value
,
0
,
charCount
,
buffer
,
0
);
if
(
newLineChars
>
0
)
if
(
newLineChars
>
0
)
{
{
Buffer
.
BlockCopy
(
newLine
,
0
,
buffer
,
idx
,
newLineChars
);
Buffer
.
BlockCopy
(
newLine
,
0
,
buffer
,
idx
,
newLineChars
);
...
@@ -67,7 +67,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -67,7 +67,7 @@ namespace Titanium.Web.Proxy.Helpers
else
else
{
{
var
buffer
=
new
byte
[
charCount
+
newLineChars
+
1
];
var
buffer
=
new
byte
[
charCount
+
newLineChars
+
1
];
int
idx
=
encod
er
.
GetBytes
(
value
,
0
,
charCount
,
buffer
,
0
);
int
idx
=
encod
ing
.
GetBytes
(
value
,
0
,
charCount
,
buffer
,
0
);
if
(
newLineChars
>
0
)
if
(
newLineChars
>
0
)
{
{
Buffer
.
BlockCopy
(
newLine
,
0
,
buffer
,
idx
,
newLineChars
);
Buffer
.
BlockCopy
(
newLine
,
0
,
buffer
,
idx
,
newLineChars
);
...
...
src/Titanium.Web.Proxy/Http/HttpWebClient.cs
View file @
1a2a9546
...
@@ -107,11 +107,12 @@ namespace Titanium.Web.Proxy.Http
...
@@ -107,11 +107,12 @@ namespace Titanium.Web.Proxy.Http
url
=
Request
.
RequestUri
.
GetOriginalPathAndQuery
();
url
=
Request
.
RequestUri
.
GetOriginalPathAndQuery
();
}
}
var
headerBuilder
=
new
StringBuilder
();
// prepare the request & headers
// prepare the request & headers
await
writer
.
WriteLineAsync
(
Request
.
CreateRequestLine
(
Request
.
Method
,
url
,
Request
.
HttpVersion
),
cancellationToken
);
headerBuilder
.
Append
(
Request
.
CreateRequestLine
(
Request
.
Method
,
url
,
Request
.
HttpVersion
));
headerBuilder
.
Append
(
ProxyConstants
.
NewLine
);
var
headerBuilder
=
new
StringBuilder
();
// Send Authentication to Upstream proxy if needed
// Send Authentication to Upstream proxy if needed
if
(!
isTransparent
&&
upstreamProxy
!=
null
if
(!
isTransparent
&&
upstreamProxy
!=
null
&&
Connection
.
IsHttps
==
false
&&
Connection
.
IsHttps
==
false
...
...
src/Titanium.Web.Proxy/Http/Request.cs
View file @
1a2a9546
...
@@ -158,7 +158,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -158,7 +158,7 @@ namespace Titanium.Web.Proxy.Http
sb
.
Append
(
$"
{
CreateRequestLine
(
Method
,
RequestUriString
,
HttpVersion
)}{
ProxyConstants
.
NewLine
}
"
);
sb
.
Append
(
$"
{
CreateRequestLine
(
Method
,
RequestUriString
,
HttpVersion
)}{
ProxyConstants
.
NewLine
}
"
);
foreach
(
var
header
in
Headers
)
foreach
(
var
header
in
Headers
)
{
{
sb
.
Append
(
$"
{
header
.
ToString
()
}{
ProxyConstants
.
NewLine
}
"
);
sb
.
Append
(
$"
{
header
}{
ProxyConstants
.
NewLine
}
"
);
}
}
sb
.
Append
(
ProxyConstants
.
NewLine
);
sb
.
Append
(
ProxyConstants
.
NewLine
);
...
@@ -205,30 +205,38 @@ namespace Titanium.Web.Proxy.Http
...
@@ -205,30 +205,38 @@ namespace Titanium.Web.Proxy.Http
internal
static
void
ParseRequestLine
(
string
httpCmd
,
out
string
httpMethod
,
out
string
httpUrl
,
internal
static
void
ParseRequestLine
(
string
httpCmd
,
out
string
httpMethod
,
out
string
httpUrl
,
out
Version
version
)
out
Version
version
)
{
{
// break up the line into three components (method, remote URL & Http Version)
int
firstSpace
=
httpCmd
.
IndexOf
(
' '
);
var
httpCmdSplit
=
httpCmd
.
Split
(
ProxyConstants
.
SpaceSplit
,
3
);
if
(
firstSpace
==
-
1
)
if
(
httpCmdSplit
.
Length
<
2
)
{
{
// does not contain at least 2 parts
throw
new
Exception
(
"Invalid HTTP request line: "
+
httpCmd
);
throw
new
Exception
(
"Invalid HTTP request line: "
+
httpCmd
);
}
}
int
lastSpace
=
httpCmd
.
LastIndexOf
(
' '
);
// break up the line into three components (method, remote URL & Http Version)
// Find the request Verb
// Find the request Verb
httpMethod
=
httpCmd
Split
[
0
]
;
httpMethod
=
httpCmd
.
Substring
(
0
,
firstSpace
)
;
if
(!
isAllUpper
(
httpMethod
))
if
(!
isAllUpper
(
httpMethod
))
{
{
httpMethod
=
httpMethod
.
ToUpper
();
httpMethod
=
httpMethod
.
ToUpper
();
}
}
httpUrl
=
httpCmdSplit
[
1
];
// parse the HTTP version
version
=
HttpHeader
.
Version11
;
version
=
HttpHeader
.
Version11
;
if
(
httpCmdSplit
.
Length
==
3
)
if
(
firstSpace
==
lastSpace
)
{
{
string
httpVersion
=
httpCmdSplit
[
2
].
Trim
();
httpUrl
=
httpCmd
.
AsSpan
(
firstSpace
+
1
).
ToString
();
}
else
{
httpUrl
=
httpCmd
.
AsSpan
(
firstSpace
+
1
,
lastSpace
-
firstSpace
-
1
).
ToString
();
// parse the HTTP version
var
httpVersion
=
httpCmd
.
AsSpan
(
lastSpace
+
1
);
if
(
httpVersion
.
EqualsIgnoreCase
(
"HTTP/1.0"
))
if
(
httpVersion
.
EqualsIgnoreCase
(
"HTTP/1.0"
.
AsSpan
(
0
)
))
{
{
version
=
HttpHeader
.
Version10
;
version
=
HttpHeader
.
Version10
;
}
}
...
...
src/Titanium.Web.Proxy/Http/Response.cs
View file @
1a2a9546
...
@@ -134,22 +134,39 @@ namespace Titanium.Web.Proxy.Http
...
@@ -134,22 +134,39 @@ namespace Titanium.Web.Proxy.Http
internal
static
void
ParseResponseLine
(
string
httpStatus
,
out
Version
version
,
out
int
statusCode
,
internal
static
void
ParseResponseLine
(
string
httpStatus
,
out
Version
version
,
out
int
statusCode
,
out
string
statusDescription
)
out
string
statusDescription
)
{
{
var
httpResult
=
httpStatus
.
Split
(
ProxyConstants
.
SpaceSplit
,
3
);
int
firstSpace
=
httpStatus
.
IndexOf
(
' '
);
if
(
httpResult
.
Length
<=
1
)
if
(
firstSpace
==
-
1
)
{
{
throw
new
Exception
(
"Invalid HTTP status line: "
+
httpStatus
);
throw
new
Exception
(
"Invalid HTTP status line: "
+
httpStatus
);
}
}
string
httpVersion
=
httpResult
[
0
]
;
var
httpVersion
=
httpStatus
.
AsSpan
(
0
,
firstSpace
)
;
version
=
HttpHeader
.
Version11
;
version
=
HttpHeader
.
Version11
;
if
(
httpVersion
.
EqualsIgnoreCase
(
"HTTP/1.0"
))
if
(
httpVersion
.
EqualsIgnoreCase
(
"HTTP/1.0"
.
AsSpan
()
))
{
{
version
=
HttpHeader
.
Version10
;
version
=
HttpHeader
.
Version10
;
}
}
statusCode
=
int
.
Parse
(
httpResult
[
1
]);
int
secondSpace
=
httpStatus
.
IndexOf
(
' '
,
firstSpace
+
1
);
statusDescription
=
httpResult
.
Length
>
2
?
httpResult
[
2
]
:
string
.
Empty
;
if
(
secondSpace
!=
-
1
)
{
#if NETSTANDARD2_1
statusCode
=
int
.
Parse
(
httpStatus
.
AsSpan
(
firstSpace
+
1
,
secondSpace
-
firstSpace
-
1
));
#else
statusCode
=
int
.
Parse
(
httpStatus
.
AsSpan
(
firstSpace
+
1
,
secondSpace
-
firstSpace
-
1
).
ToString
());
#endif
statusDescription
=
httpStatus
.
AsSpan
(
secondSpace
+
1
).
ToString
();
}
else
{
#if NETSTANDARD2_1
statusCode
=
int
.
Parse
(
httpStatus
.
AsSpan
(
firstSpace
+
1
));
#else
statusCode
=
int
.
Parse
(
httpStatus
.
AsSpan
(
firstSpace
+
1
).
ToString
());
#endif
statusDescription
=
string
.
Empty
;
}
}
}
}
}
}
}
src/Titanium.Web.Proxy/ProxyAuthorizationHandler.cs
View file @
1a2a9546
...
@@ -30,30 +30,35 @@ namespace Titanium.Web.Proxy
...
@@ -30,30 +30,35 @@ namespace Titanium.Web.Proxy
try
try
{
{
var
header
=
httpHeaders
.
GetFirstHeader
(
KnownHeaders
.
ProxyAuthorization
);
var
header
Obj
=
httpHeaders
.
GetFirstHeader
(
KnownHeaders
.
ProxyAuthorization
);
if
(
header
==
null
)
if
(
header
Obj
==
null
)
{
{
session
.
HttpClient
.
Response
=
createAuthentication407Response
(
"Proxy Authentication Required"
);
session
.
HttpClient
.
Response
=
createAuthentication407Response
(
"Proxy Authentication Required"
);
return
false
;
return
false
;
}
}
var
headerValueParts
=
header
.
Value
.
Split
(
ProxyConstants
.
SpaceSplit
);
string
header
=
headerObj
.
Value
;
int
firstSpace
=
header
.
IndexOf
(
' '
);
if
(
headerValueParts
.
Length
!=
2
)
// header value should contain exactly 1 space
if
(
firstSpace
==
-
1
||
header
.
IndexOf
(
' '
,
firstSpace
+
1
)
!=
-
1
)
{
{
// Return not authorized
// Return not authorized
session
.
HttpClient
.
Response
=
createAuthentication407Response
(
"Proxy Authentication Invalid"
);
session
.
HttpClient
.
Response
=
createAuthentication407Response
(
"Proxy Authentication Invalid"
);
return
false
;
return
false
;
}
}
var
authenticationType
=
header
.
AsMemory
(
0
,
firstSpace
);
var
credentials
=
header
.
AsMemory
(
firstSpace
+
1
);
if
(
ProxyBasicAuthenticateFunc
!=
null
)
if
(
ProxyBasicAuthenticateFunc
!=
null
)
{
{
return
await
authenticateUserBasic
(
session
,
headerValuePart
s
);
return
await
authenticateUserBasic
(
session
,
authenticationType
,
credential
s
);
}
}
if
(
ProxySchemeAuthenticateFunc
!=
null
)
if
(
ProxySchemeAuthenticateFunc
!=
null
)
{
{
var
result
=
await
ProxySchemeAuthenticateFunc
(
session
,
headerValueParts
[
0
],
headerValueParts
[
1
]
);
var
result
=
await
ProxySchemeAuthenticateFunc
(
session
,
authenticationType
.
ToString
(),
credentials
.
ToString
()
);
if
(
result
.
Result
==
ProxyAuthenticationResult
.
ContinuationNeeded
)
if
(
result
.
Result
==
ProxyAuthenticationResult
.
ContinuationNeeded
)
{
{
...
@@ -78,16 +83,16 @@ namespace Titanium.Web.Proxy
...
@@ -78,16 +83,16 @@ namespace Titanium.Web.Proxy
}
}
}
}
private
async
Task
<
bool
>
authenticateUserBasic
(
SessionEventArgsBase
session
,
string
[]
headerValuePart
s
)
private
async
Task
<
bool
>
authenticateUserBasic
(
SessionEventArgsBase
session
,
ReadOnlyMemory
<
char
>
authenticationType
,
ReadOnlyMemory
<
char
>
credential
s
)
{
{
if
(!
headerValueParts
[
0
].
EqualsIgnoreCase
(
KnownHeaders
.
ProxyAuthorizationBasic
))
if
(!
authenticationType
.
Span
.
EqualsIgnoreCase
(
KnownHeaders
.
ProxyAuthorizationBasic
.
AsSpan
()
))
{
{
// Return not authorized
// Return not authorized
session
.
HttpClient
.
Response
=
createAuthentication407Response
(
"Proxy Authentication Invalid"
);
session
.
HttpClient
.
Response
=
createAuthentication407Response
(
"Proxy Authentication Invalid"
);
return
false
;
return
false
;
}
}
string
decoded
=
Encoding
.
UTF8
.
GetString
(
Convert
.
FromBase64String
(
headerValueParts
[
1
]
));
string
decoded
=
Encoding
.
UTF8
.
GetString
(
Convert
.
FromBase64String
(
credentials
.
ToString
()
));
int
colonIndex
=
decoded
.
IndexOf
(
':'
);
int
colonIndex
=
decoded
.
IndexOf
(
':'
);
if
(
colonIndex
==
-
1
)
if
(
colonIndex
==
-
1
)
{
{
...
...
src/Titanium.Web.Proxy/Shared/ProxyConstants.cs
View file @
1a2a9546
...
@@ -12,7 +12,6 @@ namespace Titanium.Web.Proxy.Shared
...
@@ -12,7 +12,6 @@ namespace Titanium.Web.Proxy.Shared
{
{
internal
static
readonly
char
DotSplit
=
'.'
;
internal
static
readonly
char
DotSplit
=
'.'
;
internal
static
readonly
char
[]
SpaceSplit
=
{
' '
};
internal
static
readonly
char
[]
ColonSplit
=
{
':'
};
internal
static
readonly
char
[]
ColonSplit
=
{
':'
};
internal
static
readonly
char
[]
SemiColonSplit
=
{
';'
};
internal
static
readonly
char
[]
SemiColonSplit
=
{
';'
};
internal
static
readonly
char
[]
EqualSplit
=
{
'='
};
internal
static
readonly
char
[]
EqualSplit
=
{
'='
};
...
...
src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs
View file @
1a2a9546
...
@@ -5,6 +5,7 @@ using System.Net.Sockets;
...
@@ -5,6 +5,7 @@ using System.Net.Sockets;
using
System.Text
;
using
System.Text
;
using
System.Threading
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.StreamExtended.BufferPool
;
using
Titanium.Web.Proxy.StreamExtended.BufferPool
;
namespace
Titanium.Web.Proxy.StreamExtended.Network
namespace
Titanium.Web.Proxy.StreamExtended.Network
...
@@ -21,7 +22,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
...
@@ -21,7 +22,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
private
byte
[]
streamBuffer
;
private
byte
[]
streamBuffer
;
// default to UTF-8
// default to UTF-8
private
static
readonly
Encoding
encoding
=
Encoding
.
UTF8
;
private
static
Encoding
encoding
=>
HttpHelper
.
HeaderEncoding
;
private
static
readonly
bool
networkStreamHack
=
true
;
private
static
readonly
bool
networkStreamHack
=
true
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment