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
193
Issues
193
List
Board
Labels
Milestones
Merge Requests
9
Merge Requests
9
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
gargantext
haskell-gargantext
Commits
16bece62
Commit
16bece62
authored
Jun 17, 2024
by
Alfredo Di Napoli
1
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 @@
module
Gargantext.MicroServices.ReverseProxy
(
microServicesProxyApp
-- * Internals
,
replaceIt
)
where
import
Prelude
...
...
@@ -41,6 +38,21 @@ import Text.RE.Replace hiding (Capture)
-- 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
{
notesProxy
::
mode
:-
"notes-proxy"
:>
NamedRoutes
NotesProxy
,
notesSocketIo
::
mode
:-
"socket.io"
:>
NamedRoutes
SocketIOProxy
...
...
@@ -48,8 +60,8 @@ data ReverseProxyAPI mode = ReverseProxyAPI
}
deriving
Generic
data
NotesProxy
mode
=
NotesProxy
{
noteProxyEp
::
mode
:-
Capture
"frameId"
T
.
Text
:>
Raw
{
noteProxyEp
::
mode
:-
Capture
"frameId"
T
.
Text
:>
Raw
,
slideEp
::
mode
:-
Capture
"frameId"
T
.
Text
:>
"slide"
:>
Raw
}
deriving
Generic
data
SocketIOProxy
mode
=
SocketIOProxy
...
...
@@ -57,7 +69,7 @@ data SocketIOProxy mode = SocketIOProxy
}
deriving
Generic
--
-- Server
--
The
Server
--
microServicesProxyApp
::
Env
->
Application
...
...
@@ -67,91 +79,108 @@ server :: Env -> ReverseProxyAPI AsServer
server
env
=
ReverseProxyAPI
{
notesProxy
=
notesProxyImplementation
env
,
notesSocketIo
=
socketIOProxyImplementation
env
,
meEndpoint
=
forward
Server
env
,
meEndpoint
=
proxyPass
Server
env
}
notesProxyImplementation
::
Env
->
NotesProxy
AsServer
notesProxyImplementation
env
=
NotesProxy
{
noteProxyEp
=
\
_frameId
->
forwardServer
env
noteProxyEp
=
\
_frameId
->
notesProxyServer
env
,
slideEp
=
\
frameId
->
slideProxyServer
env
frameId
}
socketIOProxyImplementation
::
Env
->
SocketIOProxy
AsServer
socketIOProxyImplementation
env
=
SocketIOProxy
{
socketIoEp
=
\
_noteId
->
forward
Server
env
socketIoEp
=
\
_noteId
->
proxyPass
Server
env
}
forwardServer
::
Env
->
ServerT
Raw
m
forwardServer
env
=
Tagged
$
waiProxyToSettings
forwardRequest
proxySettings
(
env
^.
env_manager
)
notesProxyServer
::
Env
->
ServerT
Raw
m
notesProxyServer
env
=
defaultForwardServer
(
removeProxyPath
"/notes-proxy"
)
env
slideProxyServer
::
Env
->
T
.
Text
->
ServerT
Raw
m
slideProxyServer
env
frameId
=
defaultForwardServer
(
\
rq
->
rq
{
rawPathInfo
=
changePath
(
rawPathInfo
rq
)
})
env
where
changePath
::
ByteString
->
ByteString
changePath
_
=
TE
.
encodeUtf8
$
"/p/"
<>
frameId
<>
"#/"
microSrvSettings
::
MicroServicesSettings
microSrvSettings
=
env
^.
env_settings
.
microservicesSettings
-- Generic server forwarder
proxyPassServer
::
Env
->
ServerT
Raw
m
proxyPassServer
env
=
defaultForwardServer
id
env
pxyPort
::
Int
pxyPort
=
microSrvSettings
^.
msProxyPort
writeFrameURL
::
T
.
Text
writeFrameURL
=
env
^.
hasConfig
.
gc_frame_write_url
mkProxyDestination
::
Env
->
ProxyDestination
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
|
snd
forwardedHost
/=
80
=
TE
.
encodeUtf8
$
writeFrameURL
<>
":"
<>
T
.
pack
(
Prelude
.
show
$
snd
forwardedHost
)
|
otherwise
=
TE
.
encodeUtf8
writeFrameURL
--
-- Combinators over the input Request
--
removeProxyPath
::
ByteString
->
ByteString
removeProxyPath
=
TE
.
encodeUtf8
.
T
.
replace
"/notes-proxy"
""
.
TE
.
decodeUtf8
removeProxyPath
::
T
.
Text
->
Request
->
Request
removeProxyPath
pth
originalRequest
=
originalRequest
{
rawPathInfo
=
removePath
(
rawPathInfo
originalRequest
)
}
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
()
replaceRelativeLinks
=
CC
.
map
(
flushReplace
assetPath
)
where
defaultForwardServer
::
(
Request
->
Request
)
->
Env
->
ServerT
Raw
m
defaultForwardServer
presendModifyRequest
env
=
Tagged
$
waiProxyToSettings
forwardRequest
(
proxySettings
$
mkProxyDestination
env
)
(
env
^.
env_manager
)
where
noCache
::
RequestHeaders
->
RequestHeaders
noCache
hdrs
=
(
hCacheControl
,
fromString
"no-cache"
)
:
filter
((
/=
)
hCacheControl
.
fst
)
hdrs
proxyDestination
::
ProxyDestination
proxyDestination
=
mkProxyDestination
env
newHost
::
RequestHeaders
->
RequestHeaders
newHost
hdrs
=
(
hHost
,
fromString
$
fst
forwardedHost
<>
":"
<>
Prelude
.
show
(
snd
forwardedHost
))
:
filter
((
/=
)
hHost
.
fst
)
hdrs
microSrvSettings
::
MicroServicesSettings
microSrvSettings
=
env
^.
env_settings
.
microservicesSettings
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
hdrs
=
(
hReferer
,
fromString
$
"http://localhost:"
<>
Prelude
.
show
p
xy
Port
)
:
(
hReferer
,
fromString
$
"http://localhost:"
<>
Prelude
.
show
p
roxyListening
Port
)
:
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.
forwardRequest
::
Request
->
IO
WaiProxyResponse
forwardRequest
originalRequest
=
do
let
proxiedReq
=
originalRequest
{
rawPathInfo
=
removeProxyPath
(
rawPathInfo
originalRequest
)
,
requestHeaders
=
(
newReferer
.
newHost
.
noCache
$
(
requestHeaders
originalRequest
))
let
proxiedReq
=
presendModifyRequest
$
originalRequest
{
requestHeaders
=
(
newReferer
.
newHost
proxyDestination
.
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
=
Prelude
.
map
tweakHeader
where
...
...
@@ -161,17 +190,21 @@ tweakResponseHeaders = Prelude.map tweakHeader
|
otherwise
=
(
k
,
v
)
-- | Replaces the relative links in the proxied page content with proper urls.
flushReplace
::
B
.
ByteString
->
B
.
ByteString
->
Flush
Builder
flushReplace
assetPath
=
Chunk
.
byteString
.
replaceIt
assetPath
replaceIt
::
B
.
ByteString
->
B
.
ByteString
->
B
.
ByteString
replaceIt
assetPath
htmlBlob
=
replaceAllCaptures
ALL
makeAbsolute
$
htmlBlob
*=~
[
re
|
src="\/build\/|href="\/build\/|src="\/config|src="\/js\/
|]
-- | Replaces the relative links in any HTML blob returned by the proxy.
replaceRelativeLinks
::
B
.
ByteString
->
ConduitT
B
.
ByteString
(
Flush
Builder
)
IO
()
replaceRelativeLinks
assetPath
=
CC
.
map
flushReplace
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
-- Replaces the relative links in the proxied page content with proper urls.
flushReplace
::
B
.
ByteString
->
Flush
Builder
flushReplace
=
Chunk
.
byteString
.
replaceIt
replaceIt
::
B
.
ByteString
->
B
.
ByteString
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
Przemyslaw Kaminski
@cgenie
mentioned in commit
5660aec0
·
Oct 08, 2024
mentioned in commit
5660aec0
mentioned in commit 5660aec07ec5a0a0a5468f440092c1a8f57a864e
Toggle commit list
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