| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.dubbo.remoting.http; |
| |
| import org.apache.dubbo.remoting.Constants; |
| import org.apache.dubbo.rpc.Invocation; |
| |
| import java.io.Serializable; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| public class RequestTemplate implements Serializable { |
| private static final long serialVersionUID = 1L; |
| public static final String CONTENT_ENCODING = "Content-Encoding"; |
| private static final String CONTENT_LENGTH = "Content-Length"; |
| public static final String ENCODING_GZIP = "gzip"; |
| public static final String ENCODING_DEFLATE = "deflate"; |
| private static final List<String> EMPTY_ARRAYLIST = new ArrayList<>(); |
| |
| private final Map<String, Collection<String>> queries = new LinkedHashMap<>(); |
| private final Map<String, Collection<String>> headers = new LinkedHashMap<>(); |
| private String httpMethod; |
| private String path; |
| private String address; |
| private Object body; |
| private byte[] byteBody = new byte[0]; |
| private String protocol = "http://"; |
| private final Invocation invocation; |
| private String contextPath = ""; |
| private Class<?> bodyType; |
| |
| public RequestTemplate(Invocation invocation, String httpMethod, String address) { |
| this(invocation, httpMethod, address, ""); |
| } |
| |
| public RequestTemplate(Invocation invocation, String httpMethod, String address, String contextPath) { |
| this.httpMethod = httpMethod; |
| this.address = address; |
| this.invocation = invocation; |
| this.contextPath = contextPath; |
| } |
| |
| public String getURL() { |
| StringBuilder stringBuilder = new StringBuilder(getProtocol() + address); |
| |
| stringBuilder.append(getUri()); |
| return stringBuilder.toString(); |
| } |
| |
| public String getUri() { |
| StringBuilder stringBuilder = new StringBuilder(getContextPath() + path); |
| return stringBuilder.append(getQueryString()).toString(); |
| } |
| |
| public String getQueryString() { |
| |
| if (queries.isEmpty()) { |
| return ""; |
| } |
| |
| StringBuilder queryBuilder = new StringBuilder("?"); |
| for (String field : queries.keySet()) { |
| |
| Collection<String> queryValues = queries.get(field); |
| |
| if (queryValues == null || queryValues.isEmpty()) { |
| continue; |
| } |
| |
| for (String value : queryValues) { |
| queryBuilder.append('&'); |
| queryBuilder.append(field); |
| if (value == null) { |
| continue; |
| } |
| |
| queryBuilder.append('='); |
| queryBuilder.append(value); |
| } |
| } |
| |
| return queryBuilder.toString().replace("?&", "?"); |
| } |
| |
| public RequestTemplate path(String path) { |
| this.path = path; |
| return this; |
| } |
| |
| public String getHttpMethod() { |
| return httpMethod; |
| } |
| |
| public RequestTemplate httpMethod(String httpMethod) { |
| this.httpMethod = httpMethod; |
| return this; |
| } |
| |
| public byte[] getSerializedBody() { |
| return byteBody; |
| } |
| |
| public void serializeBody(byte[] body) { |
| addHeader(CONTENT_LENGTH, body.length); // must header |
| this.byteBody = body; |
| } |
| |
| public boolean isBodyEmpty() { |
| return getUnSerializedBody() == null; |
| } |
| |
| public RequestTemplate body(Object body, Class bodyType) { |
| this.body = body; |
| setBodyType(bodyType); |
| return this; |
| } |
| |
| public Object getUnSerializedBody() { |
| return body; |
| } |
| |
| public Map<String, Collection<String>> getAllHeaders() { |
| return headers; |
| } |
| |
| public Collection<String> getHeaders(String name) { |
| return headers.get(name); |
| } |
| |
| public String getHeader(String name) { |
| if (headers.containsKey(name)) { |
| |
| Collection<String> headers = getHeaders(name); |
| |
| if (headers.isEmpty()) { |
| return null; |
| } |
| String[] strings = headers.toArray(new String[0]); |
| return strings[0]; |
| |
| } else { |
| return null; |
| } |
| } |
| |
| public Collection<String> getEncodingValues() { |
| if (headers.containsKey(CONTENT_ENCODING)) { |
| return headers.get(CONTENT_ENCODING); |
| } |
| return EMPTY_ARRAYLIST; |
| } |
| |
| public boolean isGzipEncodedRequest() { |
| return getEncodingValues().contains(ENCODING_GZIP); |
| } |
| |
| public boolean isDeflateEncodedRequest() { |
| return getEncodingValues().contains(ENCODING_DEFLATE); |
| } |
| |
| public void addHeader(String key, String value) { |
| addValueByKey(key, value, this.headers); |
| } |
| |
| public void addHeader(String key, Object value) { |
| addValueByKey(key, String.valueOf(value), this.headers); |
| } |
| |
| public void addKeepAliveHeader(int time) { |
| addHeader(Constants.KEEP_ALIVE_HEADER, time); |
| addHeader(Constants.CONNECTION, Constants.KEEP_ALIVE); |
| } |
| |
| public void addHeaders(String key, Collection<String> values) { |
| Collection<String> header = getHeaders(key); |
| |
| if (header == null) { |
| header = new HashSet<>(); |
| this.headers.put(key, header); |
| } |
| header.addAll(values); |
| } |
| |
| public void addParam(String key, String value) { |
| addValueByKey(key, value, this.queries); |
| } |
| |
| public void addParam(String key, Object value) { |
| addParam(key, String.valueOf(value)); |
| } |
| |
| public Map<String, Collection<String>> getQueries() { |
| return queries; |
| } |
| |
| public Collection<String> getParam(String key) { |
| return getQueries().get(key); |
| } |
| |
| public void addParams(String key, Collection<String> values) { |
| Collection<String> params = getParam(key); |
| |
| if (params == null) { |
| params = new HashSet<>(); |
| this.queries.put(key, params); |
| } |
| params.addAll(values); |
| } |
| |
| public void addValueByKey(String key, String value, Map<String, Collection<String>> maps) { |
| |
| if (value == null) { |
| return; |
| } |
| |
| Collection<String> values = null; |
| if (!maps.containsKey(key)) { |
| values = new HashSet<>(); |
| maps.put(key, values); |
| } |
| values = maps.get(key); |
| |
| values.add(value); |
| } |
| |
| public Integer getContentLength() { |
| |
| if (!getAllHeaders().containsKey(CONTENT_LENGTH)) { |
| return null; |
| } |
| |
| HashSet<String> strings = (HashSet<String>) getAllHeaders().get(CONTENT_LENGTH); |
| |
| return Integer.parseInt(new ArrayList<>(strings).get(0)); |
| } |
| |
| public String getAddress() { |
| return address; |
| } |
| |
| public void setAddress(String address) { |
| addHeader("Host", address); // must header |
| this.address = address; |
| } |
| |
| public String getProtocol() { |
| return protocol; |
| } |
| |
| public void setProtocol(String protocol) { |
| this.protocol = protocol; |
| } |
| |
| public Invocation getInvocation() { |
| return invocation; |
| } |
| |
| public String getContextPath() { |
| if (contextPath == null || contextPath.length() == 0) { |
| return ""; |
| } |
| |
| if (contextPath.startsWith("/")) { |
| return contextPath; |
| } else { |
| return "/" + contextPath; |
| } |
| } |
| |
| public void setContextPath(String contextPath) { |
| this.contextPath = contextPath; |
| } |
| |
| public Class<?> getBodyType() { |
| return bodyType; |
| } |
| |
| public void setBodyType(Class<?> bodyType) { |
| this.bodyType = bodyType; |
| } |
| } |