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
f8d876c6
Commit
f8d876c6
authored
Mar 24, 2018
by
Honfika
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
baseclass for request and response
parent
17762053
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
207 additions
and
344 deletions
+207
-344
CompressionFactory.cs
Titanium.Web.Proxy/Compression/CompressionFactory.cs
+3
-2
DecompressionFactory.cs
Titanium.Web.Proxy/Decompression/DecompressionFactory.cs
+3
-2
SessionEventArgs.cs
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+8
-8
KnownHeaders.cs
Titanium.Web.Proxy/Http/KnownHeaders.cs
+2
-0
Request.cs
Titanium.Web.Proxy/Http/Request.cs
+5
-167
RequestResponseBase.cs
Titanium.Web.Proxy/Http/RequestResponseBase.cs
+178
-0
Response.cs
Titanium.Web.Proxy/Http/Response.cs
+4
-161
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+2
-2
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+2
-2
No files found.
Titanium.Web.Proxy/Compression/CompressionFactory.cs
View file @
f8d876c6
using
System
;
using
Titanium.Web.Proxy.Http
;
namespace
Titanium.Web.Proxy.Compression
{
...
...
@@ -18,9 +19,9 @@ namespace Titanium.Web.Proxy.Compression
{
switch
(
type
)
{
case
"gzip"
:
case
KnownHeaders
.
ContentEncodingGzip
:
return
gzip
.
Value
;
case
"deflate"
:
case
KnownHeaders
.
ContentEncodingDeflate
:
return
deflate
.
Value
;
default
:
return
def
.
Value
;
...
...
Titanium.Web.Proxy/Decompression/DecompressionFactory.cs
View file @
f8d876c6
using
System
;
using
Titanium.Web.Proxy.Http
;
namespace
Titanium.Web.Proxy.Decompression
{
...
...
@@ -18,9 +19,9 @@ namespace Titanium.Web.Proxy.Decompression
{
switch
(
type
)
{
case
"gzip"
:
case
KnownHeaders
.
ContentEncodingGzip
:
return
gzip
.
Value
;
case
"deflate"
:
case
KnownHeaders
.
ContentEncodingDeflate
:
return
deflate
.
Value
;
default
:
return
def
.
Value
;
...
...
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
f8d876c6
...
...
@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
private
async
Task
ReadResponseBodyAsync
()
{
if
(!
WebSession
.
Request
.
Request
Locked
)
if
(!
WebSession
.
Request
.
Locked
)
{
throw
new
Exception
(
"You cannot read the response body before request is made to server."
);
}
...
...
@@ -453,7 +453,7 @@ namespace Titanium.Web.Proxy.EventArguments
public
async
Task
SetRequestBody
(
byte
[]
body
)
{
var
request
=
WebSession
.
Request
;
if
(
request
.
Request
Locked
)
if
(
request
.
Locked
)
{
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
}
...
...
@@ -474,7 +474,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body"></param>
public
async
Task
SetRequestBodyString
(
string
body
)
{
if
(
WebSession
.
Request
.
Request
Locked
)
if
(
WebSession
.
Request
.
Locked
)
{
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
}
...
...
@@ -522,7 +522,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body"></param>
public
async
Task
SetResponseBody
(
byte
[]
body
)
{
if
(!
WebSession
.
Request
.
Request
Locked
)
if
(!
WebSession
.
Request
.
Locked
)
{
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
}
...
...
@@ -547,7 +547,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body"></param>
public
async
Task
SetResponseBodyString
(
string
body
)
{
if
(!
WebSession
.
Request
.
Request
Locked
)
if
(!
WebSession
.
Request
.
Locked
)
{
throw
new
Exception
(
"You cannot call this function before request is made to server."
);
}
...
...
@@ -659,14 +659,14 @@ namespace Titanium.Web.Proxy.EventArguments
/// a generic responder method
public
void
Respond
(
Response
response
)
{
if
(
WebSession
.
Request
.
Request
Locked
)
if
(
WebSession
.
Request
.
Locked
)
{
throw
new
Exception
(
"You cannot call this function after request is made to server."
);
}
WebSession
.
Request
.
Request
Locked
=
true
;
WebSession
.
Request
.
Locked
=
true
;
response
.
Response
Locked
=
true
;
response
.
Locked
=
true
;
response
.
IsBodyRead
=
true
;
WebSession
.
Response
=
response
;
...
...
Titanium.Web.Proxy/Http/KnownHeaders.cs
View file @
f8d876c6
...
...
@@ -40,6 +40,8 @@ namespace Titanium.Web.Proxy.Http
// Response headers
public
const
string
ContentEncoding
=
"content-encoding"
;
public
const
string
ContentEncodingDeflate
=
"deflate"
;
public
const
string
ContentEncodingGzip
=
"gzip"
;
public
const
string
Location
=
"Location"
;
...
...
Titanium.Web.Proxy/Http/Request.cs
View file @
f8d876c6
...
...
@@ -3,28 +3,17 @@ using System.ComponentModel;
using
System.Text
;
using
Titanium.Web.Proxy.Exceptions
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Shared
;
namespace
Titanium.Web.Proxy.Http
{
/// <summary>
///
A HTTP(S
) request object
///
Http(s
) request object
/// </summary>
[
TypeConverter
(
typeof
(
ExpandableObjectConverter
))]
public
class
Request
public
class
Request
:
RequestResponseBase
{
/// <summary>
/// Cached request body as byte array
/// </summary>
private
byte
[]
body
;
/// <summary>
/// Cached request body as string
/// </summary>
private
string
bodyString
;
/// <summary>
/// Request Method
/// </summary>
...
...
@@ -45,16 +34,6 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
public
string
OriginalUrl
{
get
;
set
;
}
/// <summary>
/// Request Http Version
/// </summary>
public
Version
HttpVersion
{
get
;
set
;
}
/// <summary>
/// Keeps the request body data after the session is finished
/// </summary>
public
bool
KeepBody
{
get
;
set
;
}
/// <summary>
/// Has request body?
/// </summary>
...
...
@@ -97,80 +76,6 @@ namespace Titanium.Web.Proxy.Http
set
=>
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
Host
,
value
);
}
/// <summary>
/// Content encoding header value
/// </summary>
public
string
ContentEncoding
=>
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentEncoding
);
/// <summary>
/// Request content-length
/// </summary>
public
long
ContentLength
{
get
{
string
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentLength
);
if
(
headerValue
==
null
)
{
return
-
1
;
}
long
.
TryParse
(
headerValue
,
out
long
contentLen
);
if
(
contentLen
>=
0
)
{
return
contentLen
;
}
return
-
1
;
}
set
{
if
(
value
>=
0
)
{
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
ContentLength
,
value
.
ToString
());
IsChunked
=
false
;
}
else
{
Headers
.
RemoveHeader
(
KnownHeaders
.
ContentLength
);
}
}
}
/// <summary>
/// Request content-type
/// </summary>
public
string
ContentType
{
get
=>
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentType
);
set
=>
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
ContentType
,
value
);
}
/// <summary>
/// Is request body send as chunked bytes
/// </summary>
public
bool
IsChunked
{
get
{
string
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
TransferEncoding
);
return
headerValue
!=
null
&&
headerValue
.
ContainsIgnoreCase
(
KnownHeaders
.
TransferEncodingChunked
);
}
set
{
if
(
value
)
{
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
TransferEncoding
,
KnownHeaders
.
TransferEncodingChunked
);
ContentLength
=
-
1
;
}
else
{
Headers
.
RemoveHeader
(
KnownHeaders
.
TransferEncoding
);
}
}
}
/// <summary>
/// Does this request has a 100-continue header?
/// </summary>
...
...
@@ -190,17 +95,12 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
public
string
Url
=>
RequestUri
.
OriginalString
;
/// <summary>
/// Encoding for this request
/// </summary>
public
Encoding
Encoding
=>
HttpHelper
.
GetEncodingFromContentType
(
ContentType
);
/// <summary>
/// Terminates the underlying Tcp Connection to client after current request
/// </summary>
internal
bool
CancelRequest
{
get
;
set
;
}
internal
void
EnsureBodyAvailable
(
bool
throwWhenNotReadYet
=
true
)
internal
override
void
EnsureBodyAvailable
(
bool
throwWhenNotReadYet
=
true
)
{
//GET request don't have a request body to read
if
(!
HasBody
)
...
...
@@ -211,7 +111,7 @@ namespace Titanium.Web.Proxy.Http
if
(!
IsBodyRead
)
{
if
(
Request
Locked
)
if
(
Locked
)
{
throw
new
Exception
(
"You cannot get the request body after request is made to server."
);
}
...
...
@@ -225,41 +125,6 @@ namespace Titanium.Web.Proxy.Http
}
}
/// <summary>
/// Request body as byte array
/// </summary>
[
Browsable
(
false
)]
public
byte
[]
Body
{
get
{
EnsureBodyAvailable
();
return
body
;
}
internal
set
{
body
=
value
;
bodyString
=
null
;
}
}
/// <summary>
/// Request body as string
/// Use the encoding specified in request to decode the byte[] data to string
/// </summary>
[
Browsable
(
false
)]
public
string
BodyString
=>
bodyString
??
(
bodyString
=
Encoding
.
GetString
(
Body
));
/// <summary>
/// Request body was read by user?
/// </summary>
public
bool
IsBodyRead
{
get
;
internal
set
;
}
/// <summary>
/// Request is ready to be sent (user callbacks are complete?)
/// </summary>
internal
bool
RequestLocked
{
get
;
set
;
}
/// <summary>
/// Does this request has an upgrade to websocket header?
/// </summary>
...
...
@@ -278,11 +143,6 @@ namespace Titanium.Web.Proxy.Http
}
}
/// <summary>
/// Request header collection
/// </summary>
public
HeaderCollection
Headers
{
get
;
}
=
new
HeaderCollection
();
/// <summary>
/// Does server responsed positively for 100 continue request
/// </summary>
...
...
@@ -296,7 +156,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// Gets the header text.
/// </summary>
public
string
HeaderText
public
override
string
HeaderText
{
get
{
...
...
@@ -367,27 +227,5 @@ namespace Titanium.Web.Proxy.Http
return
true
;
}
internal
void
UpdateContentLength
()
{
ContentLength
=
IsChunked
?
-
1
:
body
.
Length
;
}
/// <summary>
/// Finish the session
/// </summary>
public
void
FinishSession
()
{
if
(!
KeepBody
)
{
body
=
null
;
bodyString
=
null
;
}
}
public
override
string
ToString
()
{
return
HeaderText
;
}
}
}
Titanium.Web.Proxy/Http/RequestResponseBase.cs
0 → 100644
View file @
f8d876c6
using
System
;
using
System.Collections.Generic
;
using
System.ComponentModel
;
using
System.Linq
;
using
System.Text
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Models
;
namespace
Titanium.Web.Proxy.Http
{
public
abstract
class
RequestResponseBase
{
/// <summary>
/// Cached body content as byte array
/// </summary>
private
byte
[]
body
;
/// <summary>
/// Cached body as string
/// </summary>
private
string
bodyString
;
/// <summary>
/// Keeps the body data after the session is finished
/// </summary>
public
bool
KeepBody
{
get
;
set
;
}
/// <summary>
/// Http Version
/// </summary>
public
Version
HttpVersion
{
get
;
set
;
}
=
HttpHeader
.
VersionUnknown
;
/// <summary>
/// Collection of all headers
/// </summary>
public
HeaderCollection
Headers
{
get
;
}
=
new
HeaderCollection
();
/// <summary>
/// Length of the body
/// </summary>
public
long
ContentLength
{
get
{
string
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentLength
);
if
(
headerValue
==
null
)
{
return
-
1
;
}
if
(
long
.
TryParse
(
headerValue
,
out
long
contentLen
)
&&
contentLen
>=
0
)
{
return
contentLen
;
}
return
-
1
;
}
set
{
if
(
value
>=
0
)
{
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
ContentLength
,
value
.
ToString
());
IsChunked
=
false
;
}
else
{
Headers
.
RemoveHeader
(
KnownHeaders
.
ContentLength
);
}
}
}
/// <summary>
/// Content encoding for this request/response
/// </summary>
public
string
ContentEncoding
=>
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentEncoding
)?.
Trim
();
/// <summary>
/// Encoding for this request/response
/// </summary>
public
Encoding
Encoding
=>
HttpHelper
.
GetEncodingFromContentType
(
ContentType
);
/// <summary>
/// Content-type of the request/response
/// </summary>
public
string
ContentType
{
get
=>
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentType
);
set
=>
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
ContentType
,
value
);
}
/// <summary>
/// Is body send as chunked bytes
/// </summary>
public
bool
IsChunked
{
get
{
string
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
TransferEncoding
);
return
headerValue
!=
null
&&
headerValue
.
ContainsIgnoreCase
(
KnownHeaders
.
TransferEncodingChunked
);
}
set
{
if
(
value
)
{
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
TransferEncoding
,
KnownHeaders
.
TransferEncodingChunked
);
ContentLength
=
-
1
;
}
else
{
Headers
.
RemoveHeader
(
KnownHeaders
.
TransferEncoding
);
}
}
}
public
abstract
string
HeaderText
{
get
;
}
/// <summary>
/// Body as byte array
/// </summary>
[
Browsable
(
false
)]
public
byte
[]
Body
{
get
{
EnsureBodyAvailable
();
return
body
;
}
internal
set
{
body
=
value
;
bodyString
=
null
;
}
}
internal
abstract
void
EnsureBodyAvailable
(
bool
throwWhenNotReadYet
=
true
);
/// <summary>
/// Body as string
/// Use the encoding specified to decode the byte[] data to string
/// </summary>
[
Browsable
(
false
)]
public
string
BodyString
=>
bodyString
??
(
bodyString
=
Encoding
.
GetString
(
Body
));
/// <summary>
/// Was the body read by user?
/// </summary>
public
bool
IsBodyRead
{
get
;
internal
set
;
}
/// <summary>
/// Is the request/response no more modifyable by user (user callbacks complete?)
/// </summary>
internal
bool
Locked
{
get
;
set
;
}
internal
void
UpdateContentLength
()
{
ContentLength
=
IsChunked
?
-
1
:
body
.
Length
;
}
/// <summary>
/// Finish the session
/// </summary>
internal
void
FinishSession
()
{
if
(!
KeepBody
)
{
body
=
null
;
bodyString
=
null
;
}
}
public
override
string
ToString
()
{
return
HeaderText
;
}
}
}
Titanium.Web.Proxy/Http/Response.cs
View file @
f8d876c6
...
...
@@ -2,7 +2,6 @@
using
System.ComponentModel
;
using
System.Text
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Shared
;
...
...
@@ -12,18 +11,8 @@ namespace Titanium.Web.Proxy.Http
/// Http(s) response object
/// </summary>
[
TypeConverter
(
typeof
(
ExpandableObjectConverter
))]
public
class
Response
public
class
Response
:
RequestResponseBase
{
/// <summary>
/// Cached response body content as byte array
/// </summary>
private
byte
[]
body
;
/// <summary>
/// Cached response body as string
/// </summary>
private
string
bodyString
;
/// <summary>
/// Response Status Code.
/// </summary>
...
...
@@ -34,26 +23,6 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
public
string
StatusDescription
{
get
;
set
;
}
/// <summary>
/// Encoding used in response
/// </summary>
public
Encoding
Encoding
=>
HttpHelper
.
GetEncodingFromContentType
(
ContentType
);
/// <summary>
/// Content encoding for this response
/// </summary>
public
string
ContentEncoding
=>
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentEncoding
)?.
Trim
();
/// <summary>
/// Http version
/// </summary>
public
Version
HttpVersion
{
get
;
set
;
}
=
HttpHeader
.
VersionUnknown
;
/// <summary>
/// Keeps the response body data after the session is finished
/// </summary>
public
bool
KeepBody
{
get
;
set
;
}
/// <summary>
/// Has response body?
/// </summary>
...
...
@@ -108,78 +77,9 @@ namespace Titanium.Web.Proxy.Http
}
}
/// <summary>
/// Content type of this response
/// </summary>
public
string
ContentType
=>
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentType
);
/// <summary>
/// Length of response body
/// </summary>
public
long
ContentLength
{
get
{
string
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
ContentLength
);
if
(
headerValue
==
null
)
{
return
-
1
;
}
if
(
long
.
TryParse
(
headerValue
,
out
long
contentLen
))
{
return
contentLen
;
}
return
-
1
;
}
set
{
if
(
value
>=
0
)
{
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
ContentLength
,
value
.
ToString
());
IsChunked
=
false
;
}
else
{
Headers
.
RemoveHeader
(
KnownHeaders
.
ContentLength
);
}
}
}
/// <summary>
/// Response transfer-encoding is chunked?
/// </summary>
public
bool
IsChunked
internal
override
void
EnsureBodyAvailable
(
bool
throwWhenNotReadYet
=
true
)
{
get
{
string
headerValue
=
Headers
.
GetHeaderValueOrNull
(
KnownHeaders
.
TransferEncoding
);
return
headerValue
!=
null
&&
headerValue
.
ContainsIgnoreCase
(
KnownHeaders
.
TransferEncodingChunked
);
}
set
{
if
(
value
)
{
Headers
.
SetOrAddHeaderValue
(
KnownHeaders
.
TransferEncoding
,
KnownHeaders
.
TransferEncodingChunked
);
ContentLength
=
-
1
;
}
else
{
Headers
.
RemoveHeader
(
KnownHeaders
.
TransferEncoding
);
}
}
}
/// <summary>
/// Collection of all response headers
/// </summary>
public
HeaderCollection
Headers
{
get
;
}
=
new
HeaderCollection
();
internal
void
EnsureBodyAvailable
()
{
if
(!
IsBodyRead
)
if
(!
IsBodyRead
&&
throwWhenNotReadYet
)
{
throw
new
Exception
(
"Response body is not read yet. "
+
"Use SessionEventArgs.GetResponseBody() or SessionEventArgs.GetResponseBodyAsString() "
+
...
...
@@ -187,41 +87,6 @@ namespace Titanium.Web.Proxy.Http
}
}
/// <summary>
/// Response body as byte array
/// </summary>
[
Browsable
(
false
)]
public
byte
[]
Body
{
get
{
EnsureBodyAvailable
();
return
body
;
}
internal
set
{
body
=
value
;
bodyString
=
null
;
}
}
/// <summary>
/// Response body as string
/// Use the encoding specified in response to decode the byte[] data to string
/// </summary>
[
Browsable
(
false
)]
public
string
BodyString
=>
bodyString
??
(
bodyString
=
Encoding
.
GetString
(
Body
));
/// <summary>
/// Was response body read by user
/// </summary>
public
bool
IsBodyRead
{
get
;
internal
set
;
}
/// <summary>
/// Is response is no more modifyable by user (user callbacks complete?)
/// </summary>
internal
bool
ResponseLocked
{
get
;
set
;
}
/// <summary>
/// Is response 100-continue
/// </summary>
...
...
@@ -240,7 +105,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// Gets the header text.
/// </summary>
public
string
HeaderText
public
override
string
HeaderText
{
get
{
...
...
@@ -280,27 +145,5 @@ namespace Titanium.Web.Proxy.Http
statusCode
=
int
.
Parse
(
httpResult
[
1
]);
statusDescription
=
httpResult
[
2
];
}
internal
void
UpdateContentLength
()
{
ContentLength
=
IsChunked
?
-
1
:
body
.
Length
;
}
/// <summary>
/// Finish the session
/// </summary>
internal
void
FinishSession
()
{
if
(!
KeepBody
)
{
body
=
null
;
bodyString
=
null
;
}
}
public
override
string
ToString
()
{
return
HeaderText
;
}
}
}
Titanium.Web.Proxy/RequestHandler.cs
View file @
f8d876c6
...
...
@@ -435,7 +435,7 @@ namespace Titanium.Web.Proxy
}
//If user requested call back then do it
if
(!
args
.
WebSession
.
Response
.
Response
Locked
)
if
(!
args
.
WebSession
.
Response
.
Locked
)
{
await
InvokeBeforeResponse
(
args
);
}
...
...
@@ -490,7 +490,7 @@ namespace Titanium.Web.Proxy
try
{
var
request
=
args
.
WebSession
.
Request
;
request
.
Request
Locked
=
true
;
request
.
Locked
=
true
;
//if expect continue is enabled then send the headers first
//and see if server would return 100 conitinue
...
...
Titanium.Web.Proxy/ResponseHandler.cs
View file @
f8d876c6
...
...
@@ -38,7 +38,7 @@ namespace Titanium.Web.Proxy
args
.
ReRequest
=
false
;
//if user requested call back then do it
if
(!
response
.
Response
Locked
)
if
(!
response
.
Locked
)
{
await
InvokeBeforeResponse
(
args
);
}
...
...
@@ -53,7 +53,7 @@ namespace Titanium.Web.Proxy
return
;
}
response
.
Response
Locked
=
true
;
response
.
Locked
=
true
;
var
clientStreamWriter
=
args
.
ProxyClient
.
ClientStreamWriter
;
...
...
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