Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
CAP
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
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
tsai
CAP
Commits
152ee4a6
Commit
152ee4a6
authored
Sep 24, 2017
by
Savorboard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gateway proxy middleware function maturation
parent
ef542010
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
103 additions
and
21 deletions
+103
-21
GatewayProxyMiddleware.cs
...Core.CAP/Dashboard/GatewayProxy/GatewayProxyMiddleware.cs
+102
-20
IRequestMapper.Default.cs
...Core.CAP/Dashboard/GatewayProxy/IRequestMapper.Default.cs
+1
-1
No files found.
src/DotNetCore.CAP/Dashboard/GatewayProxy/GatewayProxyMiddleware.cs
View file @
152ee4a6
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.Linq
;
using
System.Net
;
using
System.Net.Http
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
DotNetCore.CAP.Dashboard.GatewayProxy.Requester
;
using
DotNetCore.CAP.Dashboard.GatewayProxy.Requester
;
using
DotNetCore.CAP.NodeDiscovery
;
using
Microsoft.AspNetCore.Http
;
using
Microsoft.AspNetCore.Http
;
using
Microsoft.Extensions.Logging
;
using
Microsoft.Extensions.Logging
;
using
Microsoft.Extensions.Primitives
;
namespace
DotNetCore.CAP.Dashboard.GatewayProxy
namespace
DotNetCore.CAP.Dashboard.GatewayProxy
{
{
public
class
GatewayProxyMiddleware
:
GatewayProxyMiddlewareBase
public
class
GatewayProxyMiddleware
{
{
private
const
string
NODE_COOKIE_NAME
=
"cap.node"
;
private
readonly
RequestDelegate
_next
;
private
readonly
RequestDelegate
_next
;
private
readonly
ILogger
_logger
;
private
readonly
ILogger
_logger
;
private
readonly
IRequestMapper
_requestMapper
;
private
readonly
IRequestMapper
_requestMapper
;
private
readonly
IHttpRequester
_requester
;
private
readonly
IHttpRequester
_requester
;
private
INodeDiscoveryProvider
_discoveryProvider
;
protected
HttpRequestMessage
DownstreamRequest
{
get
;
set
;
}
public
GatewayProxyMiddleware
(
RequestDelegate
next
,
public
GatewayProxyMiddleware
(
RequestDelegate
next
,
ILoggerFactory
loggerFactory
,
ILoggerFactory
loggerFactory
,
IRequestMapper
requestMapper
,
IRequestMapper
requestMapper
,
...
@@ -24,39 +37,108 @@ namespace DotNetCore.CAP.Dashboard.GatewayProxy
...
@@ -24,39 +37,108 @@ namespace DotNetCore.CAP.Dashboard.GatewayProxy
_requester
=
requester
;
_requester
=
requester
;
}
}
public
async
Task
Invoke
(
HttpContext
context
,
IRequestScopedDataRepository
requestScopedDataRepository
)
public
async
Task
Invoke
(
HttpContext
context
,
DiscoveryOptions
discoveryOptions
,
INodeDiscoveryProvider
discoveryProvider
)
{
{
_
requestScopedDataRepository
=
requestScopedDataRepository
;
_
discoveryProvider
=
discoveryProvider
;
_logger
.
LogDebug
(
"started calling gateway proxy middleware"
);
var
request
=
context
.
Request
;
var
pathMatch
=
discoveryOptions
.
MatchPath
;
var
isCapRequest
=
request
.
Path
.
StartsWithSegments
(
new
PathString
(
pathMatch
),
out
PathString
matchedPath
,
out
PathString
remainingPath
);
var
downstreamRequest
=
await
_requestMapper
.
Map
(
context
.
Request
);
var
isSwitchNode
=
request
.
Cookies
.
TryGetValue
(
NODE_COOKIE_NAME
,
out
string
requestNodeId
);
var
isCurrentNode
=
discoveryOptions
.
NodeId
.
ToString
()
==
requestNodeId
;
_logger
.
LogDebug
(
"setting downstream request"
);
if
(!
isCapRequest
||
!
isSwitchNode
||
isCurrentNode
)
{
await
_next
.
Invoke
(
context
);
}
else
{
_logger
.
LogDebug
(
"started calling gateway proxy middleware"
);
SetDownstreamRequest
(
downstreamRequest
);
if
(
TryGetRemoteNode
(
requestNodeId
,
out
Node
node
))
{
try
{
DownstreamRequest
=
await
_requestMapper
.
Map
(
request
);
_logger
.
LogDebug
(
"setting upstream request"
);
SetDownStreamRequestUri
(
node
,
request
.
Path
.
Value
);
SetUpstreamRequestForThisRequest
(
DownstreamRequest
);
var
response
=
await
_requester
.
GetResponse
(
DownstreamRequest
);
await
SetResponseOnHttpContext
(
context
,
response
);
}
catch
(
Exception
ex
)
{
_logger
.
LogError
(
ex
.
Message
);
}
}
else
{
context
.
Response
.
Cookies
.
Delete
(
NODE_COOKIE_NAME
);
await
_next
.
Invoke
(
context
);
}
}
}
var
uriBuilder
=
new
UriBuilder
(
DownstreamRequest
.
RequestUri
)
private
bool
TryGetRemoteNode
(
string
requestNodeId
,
out
Node
node
)
{
{
//Path = dsPath.Data.Value,
var
nodes
=
_discoveryProvider
.
GetNodes
().
GetAwaiter
().
GetResult
();
//Scheme = DownstreamRoute.ReRoute.DownstreamScheme
node
=
nodes
.
FirstOrDefault
(
x
=>
x
.
Id
==
requestNodeId
);
};
return
node
!=
null
;
}
private
void
SetDownStreamRequestUri
(
Node
node
,
string
requestPath
)
{
var
uriBuilder
=
new
UriBuilder
(
"http://"
,
node
.
Address
,
node
.
Port
,
requestPath
);
DownstreamRequest
.
RequestUri
=
uriBuilder
.
Uri
;
DownstreamRequest
.
RequestUri
=
uriBuilder
.
Uri
;
}
public
async
Task
SetResponseOnHttpContext
(
HttpContext
context
,
HttpResponseMessage
response
)
{
foreach
(
var
httpResponseHeader
in
response
.
Content
.
Headers
)
{
AddHeaderIfDoesntExist
(
context
,
httpResponseHeader
);
}
var
stringContent
=
await
response
.
Content
.
ReadAsStringAsync
();
var
content
=
await
response
.
Content
.
ReadAsByteArrayAsync
();
_logger
.
LogDebug
(
"started calling request"
);
AddHeaderIfDoesntExist
(
context
,
new
KeyValuePair
<
string
,
IEnumerable
<
string
>>(
"Content-Length"
,
new
[]
{
content
.
Length
.
ToString
()
}));
context
.
Response
.
OnStarting
(
state
=>
{
var
httpContext
=
(
HttpContext
)
state
;
var
response
=
await
_requester
.
GetResponse
(
Request
)
;
httpContext
.
Response
.
StatusCode
=
(
int
)
response
.
StatusCode
;
_logger
.
LogDebug
(
"setting http response message"
)
;
return
Task
.
CompletedTask
;
SetHttpResponseMessageThisRequest
(
response
);
},
context
);
_logger
.
LogDebug
(
"returning to calling middleware"
);
using
(
Stream
stream
=
new
MemoryStream
(
content
))
{
if
(
response
.
StatusCode
!=
HttpStatusCode
.
NotModified
)
{
await
stream
.
CopyToAsync
(
context
.
Response
.
Body
);
}
}
}
private
static
void
AddHeaderIfDoesntExist
(
HttpContext
context
,
KeyValuePair
<
string
,
IEnumerable
<
string
>>
httpResponseHeader
)
{
if
(!
context
.
Response
.
Headers
.
ContainsKey
(
httpResponseHeader
.
Key
))
{
context
.
Response
.
Headers
.
Add
(
httpResponseHeader
.
Key
,
new
StringValues
(
httpResponseHeader
.
Value
.
ToArray
()));
}
}
}
}
}
}
}
\ No newline at end of file
src/DotNetCore.CAP/Dashboard/GatewayProxy/IRequestMapper.Default.cs
View file @
152ee4a6
...
@@ -12,7 +12,7 @@ namespace DotNetCore.CAP.Dashboard.GatewayProxy
...
@@ -12,7 +12,7 @@ namespace DotNetCore.CAP.Dashboard.GatewayProxy
{
{
public
class
RequestMapper
:
IRequestMapper
public
class
RequestMapper
:
IRequestMapper
{
{
private
readonly
string
[]
_unsupportedHeaders
=
{
"host"
};
private
readonly
string
[]
_unsupportedHeaders
=
{
"host"
,
"cookie"
};
private
const
string
SchemeDelimiter
=
"://"
;
private
const
string
SchemeDelimiter
=
"://"
;
public
async
Task
<
HttpRequestMessage
>
Map
(
HttpRequest
request
)
public
async
Task
<
HttpRequestMessage
>
Map
(
HttpRequest
request
)
...
...
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