Skip to content

Commit eeb7af1

Browse files
发布v2.3.28
1.dubbo代理支持前后端心跳包 2.servlet-urlpattern优化匹配策略 3.servlet优化qps 4.servlet支持mapperContextRootRedirectEnabled
1 parent 94b8cd9 commit eeb7af1

15 files changed

+366
-186
lines changed

src/main/java/com/github/netty/core/util/ReadOnlyPooledHeapByteBuf.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ class ReadOnlyPooledHeapByteBuf extends AbstractReferenceCountedByteBuf {
2929
private ByteBuffer tmpNioBuf;
3030
private int offset;
3131
private int capacity;
32-
private ByteBuf parent;
3332

3433
private ReadOnlyPooledHeapByteBuf() {
3534
super(0);
@@ -103,7 +102,6 @@ public ByteBuf slice(int index, int length) {
103102
slice.maxCapacity(length);
104103
slice.capacity = length;
105104
slice.setIndex(0, length);
106-
slice.parent = this;
107105
slice.offset = offset + index;
108106
return slice;
109107
}
@@ -435,7 +433,6 @@ public ByteBuf copy() {
435433
copy.maxCapacity(maxCapacity());
436434
copy.capacity = capacity;
437435
copy.setIndex(readerIndex(), writerIndex());
438-
copy.parent = this;
439436
copy.offset = offset;
440437
return copy;
441438
}
@@ -497,7 +494,6 @@ protected final ByteBuffer internalNioBuffer() {
497494
protected void deallocate() {
498495
freeArray(array);
499496
array = EMPTY_BYTES;
500-
parent = null;
501497
offset = 0;
502498
RECYCLER.recycleInstance(this);
503499
}

src/main/java/com/github/netty/protocol/servlet/NettyHttpResponse.java

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.concurrent.atomic.AtomicBoolean;
1616

1717
import static com.github.netty.protocol.servlet.util.HttpHeaderConstants.CLOSE;
18+
import static com.github.netty.protocol.servlet.util.HttpHeaderConstants.cacheAsciiString;
1819

1920
/**
2021
* NettyHttpResponse
@@ -238,7 +239,7 @@ private void settingResponseHeader(boolean isKeepAlive, Protocol protocol, boole
238239
ServletSessionCookieConfig sessionCookieConfig) {
239240
HttpHeaderUtil.setKeepAlive(this, isKeepAlive);
240241
HttpHeaders headers = headers();
241-
242+
StringBuilder[] buf = new StringBuilder[1];
242243
if (protocol.isHttp2()) {
243244
// h2 adapter
244245
String streamId = servletRequest.getNettyHeaders().get(HttpConstants.H2_EXT_STREAM_ID);
@@ -273,25 +274,36 @@ private void settingResponseHeader(boolean isKeepAlive, Protocol protocol, boole
273274

274275
//Content Type The content of the response header
275276
if (null != contentType) {
276-
String value = (null == characterEncoding) ? contentType :
277-
RecyclableUtil.newStringBuilder()
278-
.append(contentType)
279-
.append(APPEND_CONTENT_TYPE)
280-
.append(characterEncoding).toString();
277+
CharSequence value;
278+
if (null == characterEncoding) {
279+
value = HttpHeaderConstants.cacheAsciiString(contentType);
280+
} else {
281+
value = HttpHeaderConstants.cacheAsciiString(contentType, characterEncoding,
282+
() -> {
283+
if (buf[0] == null) {
284+
buf[0] = RecyclableUtil.newStringBuilder();
285+
} else {
286+
buf[0].setLength(0);
287+
}
288+
return cacheAsciiString(buf[0].append(contentType)
289+
.append(APPEND_CONTENT_TYPE)
290+
.append(characterEncoding)
291+
.toString());
292+
});
293+
}
281294
headers.set(HttpHeaderConstants.CONTENT_TYPE, value);
282295
}
283296

284297
//Server information response header
285-
String serverHeader = servletRequest.getServletContext().getServerHeader();
286-
if (serverHeader != null && serverHeader.length() > 0) {
298+
CharSequence serverHeader = servletRequest.getServletContext().getServerHeaderAscii();
299+
if (serverHeader != null && serverHeader.length() != 0) {
287300
headers.set(HttpHeaderConstants.SERVER, serverHeader);
288301
}
289302

290303
//language
291304
if (locale != null && !headers.contains(HttpHeaderConstants.CONTENT_LANGUAGE)) {
292-
headers.set(HttpHeaderConstants.CONTENT_LANGUAGE, locale.toLanguageTag());
305+
headers.set(HttpHeaderConstants.CONTENT_LANGUAGE, HttpHeaderConstants.cacheAsciiString(locale.toLanguageTag()));
293306
}
294-
295307
// Cookies processing
296308
//Session is handled first. If it is a new Session and the Session id is not the same as the Session id passed by the request, it needs to be written through the Cookie
297309
ServletHttpSession httpSession = servletRequest.getSession(false);
@@ -300,11 +312,16 @@ private void settingResponseHeader(boolean isKeepAlive, Protocol protocol, boole
300312
if (sessionCookieName == null || sessionCookieName.isEmpty()) {
301313
sessionCookieName = HttpConstants.JSESSION_ID_COOKIE;
302314
}
303-
String sessionCookiePath = sessionCookieConfig.getPath();
304-
if (sessionCookiePath == null || sessionCookiePath.isEmpty()) {
315+
CharSequence sessionCookiePath = sessionCookieConfig.getPath();
316+
if (sessionCookiePath == null || sessionCookiePath.length() == 0) {
305317
sessionCookiePath = HttpConstants.DEFAULT_SESSION_COOKIE_PATH;
306318
}
307-
String sessionCookieText = ServletUtil.encodeCookie(sessionCookieName, httpSession.getId(), sessionCookieConfig.getMaxAge(),
319+
if (buf[0] == null) {
320+
buf[0] = RecyclableUtil.newStringBuilder();
321+
} else {
322+
buf[0].setLength(0);
323+
}
324+
CharSequence sessionCookieText = ServletUtil.encodeCookie(buf[0], sessionCookieName, httpSession.getId(), sessionCookieConfig.getMaxAge(),
308325
sessionCookiePath, sessionCookieConfig.getDomain(), sessionCookieConfig.isSecure(), sessionCookieConfig.isHttpOnly());
309326
headers.add(HttpHeaderConstants.SET_COOKIE, sessionCookieText);
310327
}
@@ -314,7 +331,12 @@ private void settingResponseHeader(boolean isKeepAlive, Protocol protocol, boole
314331
if (cookieSize > 0) {
315332
for (int i = 0; i < cookieSize; i++) {
316333
Cookie cookie = cookies.get(i);
317-
String cookieText = ServletUtil.encodeCookie(cookie.getName(), cookie.getValue(), cookie.getMaxAge(), cookie.getPath(), cookie.getDomain(), cookie.getSecure(), cookie.isHttpOnly());
334+
if (buf[0] == null) {
335+
buf[0] = RecyclableUtil.newStringBuilder();
336+
} else {
337+
buf[0].setLength(0);
338+
}
339+
CharSequence cookieText = ServletUtil.encodeCookie(buf[0], cookie.getName(), cookie.getValue(), cookie.getMaxAge(), cookie.getPath(), cookie.getDomain(), cookie.getSecure(), cookie.isHttpOnly());
318340
headers.add(HttpHeaderConstants.SET_COOKIE, cookieText);
319341
}
320342
}

src/main/java/com/github/netty/protocol/servlet/NettyMessageToServletRunnable.java

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ public void setExchange(ServletHttpExchange exchange) {
235235
public void run() {
236236
ServletHttpServletRequest request = exchange.getRequest();
237237
ServletHttpServletResponse response = exchange.getResponse();
238-
ServletErrorPageManager errorPageManager = exchange.getServletContext().getErrorPageManager();
238+
ServletContext servletContext = exchange.getServletContext();
239+
ServletErrorPageManager errorPageManager = servletContext.getErrorPageManager();
239240
Throwable realThrowable = null;
240241

241242
// upload cannot block event loop
@@ -249,26 +250,33 @@ public void run() {
249250
ASYNC_CONTEXT_DISPATCH_THREAD_LOCAL.set(asyncContextDispatchOperList);
250251
ServletRequestDispatcher dispatcher = null;
251252
try {
252-
dispatcher = request.getRequestDispatcher(request.getRequestURI());
253-
if (dispatcher == null) {
254-
Servlet defaultServlet = exchange.getServletContext().getDefaultServlet();
255-
if (defaultServlet != null) {
256-
defaultServlet.service(request, response);
253+
String requestURI = request.getRequestURI();
254+
if (servletContext.isMapperContextRootRedirectEnabled() && requestURI.equals(servletContext.getContextPath())) {
255+
response.sendRedirect(requestURI.concat("/"));
256+
} else {
257+
dispatcher = request.getRequestDispatcher(requestURI);
258+
if (dispatcher == null) {
259+
Servlet defaultServlet = exchange.getServletContext().getDefaultServlet();
260+
if (defaultServlet != null) {
261+
defaultServlet.service(request, response);
262+
} else {
263+
response.sendError(HttpServletResponse.SC_NOT_FOUND);
264+
}
257265
} else {
258-
response.sendError(HttpServletResponse.SC_NOT_FOUND);
266+
request.setAsyncSupportedFlag(dispatcher.getFilterChain().getServletRegistration().isAsyncSupported());
267+
request.setDispatcher(dispatcher);
268+
dispatcher.dispatch(request, response);
259269
}
260-
} else {
261-
request.setAsyncSupportedFlag(dispatcher.getFilterChain().getServletRegistration().isAsyncSupported());
262-
request.setDispatcher(dispatcher);
263-
dispatcher.dispatch(request, response);
264270
}
265271
} catch (ServletException se) {
266272
realThrowable = se.getRootCause();
267273
} catch (Throwable throwable) {
268274
realThrowable = throwable;
269275
} finally {
270276
try {
271-
handleErrorPage(errorPageManager, realThrowable, dispatcher, request, response);
277+
if (dispatcher != null) {
278+
handleErrorPage(errorPageManager, realThrowable, dispatcher, request, response);
279+
}
272280
} catch (Throwable e) {
273281
logger.warn("handleErrorPage error = {}", e.toString(), e);
274282
} finally {

src/main/java/com/github/netty/protocol/servlet/ServletContext.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package com.github.netty.protocol.servlet;
22

33
import com.github.netty.Version;
4-
import com.github.netty.core.util.*;
4+
import com.github.netty.core.util.LoggerFactoryX;
5+
import com.github.netty.core.util.LoggerX;
6+
import com.github.netty.core.util.ResourceManager;
7+
import com.github.netty.core.util.SystemPropertyUtil;
58
import com.github.netty.protocol.servlet.util.FilterMapper;
69
import com.github.netty.protocol.servlet.util.HttpConstants;
710
import com.github.netty.protocol.servlet.util.MimeMappingsX;
@@ -11,6 +14,7 @@
1114
import io.netty.handler.codec.http.multipart.DiskAttribute;
1215
import io.netty.handler.codec.http.multipart.DiskFileUpload;
1316
import io.netty.handler.codec.http.multipart.HttpDataFactory;
17+
import io.netty.util.AsciiString;
1418
import io.netty.util.concurrent.FastThreadLocal;
1519

1620
import javax.servlet.*;
@@ -82,8 +86,10 @@ protected Map<Charset, DefaultHttpDataFactory> initialValue() throws Exception {
8286
private Set<SessionTrackingMode> sessionTrackingModeSet;
8387
private Servlet defaultServlet = new DefaultServlet();
8488
private boolean enableLookupFlag = false;
89+
private boolean mapperContextRootRedirectEnabled = true;
8590
private boolean autoFlush;
8691
private String serverHeader;
92+
private CharSequence serverHeaderAscii;
8793
private String contextPath = "";
8894
private String requestCharacterEncoding;
8995
private String responseCharacterEncoding;
@@ -191,6 +197,14 @@ public void setUploadFileTimeoutMs(long uploadFileTimeoutMs) {
191197
this.uploadFileTimeoutMs = uploadFileTimeoutMs;
192198
}
193199

200+
public boolean isMapperContextRootRedirectEnabled() {
201+
return mapperContextRootRedirectEnabled;
202+
}
203+
204+
public void setMapperContextRootRedirectEnabled(boolean mapperContextRootRedirectEnabled) {
205+
this.mapperContextRootRedirectEnabled = mapperContextRootRedirectEnabled;
206+
}
207+
194208
public boolean isEnableLookupFlag() {
195209
return enableLookupFlag;
196210
}
@@ -288,8 +302,15 @@ public String getServerHeader() {
288302
return serverHeader;
289303
}
290304

305+
public CharSequence getServerHeaderAscii() {
306+
return serverHeaderAscii;
307+
}
308+
291309
public void setServerHeader(String serverHeader) {
292310
this.serverHeader = serverHeader;
311+
if (serverHeader != null) {
312+
this.serverHeaderAscii = AsciiString.cached(serverHeader);
313+
}
293314
}
294315

295316
public ServletEventListenerManager getServletEventListenerManager() {

src/main/java/com/github/netty/protocol/servlet/ServletHttpAsyncRequest.java

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ public class ServletHttpAsyncRequest extends HttpServletRequestWrapper {
4444
private Map<String, String[]> parameterMap = null;
4545
private boolean decodePathsFlag = false;
4646
private boolean decodeParameterFlag = false;
47+
private boolean getQueryStringFlag = false;
48+
private boolean getRequestURIFlag = false;
49+
private int decodePathsQueryIndex;
4750
private String dispatchPath;
4851
private final ServletAsyncContext servletAsyncContext;
4952

@@ -117,18 +120,36 @@ public String getPathInfo() {
117120

118121
@Override
119122
public String getQueryString() {
120-
if (!decodePathsFlag) {
121-
decodePaths();
123+
int decodePathsQueryIndex;
124+
if (decodePathsFlag) {
125+
decodePathsQueryIndex = this.decodePathsQueryIndex;
126+
} else {
127+
decodePathsQueryIndex = decodePaths();
128+
}
129+
if (!getQueryStringFlag) {
130+
if (decodePathsQueryIndex != -1) {
131+
this.queryString = requestURI.substring(decodePathsQueryIndex + 1);
132+
}
122133
}
123-
return queryString;
134+
return this.queryString;
124135
}
125136

126137
@Override
127138
public String getRequestURI() {
128-
if (!decodePathsFlag) {
129-
decodePaths();
139+
int decodePathsQueryIndex;
140+
if (decodePathsFlag) {
141+
decodePathsQueryIndex = this.decodePathsQueryIndex;
142+
} else {
143+
decodePathsQueryIndex = decodePaths();
144+
}
145+
if (!getRequestURIFlag) {
146+
if (decodePathsQueryIndex == -1) {
147+
this.requestURI = dispatchPath;
148+
} else {
149+
this.requestURI = dispatchPath.substring(0, decodePathsQueryIndex);
150+
}
130151
}
131-
return requestURI;
152+
return this.requestURI;
132153
}
133154

134155
@Override
@@ -203,21 +224,12 @@ public Enumeration<String> getParameterNames() {
203224
/**
204225
* Parsing path
205226
*/
206-
private void decodePaths() {
227+
private int decodePaths() {
207228
String requestURI = dispatchPath;
208-
if (requestURI != null) {
209-
String queryString;
210-
int queryInx = requestURI.indexOf('?');
211-
if (queryInx != -1) {
212-
queryString = requestURI.substring(queryInx + 1);
213-
requestURI = requestURI.substring(0, queryInx);
214-
} else {
215-
queryString = null;
216-
}
217-
this.requestURI = requestURI;
218-
this.queryString = queryString;
219-
}
229+
int decodePathsQueryIndex = requestURI == null ? -1 : requestURI.indexOf('?');
230+
this.decodePathsQueryIndex = decodePathsQueryIndex;
220231
this.decodePathsFlag = true;
232+
return decodePathsQueryIndex;
221233
}
222234

223235
/**

0 commit comments

Comments
 (0)