Skip to content

Commit abed9f6

Browse files
Align server filter pipeline with main FilterChainImpl and HttpResponseBuilder
1 parent 032d91d commit abed9f6

4 files changed

Lines changed: 130 additions & 159 deletions

File tree

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
package org.example.filter;
22

3-
import org.example.http.HttpResponseBuilder;
43
import org.example.httpparser.HttpRequest;
5-
4+
import org.example.http.HttpResponseBuilder;
65

76
import java.util.List;
8-
9-
/*
10-
* The default class of FilterChain,
11-
* Contains a list of filters. For each of the filter, will execute the doFilter method.
12-
*
13-
*/
7+
import java.util.function.BiConsumer;
148

159
public class FilterChainImpl implements FilterChain {
1610

1711
private final List<Filter> filters;
12+
private final BiConsumer<HttpRequest, HttpResponseBuilder> terminalHandler;
1813
private int index = 0;
1914

2015
public FilterChainImpl(List<Filter> filters) {
16+
this(filters, (req, resp) -> {
17+
// default no-op (preserves previous behavior)
18+
});
19+
}
20+
21+
public FilterChainImpl(List<Filter> filters,
22+
BiConsumer<HttpRequest, HttpResponseBuilder> terminalHandler) {
2123
this.filters = filters;
24+
this.terminalHandler = terminalHandler;
2225
}
2326

2427
@Override
@@ -27,7 +30,7 @@ public void doFilter(HttpRequest request, HttpResponseBuilder response) {
2730
Filter next = filters.get(index++);
2831
next.doFilter(request, response, this);
2932
} else {
30-
// TODO: when no more filters, should execute the request
33+
terminalHandler.accept(request, response);
3134
}
3235
}
3336
}
Lines changed: 14 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package org.example.server;
22

3+
import org.example.filter.Filter;
4+
import org.example.filter.FilterChainImpl;
5+
import org.example.httpparser.HttpRequest;
6+
import org.example.http.HttpResponseBuilder;
7+
38
import java.util.ArrayList;
49
import java.util.Comparator;
510
import java.util.List;
11+
import java.util.function.BiConsumer;
612

713
public class ConfigurableFilterPipeline {
814

@@ -12,7 +18,8 @@ public ConfigurableFilterPipeline(List<FilterRegistration> registrations) {
1218
this.registrations = registrations;
1319
}
1420

15-
public HttpResponse execute(HttpRequest request, TerminalHandler handler) {
21+
public HttpResponseBuilder execute(HttpRequest request,
22+
BiConsumer<HttpRequest, HttpResponseBuilder> terminalHandler) {
1623

1724
List<FilterRegistration> globalRegs = new ArrayList<>();
1825
List<FilterRegistration> routeRegs = new ArrayList<>();
@@ -21,7 +28,7 @@ public HttpResponse execute(HttpRequest request, TerminalHandler handler) {
2128
if (reg.isGlobal()) {
2229
globalRegs.add(reg);
2330
} else {
24-
if (matchesAny(reg.routePatterns(), request.path())) {
31+
if (matchesAny(reg.routePatterns(), request.getPath())) {
2532
routeRegs.add(reg);
2633
}
2734
}
@@ -33,19 +40,21 @@ public HttpResponse execute(HttpRequest request, TerminalHandler handler) {
3340
globalRegs.sort(byOrder);
3441
routeRegs.sort(byOrder);
3542

36-
List<HttpFilter> allFilters = new ArrayList<>(globalRegs.size() + routeRegs.size());
43+
List<Filter> allFilters = new ArrayList<>(globalRegs.size() + routeRegs.size());
3744
for (FilterRegistration reg : globalRegs) {
3845
allFilters.add(reg.filter());
3946
}
4047
for (FilterRegistration reg : routeRegs) {
4148
allFilters.add(reg.filter());
4249
}
4350

44-
return buildChain(allFilters, handler).next(request);
51+
HttpResponseBuilder response = new HttpResponseBuilder();
52+
new FilterChainImpl(allFilters, terminalHandler).doFilter(request, response);
53+
return response;
4554
}
4655

4756
private boolean matchesAny(List<String> patterns, String path) {
48-
if (patterns == null) return false;
57+
if (patterns == null || path == null) return false;
4958

5059
for (String pattern : patterns) {
5160
if (RoutePattern.matches(pattern, path)) {
@@ -55,77 +64,4 @@ private boolean matchesAny(List<String> patterns, String path) {
5564

5665
return false;
5766
}
58-
59-
private FilterChain buildChain(List<HttpFilter> filters, TerminalHandler handler) {
60-
61-
FilterChain chain = new FilterChain() {
62-
@Override
63-
public HttpResponse next(HttpRequest request) {
64-
return handler.handle(request);
65-
}
66-
};
67-
68-
for (int i = filters.size() - 1; i >= 0; i--) {
69-
70-
HttpFilter currentFilter = filters.get(i);
71-
FilterChain nextChain = chain;
72-
73-
chain = new FilterChain() {
74-
@Override
75-
public HttpResponse next(HttpRequest request) {
76-
return currentFilter.handle(request, nextChain);
77-
}
78-
};
79-
}
80-
81-
return chain;
82-
}
83-
}
84-
85-
class HttpRequest {
86-
private final String method;
87-
private final String path;
88-
89-
public HttpRequest(String method, String path) {
90-
this.method = method;
91-
this.path = path;
92-
}
93-
94-
public String path() {
95-
return path;
96-
}
97-
98-
public String getMethod() {
99-
return method;
100-
}
101-
}
102-
103-
class HttpResponse {
104-
private final int statusCode;
105-
private final String body;
106-
107-
public HttpResponse(int statusCode, String body) {
108-
this.statusCode = statusCode;
109-
this.body = body;
110-
}
111-
112-
public int getStatusCode() {
113-
return statusCode;
114-
}
115-
116-
public String getBody() {
117-
return body;
118-
}
119-
}
120-
121-
interface HttpFilter {
122-
HttpResponse handle(HttpRequest request, FilterChain chain);
123-
}
124-
125-
interface FilterChain {
126-
HttpResponse next(HttpRequest request);
127-
}
128-
129-
interface TerminalHandler {
130-
HttpResponse handle(HttpRequest request);
13167
}

src/main/java/org/example/server/FilterRegistration.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package org.example.server;
22

3+
import org.example.filter.Filter;
4+
35
import java.util.List;
46

57
public record FilterRegistration(
6-
HttpFilter filter,
8+
Filter filter,
79
int order,
810
List<String> routePatterns
911
) {

0 commit comments

Comments
 (0)