Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
haskell-gargantext
Project
Project
Details
Activity
Releases
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
Christian Merten
haskell-gargantext
Commits
16bece62
Commit
16bece62
authored
Jun 17, 2024
by
Alfredo Di Napoli
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Slight refactoring of proxy code
parent
4ab1ebbb
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
107 additions
and
74 deletions
+107
-74
ReverseProxy.hs
src/Gargantext/MicroServices/ReverseProxy.hs
+107
-74
No files found.
src/Gargantext/MicroServices/ReverseProxy.hs
View file @
16bece62
...
@@ -4,9 +4,6 @@
...
@@ -4,9 +4,6 @@
module
Gargantext.MicroServices.ReverseProxy
(
module
Gargantext.MicroServices.ReverseProxy
(
microServicesProxyApp
microServicesProxyApp
-- * Internals
,
replaceIt
)
where
)
where
import
Prelude
import
Prelude
...
@@ -41,6 +38,21 @@ import Text.RE.Replace hiding (Capture)
...
@@ -41,6 +38,21 @@ import Text.RE.Replace hiding (Capture)
-- Types
-- Types
--
--
data
ProxyDestination
=
ProxyDestination
{
fwdProto
::
C8
.
ByteString
,
fwdHost
::
C8
.
ByteString
,
fwdPort
::
PortNumber
}
renderProxyDestination
::
ProxyDestination
->
C8
.
ByteString
renderProxyDestination
ProxyDestination
{
..
}
=
fwdProto
<>
"//"
<>
fwdHost
<>
":"
<>
C8
.
pack
(
Prelude
.
show
fwdPort
)
--
-- The API
--
data
ReverseProxyAPI
mode
=
ReverseProxyAPI
data
ReverseProxyAPI
mode
=
ReverseProxyAPI
{
notesProxy
::
mode
:-
"notes-proxy"
:>
NamedRoutes
NotesProxy
{
notesProxy
::
mode
:-
"notes-proxy"
:>
NamedRoutes
NotesProxy
,
notesSocketIo
::
mode
:-
"socket.io"
:>
NamedRoutes
SocketIOProxy
,
notesSocketIo
::
mode
:-
"socket.io"
:>
NamedRoutes
SocketIOProxy
...
@@ -48,8 +60,8 @@ data ReverseProxyAPI mode = ReverseProxyAPI
...
@@ -48,8 +60,8 @@ data ReverseProxyAPI mode = ReverseProxyAPI
}
deriving
Generic
}
deriving
Generic
data
NotesProxy
mode
=
NotesProxy
data
NotesProxy
mode
=
NotesProxy
{
noteProxyEp
::
mode
:-
Capture
"frameId"
T
.
Text
{
noteProxyEp
::
mode
:-
Capture
"frameId"
T
.
Text
:>
Raw
:>
Raw
,
slideEp
::
mode
:-
Capture
"frameId"
T
.
Text
:>
"slide"
:>
Raw
}
deriving
Generic
}
deriving
Generic
data
SocketIOProxy
mode
=
SocketIOProxy
data
SocketIOProxy
mode
=
SocketIOProxy
...
@@ -57,7 +69,7 @@ data SocketIOProxy mode = SocketIOProxy
...
@@ -57,7 +69,7 @@ data SocketIOProxy mode = SocketIOProxy
}
deriving
Generic
}
deriving
Generic
--
--
-- Server
--
The
Server
--
--
microServicesProxyApp
::
Env
->
Application
microServicesProxyApp
::
Env
->
Application
...
@@ -67,91 +79,108 @@ server :: Env -> ReverseProxyAPI AsServer
...
@@ -67,91 +79,108 @@ server :: Env -> ReverseProxyAPI AsServer
server
env
=
ReverseProxyAPI
{
server
env
=
ReverseProxyAPI
{
notesProxy
=
notesProxyImplementation
env
notesProxy
=
notesProxyImplementation
env
,
notesSocketIo
=
socketIOProxyImplementation
env
,
notesSocketIo
=
socketIOProxyImplementation
env
,
meEndpoint
=
forward
Server
env
,
meEndpoint
=
proxyPass
Server
env
}
}
notesProxyImplementation
::
Env
->
NotesProxy
AsServer
notesProxyImplementation
::
Env
->
NotesProxy
AsServer
notesProxyImplementation
env
=
NotesProxy
{
notesProxyImplementation
env
=
NotesProxy
{
noteProxyEp
=
\
_frameId
->
forwardServer
env
noteProxyEp
=
\
_frameId
->
notesProxyServer
env
,
slideEp
=
\
frameId
->
slideProxyServer
env
frameId
}
}
socketIOProxyImplementation
::
Env
->
SocketIOProxy
AsServer
socketIOProxyImplementation
::
Env
->
SocketIOProxy
AsServer
socketIOProxyImplementation
env
=
SocketIOProxy
{
socketIOProxyImplementation
env
=
SocketIOProxy
{
socketIoEp
=
\
_noteId
->
forward
Server
env
socketIoEp
=
\
_noteId
->
proxyPass
Server
env
}
}
forwardServer
::
Env
->
ServerT
Raw
m
notesProxyServer
::
Env
->
ServerT
Raw
m
forwardServer
env
=
notesProxyServer
env
=
defaultForwardServer
(
removeProxyPath
"/notes-proxy"
)
env
Tagged
$
waiProxyToSettings
forwardRequest
proxySettings
(
env
^.
env_manager
)
slideProxyServer
::
Env
->
T
.
Text
->
ServerT
Raw
m
slideProxyServer
env
frameId
=
defaultForwardServer
(
\
rq
->
rq
{
rawPathInfo
=
changePath
(
rawPathInfo
rq
)
})
env
where
where
changePath
::
ByteString
->
ByteString
changePath
_
=
TE
.
encodeUtf8
$
"/p/"
<>
frameId
<>
"#/"
microSrvSettings
::
MicroServicesSettings
-- Generic server forwarder
microSrvSettings
=
env
^.
env_settings
.
microservicesSettings
proxyPassServer
::
Env
->
ServerT
Raw
m
proxyPassServer
env
=
defaultForwardServer
id
env
pxyPort
::
Int
pxyPort
=
microSrvSettings
^.
msProxyPort
writeFrameURL
::
T
.
Text
mkProxyDestination
::
Env
->
ProxyDestination
writeFrameURL
=
env
^.
hasConfig
.
gc_frame_write_url
mkProxyDestination
env
=
fromMaybe
(
panicTrace
"Invalid URI found in the proxied Request."
)
$
do
URI
{
..
}
<-
URI
.
parseURI
(
T
.
unpack
$
env
^.
hasConfig
.
gc_frame_write_url
)
uriAut
<-
uriAuthority
port
<-
case
uriPort
uriAut
of
""
->
pure
80
xs
->
readMaybe
(
dropWhile
(
==
':'
)
xs
)
pure
$
ProxyDestination
(
C8
.
pack
uriScheme
)
(
C8
.
pack
$
uriRegName
uriAut
)
port
assetPath
::
B
.
ByteString
--
assetPath
-- Combinators over the input Request
|
snd
forwardedHost
/=
80
--
=
TE
.
encodeUtf8
$
writeFrameURL
<>
":"
<>
T
.
pack
(
Prelude
.
show
$
snd
forwardedHost
)
|
otherwise
=
TE
.
encodeUtf8
writeFrameURL
removeProxyPath
::
ByteString
->
ByteString
removeProxyPath
::
T
.
Text
->
Request
->
Request
removeProxyPath
=
TE
.
encodeUtf8
removeProxyPath
pth
originalRequest
=
.
T
.
replace
"/notes-proxy"
""
originalRequest
{
rawPathInfo
=
removePath
(
rawPathInfo
originalRequest
)
}
.
TE
.
decodeUtf8
where
removePath
::
ByteString
->
ByteString
removePath
=
TE
.
encodeUtf8
.
T
.
replace
pth
""
.
TE
.
decodeUtf8
proxySettings
::
WaiProxySettings
proxySettings
=
defaultWaiProxySettings
{
wpsProcessBody
=
\
_req
_res
->
Just
replaceRelativeLinks
,
wpsModifyResponseHeaders
=
\
_req
_res
->
tweakResponseHeaders
}
replaceRelativeLinks
::
ConduitT
B
.
ByteString
(
Flush
Builder
)
IO
()
defaultForwardServer
::
(
Request
->
Request
)
->
Env
->
ServerT
Raw
m
replaceRelativeLinks
=
CC
.
map
(
flushReplace
assetPath
)
defaultForwardServer
presendModifyRequest
env
=
where
Tagged
$
waiProxyToSettings
forwardRequest
(
proxySettings
$
mkProxyDestination
env
)
(
env
^.
env_manager
)
where
noCache
::
RequestHeaders
->
RequestHeaders
proxyDestination
::
ProxyDestination
noCache
hdrs
=
(
hCacheControl
,
fromString
"no-cache"
)
:
proxyDestination
=
mkProxyDestination
env
filter
((
/=
)
hCacheControl
.
fst
)
hdrs
newHost
::
RequestHeaders
->
RequestHeaders
microSrvSettings
::
MicroServicesSettings
newHost
hdrs
=
microSrvSettings
=
env
^.
env_settings
.
microservicesSettings
(
hHost
,
fromString
$
fst
forwardedHost
<>
":"
<>
Prelude
.
show
(
snd
forwardedHost
))
:
filter
((
/=
)
hHost
.
fst
)
hdrs
proxyListeningPort
::
Int
proxyListeningPort
=
microSrvSettings
^.
msProxyPort
proxySettings
::
ProxyDestination
->
WaiProxySettings
proxySettings
h
@
ProxyDestination
{
..
}
=
defaultWaiProxySettings
{
wpsProcessBody
=
\
_req
_res
->
Just
$
replaceRelativeLinks
assetPath
,
wpsModifyResponseHeaders
=
\
_req
_res
->
tweakResponseHeaders
}
where
assetPath
::
B
.
ByteString
assetPath
|
fwdPort
/=
80
=
renderProxyDestination
h
|
otherwise
=
fwdProto
<>
"//"
<>
fwdHost
newHost
::
ProxyDestination
->
RequestHeaders
->
RequestHeaders
newHost
hst
hdrs
=
(
hHost
,
renderProxyDestination
hst
)
:
filter
((
/=
)
hHost
.
fst
)
hdrs
newReferer
::
RequestHeaders
->
RequestHeaders
newReferer
::
RequestHeaders
->
RequestHeaders
newReferer
hdrs
=
newReferer
hdrs
=
(
hReferer
,
fromString
$
"http://localhost:"
<>
Prelude
.
show
p
xy
Port
)
:
(
hReferer
,
fromString
$
"http://localhost:"
<>
Prelude
.
show
p
roxyListening
Port
)
:
filter
((
/=
)
hHost
.
fst
)
hdrs
filter
((
/=
)
hHost
.
fst
)
hdrs
forwardedHost
::
(
String
,
Int
)
forwardedHost
=
fromMaybe
(
panicTrace
"Invalid URI found in the proxied Request."
)
$
do
URI
{
..
}
<-
URI
.
parseURI
(
T
.
unpack
writeFrameURL
)
uriAut
<-
uriAuthority
port
<-
case
uriPort
uriAut
of
""
->
pure
80
xs
->
readMaybe
(
dropWhile
(
==
':'
)
xs
)
pure
$
(
uriRegName
uriAut
,
port
)
mkProxyDest
::
ProxyDest
mkProxyDest
=
let
(
hst
,
prt
)
=
forwardedHost
in
ProxyDest
(
C8
.
pack
hst
)
prt
-- | Forwards the request by substituting back the proxied address into the actual one.
-- | Forwards the request by substituting back the proxied address into the actual one.
forwardRequest
::
Request
->
IO
WaiProxyResponse
forwardRequest
::
Request
->
IO
WaiProxyResponse
forwardRequest
originalRequest
=
do
forwardRequest
originalRequest
=
do
let
proxiedReq
=
originalRequest
{
let
proxiedReq
=
presendModifyRequest
$
originalRequest
{
rawPathInfo
=
removeProxyPath
(
rawPathInfo
originalRequest
)
requestHeaders
=
(
newReferer
.
newHost
proxyDestination
.
noCache
$
(
requestHeaders
originalRequest
))
,
requestHeaders
=
(
newReferer
.
newHost
.
noCache
$
(
requestHeaders
originalRequest
))
}
}
pure
$
WPRModifiedRequest
proxiedReq
mkProxyDest
pure
$
WPRModifiedRequest
proxiedReq
ProxyDest
(
fwdHost
proxyDestination
)
(
fwdPort
proxyDestination
))
--
-- Utility functions
--
noCache
::
RequestHeaders
->
RequestHeaders
noCache
hdrs
=
(
hCacheControl
,
fromString
"no-cache"
)
:
filter
((
/=
)
hCacheControl
.
fst
)
hdrs
-- | Tweak the response headers so that they will have a bit more permissive
-- 'Content-Security-Policy'.
tweakResponseHeaders
::
ResponseHeaders
->
ResponseHeaders
tweakResponseHeaders
::
ResponseHeaders
->
ResponseHeaders
tweakResponseHeaders
=
Prelude
.
map
tweakHeader
tweakResponseHeaders
=
Prelude
.
map
tweakHeader
where
where
...
@@ -161,17 +190,21 @@ tweakResponseHeaders = Prelude.map tweakHeader
...
@@ -161,17 +190,21 @@ tweakResponseHeaders = Prelude.map tweakHeader
|
otherwise
|
otherwise
=
(
k
,
v
)
=
(
k
,
v
)
-- | Replaces the relative links in the proxied page content with proper urls.
-- | Replaces the relative links in any HTML blob returned by the proxy.
flushReplace
::
B
.
ByteString
->
B
.
ByteString
->
Flush
Builder
replaceRelativeLinks
::
B
.
ByteString
->
ConduitT
B
.
ByteString
(
Flush
Builder
)
IO
()
flushReplace
assetPath
=
Chunk
.
byteString
.
replaceIt
assetPath
replaceRelativeLinks
assetPath
=
CC
.
map
flushReplace
replaceIt
::
B
.
ByteString
->
B
.
ByteString
->
B
.
ByteString
replaceIt
assetPath
htmlBlob
=
replaceAllCaptures
ALL
makeAbsolute
$
htmlBlob
*=~
[
re
|
src="\/build\/|href="\/build\/|src="\/config|src="\/js\/
|]
where
where
makeAbsolute
_
_loc
cap
=
case
capturedText
cap
of
-- Replaces the relative links in the proxied page content with proper urls.
"src=
\"
/build/"
->
Just
$
"src=
\"
"
<>
assetPath
<>
"/build/"
flushReplace
::
B
.
ByteString
->
Flush
Builder
"href=
\"
/build/"
->
Just
$
"href=
\"
"
<>
assetPath
<>
"/build/"
flushReplace
=
Chunk
.
byteString
.
replaceIt
"src=
\"
/config"
->
Just
$
"src=
\"
"
<>
assetPath
<>
"/config"
"src=
\"
/js/"
->
Just
$
"src=
\"
"
<>
assetPath
<>
"/js/"
replaceIt
::
B
.
ByteString
->
B
.
ByteString
_
->
Just
$
assetPath
<>
capturedText
cap
replaceIt
htmlBlob
=
replaceAllCaptures
ALL
makeAbsolute
$
htmlBlob
*=~
[
re
|
src="\/build\/|href="\/build\/|src="\/config|src="\/js\/
|]
where
makeAbsolute
_
_loc
cap
=
case
capturedText
cap
of
"src=
\"
/build/"
->
Just
$
"src=
\"
"
<>
assetPath
<>
"/build/"
"href=
\"
/build/"
->
Just
$
"href=
\"
"
<>
assetPath
<>
"/build/"
"src=
\"
/config"
->
Just
$
"src=
\"
"
<>
assetPath
<>
"/config"
"src=
\"
/js/"
->
Just
$
"src=
\"
"
<>
assetPath
<>
"/js/"
_
->
Just
$
assetPath
<>
capturedText
cap
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