Uses 1658K of libraries. Click here for Pure Java version (43817L/292K).
1 | !7 |
2 | |
3 | do not include class WebRequest. |
4 | |
5 | concept Domain { |
6 | S domain; |
7 | S moduleLibID; |
8 | S proxyDestination; |
9 | S proxyCookieChecker; // a module lib ID |
10 | bool proxyRewritePort; |
11 | bool mustBeEnabled; |
12 | |
13 | toString { ret super.toString() + " " + domain; } |
14 | } |
15 | |
16 | // Eleu is so important, we don't use a shared lib |
17 | module Eleu3 > DynEleu { |
18 | transient CRUD<Domain> domainCRUD; |
19 | switchable bool verbose; |
20 | switchable bool debugNanoHTTPD; |
21 | switchable S sameSite; |
22 | |
23 | {} { enabled = false; } |
24 | |
25 | start { |
26 | NanoHTTPD_debug = debugNanoHTTPD; |
27 | //bootstrapDBFrom(#1029618); |
28 | set flag defaultDefaultClassFinder_debug. |
29 | dbIndexingCI(Domain, 'domain); |
30 | //assertNempty(list(Domain)); |
31 | uniqCI Domain(domain := "<default>"); |
32 | domainCRUD = new CRUD(Domain); |
33 | //dm_registerAs eleuWithCRUD(); |
34 | } |
35 | |
36 | visualize { |
37 | var c = jtabs( |
38 | "Main", super.visualize(), |
39 | "Domains" := domainCRUD.visualize()); |
40 | |
41 | tablePopupMenu(domainCRUD.table(), voidfunc(JPopupMenu menu, int row) { |
42 | Domain d = domainCRUD.selected(), ret if null; |
43 | if (nempty(d.moduleLibID)) |
44 | addMenuItem(menu, "Load module", rThreadEnter { dm_makeOrShow(d.moduleLibID) }); |
45 | }); |
46 | |
47 | ret c; |
48 | } |
49 | |
50 | @Override |
51 | S moduleForDomain(S domain) { |
52 | domain = dropAfterColon(domain); // drop port number |
53 | for (Domain d : domainsInMatchingOrder()) { |
54 | if (matchingDomain(d, domain)) { |
55 | S mod = findMod(d); |
56 | if (verbose) print("Domain matched: " + domain + " / " + d.domain + " => " + mod); |
57 | try answer mod; |
58 | } else |
59 | if (verbose) print("Domain not matched: " + domain + " / " + d.domain); |
60 | } |
61 | ret findMod(defaultDomain()); |
62 | } |
63 | |
64 | Domain defaultDomain() { |
65 | ret conceptWhereCI Domain(domain := "<default>"); |
66 | } |
67 | |
68 | S findMod(Domain d) { |
69 | if (d == null || empty(d.moduleLibID)) null; |
70 | ret d.mustBeEnabled |
71 | ? dm_findModuleWithParams(d.moduleLibID, enabled := true) |
72 | : dm_findModule(d.moduleLibID); |
73 | } |
74 | |
75 | ServeHttp_CookieHandler makeCookieHandler() { |
76 | ServeHttp_CookieHandler cookieHandler = super.makeCookieHandler(); |
77 | cookieHandler.metaParams = appendPrefixIfNempty("SameSite=", sameSite); |
78 | ret cookieHandler; |
79 | } |
80 | |
81 | void onWebServersStarted :: after { |
82 | forEach(webServers(), ws -> { |
83 | print("Augmenting web server: " + ws); |
84 | |
85 | ws.collectHeaderLines = true; |
86 | |
87 | // session is an instance of NanoHTTPD.IHTTPSession |
88 | ws.specialHandling = session -> ctex { |
89 | temp enter(); |
90 | S domain = dropPortFromHost(mapGet(session.getHeaders(), "host")); |
91 | |
92 | Domain d = first(domainsInMatchingOrder(), |
93 | _d -> matchingDomain(_d, domain)); |
94 | |
95 | printVars(+domain, +d); |
96 | if (d == null || empty(d.proxyDestination)) false; |
97 | print("Handling proxy request to " + d.proxyDestination); |
98 | HostAndPort hap = new(d.proxyDestination); |
99 | |
100 | if (nempty(d.proxyCookieChecker)) { |
101 | S cookieChecker = dm_findModule(d.proxyCookieChecker); |
102 | if (empty(cookieChecker)) |
103 | fail(print("Cookie checker " + d.proxyCookieChecker + " not found, aborting request")); |
104 | |
105 | NanoHTTPD.CookieHandler cookies = session.getCookies(); |
106 | |
107 | if (!isTrue(dm_call(cookieChecker, "checkCookie", cookies.read("cookie"), domain))) |
108 | fail(print("Cookie checker disapproves")); |
109 | else |
110 | print("Cookie checker approves. URI: " + session.getUri()); |
111 | } |
112 | |
113 | new HandleProxyRequest hpr; |
114 | hpr.hap = hap; |
115 | hpr.session = session; |
116 | hpr.rewritePort = d.proxyRewritePort; |
117 | |
118 | hpr.customizeRequest = proxyRequest -> { |
119 | proxyRequest.setOut = out -> { |
120 | proxyRequest.setOut_base(out); |
121 | proxyRequest.outProxied = out; // mod here |
122 | }; |
123 | |
124 | proxyRequest.setOutOut = outOut -> { |
125 | proxyRequest.setOutOut_base(outOut); |
126 | proxyRequest.outOutProxied = outOut; // mod here |
127 | }; |
128 | }; |
129 | |
130 | vmBus_send handlingProxyRequest(me(), hpr); |
131 | |
132 | ret true with hpr.run(); |
133 | }; |
134 | }); |
135 | } // onWebServersStarted |
136 | |
137 | bool matchingDomain(Domain d, S domain) { |
138 | ret domainIsUnder_extended(domain, d.domain); |
139 | } |
140 | |
141 | class WebRequest2 extends WebRequest { |
142 | *(NanoHTTPD.IHTTPSession httpSession, S uri, SS params) { |
143 | super(httpSession, uri, params); |
144 | } |
145 | |
146 | // TODO: change uri etc |
147 | /*public NanoHTTPD.Response proxy(S url, bool rewriteHost, bool rewritePort) { |
148 | url = dropPrefix("http://", url); |
149 | if (startsWith(url, "https://")) |
150 | new HandleProxyRequest hpr; |
151 | hpr.hap = hap; |
152 | hpr.session = httpSession; |
153 | hpr.rewriteHost = rewriteHost; |
154 | hpr.rewritePort = rewritePort; |
155 | hpr.run(); |
156 | null; |
157 | }*/ |
158 | } |
159 | |
160 | @Override |
161 | WebRequest createWebRequest(NanoHTTPD.IHTTPSession httpSession, |
162 | S uri, SS params) { |
163 | ret new WebRequest2(httpSession, uri, params); |
164 | } |
165 | |
166 | // API |
167 | |
168 | Cl<Domain> domainsInMatchingOrder() { |
169 | ret sortByCalculatedFieldICDesc( |
170 | filter(list(Domain), d -> !eqic(d.domain, "<default>")), |
171 | d -> reversed(d.domain)); |
172 | } |
173 | |
174 | void addDomain(S domain, S moduleLibID, bool mustBeEnabled) { |
175 | uniq Domain(+domain, +moduleLibID, +mustBeEnabled); |
176 | } |
177 | } |
Began life as a copy of #1029544
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
Snippet ID: | #1029618 |
Snippet name: | Eleu with CRUD by domain - main web server module [LIVE everywhere] |
Eternal ID of this version: | #1029618/49 |
Text MD5: | 1d36a46493a287c7c2c451a97aa12dea |
Transpilation MD5: | d7dd4d5300e01dbc3407d68176365856 |
Author: | stefan |
Category: | javax |
Type: | JavaX source code (Dynamic Module) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-09-07 06:24:16 |
Source code size: | 5459 bytes / 177 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 489 / 318231 |
Version history: | 48 change(s) |
Referenced in: | [show references] |