Skip to content

Commit

Permalink
Headers zero copy (#14605)
Browse files Browse the repository at this point in the history
  • Loading branch information
oxsean authored Sep 2, 2024
1 parent 720f981 commit 010d926
Show file tree
Hide file tree
Showing 100 changed files with 2,412 additions and 984 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ public static boolean isNotEmpty(Collection<?> collection) {
* @return whether the given Map is empty
*/
public static boolean isEmptyMap(Map map) {
return map == null || map.size() == 0;
return map == null || map.isEmpty();
}

/**
Expand Down Expand Up @@ -438,22 +438,22 @@ public static <T> Set<T> newLinkedHashSet(int expectedSize) {
return new LinkedHashSet<>(capacity(expectedSize));
}

public static <T, K> Map<K, T> newHashMap(int expectedSize) {
public static <K, T> Map<K, T> newHashMap(int expectedSize) {
return new HashMap<>(capacity(expectedSize));
}

public static <T, K> Map<K, T> newLinkedHashMap(int expectedSize) {
public static <K, T> Map<K, T> newLinkedHashMap(int expectedSize) {
return new LinkedHashMap<>(capacity(expectedSize));
}

public static <T, K> Map<K, T> newConcurrentHashMap(int expectedSize) {
public static <K, T> Map<K, T> newConcurrentHashMap(int expectedSize) {
if (JRE.JAVA_8.isCurrentVersion()) {
return new SafeConcurrentHashMap<>(capacity(expectedSize));
}
return new ConcurrentHashMap<>(capacity(expectedSize));
}

public static <T, K> Map<K, T> newConcurrentHashMap() {
public static <K, T> Map<K, T> newConcurrentHashMap() {
if (JRE.JAVA_8.isCurrentVersion()) {
return new SafeConcurrentHashMap<>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs;

import org.apache.dubbo.remoting.http12.HttpHeaders;

import javax.ws.rs.core.AbstractMultivaluedMap;

import java.util.List;
Expand All @@ -26,4 +28,9 @@ public final class MultivaluedMapWrapper<K, V> extends AbstractMultivaluedMap<K,
public MultivaluedMapWrapper(Map<K, List<V>> store) {
super(store);
}

@SuppressWarnings({"unchecked", "rawtypes"})
public MultivaluedMapWrapper(HttpHeaders headers) {
super((Map) headers.asMap());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.filter;

import org.apache.dubbo.remoting.http12.HttpCookie;
import org.apache.dubbo.remoting.http12.HttpHeaderNames;
import org.apache.dubbo.remoting.http12.HttpRequest;
import org.apache.dubbo.remoting.http12.HttpResponse;
import org.apache.dubbo.remoting.http12.HttpUtils;
Expand Down Expand Up @@ -146,13 +147,13 @@ public EntityTag getEntityTag() {

@Override
public Date getLastModified() {
String value = response.header("last-modified");
String value = response.header(HttpHeaderNames.LAST_MODIFIED.getKey());
return value == null ? null : DateFormatter.parseHttpDate(value);
}

@Override
public URI getLocation() {
String location = response.header("location");
String location = response.header(HttpHeaderNames.LOCATION.getKey());
return location == null ? null : URI.create(location);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ public Object resolve(ParameterMeta parameter, HttpRequest request, HttpResponse
return new ServletWebRequest((HttpServletRequest) request);
}
if (type == HttpEntity.class) {
return new HttpEntity<>(CollectionUtils.toMultiValueMap(request.headers()));
return new HttpEntity<>(
CollectionUtils.toMultiValueMap(request.headers().asMap()));
}
if (type == HttpHeaders.class) {
return new HttpHeaders(CollectionUtils.toMultiValueMap(request.headers()));
return new HttpHeaders(
CollectionUtils.toMultiValueMap(request.headers().asMap()));
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.remoting.http12.HttpChannel;
import org.apache.dubbo.remoting.http12.HttpConstants;
import org.apache.dubbo.remoting.http12.HttpMetadata;
import org.apache.dubbo.remoting.http12.HttpVersion;
import org.apache.dubbo.remoting.http12.message.DefaultHttpRequest;
Expand Down Expand Up @@ -165,7 +166,7 @@ public StringBuffer getRequestURL() {
String scheme = getScheme();
int port = getServerPort();
url.append(scheme).append("://").append(getServerName());
if (("http".equals(scheme) && port != 80) || ("https".equals(scheme) && port != 443)) {
if (HttpConstants.HTTP.equals(scheme) && port != 80 || HttpConstants.HTTPS.equals(scheme) && port != 443) {
url.append(':');
url.append(port);
}
Expand Down Expand Up @@ -367,7 +368,7 @@ public Enumeration<Locale> getLocales() {

@Override
public boolean isSecure() {
return "https".equals(scheme());
return HttpConstants.HTTPS.equals(scheme());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ public void addDateHeader(String name, long date) {
addHeader(name, new Date(date));
}

@Override
public void setHeader(String name, String value) {
super.setHeader(name, value);
}

@Override
public void addHeader(String name, String value) {
super.addHeader(name, value);
}

@Override
public void setIntHeader(String name, int value) {
setHeader(name, String.valueOf(value));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@

import javax.servlet.http.HttpServletRequest;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

public final class HttpMetadataAdapter implements Http2Header {

Expand All @@ -43,16 +41,14 @@ public HttpServletRequest getRequest() {
public HttpHeaders headers() {
HttpHeaders headers = this.headers;
if (headers == null) {
headers = new HttpHeaders();
headers = HttpHeaders.create();
Enumeration<String> en = request.getHeaderNames();
while (en.hasMoreElements()) {
String key = en.nextElement();
List<String> values = new ArrayList<>(1);
Enumeration<String> ven = request.getHeaders(key);
while (ven.hasMoreElements()) {
values.add(ven.nextElement());
headers.add(key, ven.nextElement());
}
headers.put(key, values);
}
this.headers = headers;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.remoting.http12.HttpConstants;
import org.apache.dubbo.remoting.http12.HttpHeaderNames;
import org.apache.dubbo.remoting.http12.HttpHeaders;
import org.apache.dubbo.remoting.http12.HttpMetadata;
Expand All @@ -41,7 +41,6 @@
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
Expand Down Expand Up @@ -74,7 +73,7 @@ public void writeError(int code, Throwable throwable) {
if (isGrpc) {
response.setTrailerFields(() -> {
Map<String, String> map = new HashMap<>();
map.put(TripleHeaderEnum.STATUS_KEY.getHeader(), String.valueOf(code));
map.put(TripleHeaderEnum.STATUS_KEY.getName(), String.valueOf(code));
return map;
});
return;
Expand Down Expand Up @@ -141,8 +140,8 @@ public CompletableFuture<Void> writeHeader(HttpMetadata httpMetadata) {
if (endStream) {
response.setTrailerFields(() -> {
Map<String, String> map = new HashMap<>();
for (Entry<String, List<String>> entry : headers.entrySet()) {
map.put(entry.getKey(), entry.getValue().get(0));
for (Entry<CharSequence, String> entry : headers) {
map.put(entry.getKey().toString(), entry.getValue());
}
return map;
});
Expand All @@ -153,25 +152,19 @@ public CompletableFuture<Void> writeHeader(HttpMetadata httpMetadata) {
return completed();
}

for (Entry<String, List<String>> entry : headers.entrySet()) {
String key = entry.getKey();
List<String> values = entry.getValue();
for (Entry<CharSequence, String> entry : headers) {
String key = entry.getKey().toString();
String value = entry.getValue();
if (HttpHeaderNames.STATUS.getName().equals(key)) {
response.setStatus(Integer.parseInt(values.get(0)));
response.setStatus(Integer.parseInt(value));
continue;
}
if (isHttp1
&& HttpHeaderNames.TRANSFER_ENCODING.getName().equals(key)
&& "chunked".equals(CollectionUtils.first(values))) {
&& HttpConstants.CHUNKED.equals(value)) {
continue;
}
if (values.size() == 1) {
response.setHeader(key, values.get(0));
} else {
for (int i = 0, size = values.size(); i < size; i++) {
response.addHeader(key, values.get(i));
}
}
response.addHeader(key, value);
}
} catch (Throwable t) {
LOGGER.info("Failed to write header", t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ private boolean hasGrpcMapping(HttpServletRequest request) {
return false;
}

String group = request.getHeader(TripleHeaderEnum.SERVICE_GROUP.getHeader());
String version = request.getHeader(TripleHeaderEnum.SERVICE_VERSION.getHeader());
String group = request.getHeader(TripleHeaderEnum.SERVICE_GROUP.getName());
String version = request.getHeader(TripleHeaderEnum.SERVICE_VERSION.getName());
return pathResolver.resolve(path.getPath(), group, version) != null;
}

Expand All @@ -176,7 +176,7 @@ private static int resolveTimeout(HttpServletRequest request, boolean isGrpc) {
}
}
} else {
String timeoutString = request.getHeader(TripleHeaderEnum.SERVICE_TIMEOUT.getHeader());
String timeoutString = request.getHeader(TripleHeaderEnum.SERVICE_TIMEOUT.getName());
if (timeoutString != null) {
return Integer.parseInt(timeoutString) + 2000;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ protected void doOnCompleted(Throwable throwable) {
}
if (!headerSent) {
HttpHeaders headers = httpMetadata.headers();
headers.set(HttpHeaderNames.STATUS.getName(), resolveStatusCode(throwable));
headers.set(HttpHeaderNames.CONTENT_TYPE.getName(), responseEncoder.contentType());
headers.set(HttpHeaderNames.STATUS.getKey(), resolveStatusCode(throwable));
headers.set(HttpHeaderNames.CONTENT_TYPE.getKey(), responseEncoder.contentType());
}
trailersCustomizer.accept(httpMetadata.headers(), throwable);
getHttpChannel().writeHeader(httpMetadata);
Expand Down Expand Up @@ -248,15 +248,15 @@ protected final void sendMessage(HttpOutputMessage outputMessage) throws Throwab
protected final HttpMetadata buildMetadata(String statusCode, Object data, HttpOutputMessage httpOutputMessage) {
HttpMetadata httpMetadata = encodeHttpMetadata();
HttpHeaders headers = httpMetadata.headers();
headers.set(HttpHeaderNames.STATUS.getName(), statusCode);
headers.set(HttpHeaderNames.CONTENT_TYPE.getName(), responseEncoder.contentType());
headers.set(HttpHeaderNames.STATUS.getKey(), statusCode);
headers.set(HttpHeaderNames.CONTENT_TYPE.getKey(), responseEncoder.contentType());
if (altSvc != null) {
headers.set(HttpHeaderNames.ALT_SVC.getName(), altSvc);
headers.set(HttpHeaderNames.ALT_SVC.getKey(), altSvc);
}
if (data instanceof HttpResult) {
HttpResult<?> result = (HttpResult<?>) data;
if (result.getHeaders() != null) {
headers.putAll(result.getHeaders());
headers.add(result.getHeaders());
}
}
preMetadata(httpMetadata, httpOutputMessage);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.remoting.http12.h2;
package org.apache.dubbo.remoting.http12;

public enum Http2Headers {
PATH(":path"),
public final class HttpConstants {

METHOD(":method"),
public static final String TRAILERS = "trailers";

STATUS(":status");
public static final String CHUNKED = "chunked";

private final String name;
public static final String X_FORWARDED_PROTO = "x-forwarded-proto";
public static final String X_FORWARDED_HOST = "x-forwarded-host";
public static final String X_FORWARDED_PORT = "x-forwarded-port";

Http2Headers(String name) {
this.name = name;
}
public static final String HTTPS = "https";
public static final String HTTP = "http";

public String getName() {
return name;
}
private HttpConstants() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,56 @@
*/
package org.apache.dubbo.remoting.http12;

import io.netty.handler.codec.http2.Http2Headers.PseudoHeaderName;
import io.netty.util.AsciiString;

public enum HttpHeaderNames {
STATUS(":status"),
STATUS(PseudoHeaderName.STATUS.value()),

PATH(PseudoHeaderName.PATH.value()),

ACCEPT(io.netty.handler.codec.http.HttpHeaderNames.ACCEPT),

CONTENT_TYPE(io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE),

CONTENT_LENGTH(io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH),

CONTENT_LANGUAGE(io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LANGUAGE),

CONTENT_TYPE("content-type"),
TRANSFER_ENCODING(io.netty.handler.codec.http.HttpHeaderNames.TRANSFER_ENCODING),

CONTENT_LENGTH("content-length"),
LOCATION(io.netty.handler.codec.http.HttpHeaderNames.LOCATION),

TRANSFER_ENCODING("transfer-encoding"),
HOST(io.netty.handler.codec.http.HttpHeaderNames.HOST),

LOCATION("location"),
COOKIE(io.netty.handler.codec.http.HttpHeaderNames.COOKIE),

TE("te"),
SET_COOKIE(io.netty.handler.codec.http.HttpHeaderNames.SET_COOKIE),

ALT_SVC("alt-svc"),
LAST_MODIFIED(io.netty.handler.codec.http.HttpHeaderNames.LAST_MODIFIED),

ACCEPT("accept");
TE(io.netty.handler.codec.http.HttpHeaderNames.TE),

ALT_SVC(io.netty.handler.codec.http.HttpHeaderNames.ALT_SVC);

private final String name;
private final CharSequence key;

HttpHeaderNames(String name) {
this.name = name;
key = AsciiString.cached(name);
}

HttpHeaderNames(CharSequence key) {
name = key.toString();
this.key = key;
}

public String getName() {
return name;
}

public CharSequence getKey() {
return key;
}
}
Loading

0 comments on commit 010d926

Please sign in to comment.