diff --git a/README-Android.md b/README-Android.md index f98195c..63e7a48 100644 --- a/README-Android.md +++ b/README-Android.md @@ -1,3 +1,10 @@ +Version 3.23.9.1 +New features: +1. Allow you set custom dns resolver + +Third-party dependence: +1. Remove java-xmlbuilder, use default javax.xml lib +----------------------------------------------------------------------------------- Version 3.23.9 New features: 1. Allow you set\get\list\delete bucket inventory configuration diff --git a/README-Java.md b/README-Java.md index 7800ca4..b48ecab 100644 --- a/README-Java.md +++ b/README-Java.md @@ -1,3 +1,10 @@ +Version 3.23.9.1 +New features: +1. Allow you set custom dns resolver + +Third-party dependence: +1. Remove java-xmlbuilder, use default javax.xml lib +----------------------------------------------------------------------------------- Version 3.23.9 New features: 1. Allow you set\get\list\delete bucket inventory configuration diff --git a/README.MD b/README.MD index d58773f..67b98eb 100644 --- a/README.MD +++ b/README.MD @@ -1,3 +1,10 @@ +Version 3.23.9.1 +New features: +1. Allow you set custom dns resolver + +Third-party dependence: +1. Remove java-xmlbuilder, use default javax.xml lib +----------------------------------------------------------------------------------- Version 3.23.9 New features: 1. Allow you set\get\list\delete bucket inventory configuration diff --git a/README_CN.MD b/README_CN.MD index 31609bd..180466c 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -1,3 +1,10 @@ +Version 3.23.9.1 +New features: +1. 支持设置自定义dns解析器 + +Third-party dependence: +1. 移除 java-xmlbuilder, 使用默认的javax.xml库 +----------------------------------------------------------------------------------- Version 3.23.9 New features: 1. 新增配置桶清单接口 diff --git a/app/src/main/java/com/obs/services/AbstractClient.java b/app/src/main/java/com/obs/services/AbstractClient.java index 793687c..51a1d5b 100644 --- a/app/src/main/java/com/obs/services/AbstractClient.java +++ b/app/src/main/java/com/obs/services/AbstractClient.java @@ -50,14 +50,9 @@ import com.obs.services.model.V4PostSignatureResponse; import com.obs.services.model.V4TemporarySignatureRequest; import com.obs.services.model.V4TemporarySignatureResponse; -import static com.jamesmurty.utils.BaseXMLBuilder.failIfExternalEntityParsingCannotBeConfigured; public abstract class AbstractClient extends ObsService implements Closeable, IObsClient, IFSClient { private static final ILogger ILOG = LoggerBuilder.getLogger(AbstractClient.class); - - static { - failIfExternalEntityParsingCannotBeConfigured = false; - } protected void init(String accessKey, String secretKey, String securityToken, ObsConfiguration config) { InterfaceLogBean reqBean = new InterfaceLogBean("ObsClient", config.getEndPoint(), ""); @@ -73,7 +68,7 @@ protected void init(String accessKey, String secretKey, String securityToken, Ob if (this.isAuthTypeNegotiation()) { this.getProviderCredentials().setIsAuthTypeNegotiation(true); } - this.initHttpClient(config.getHttpDispatcher()); + this.initHttpClient(config.getHttpDispatcher(), config.getCustomizedDnsImpl()); OBSXMLBuilder.setXmlDocumentBuilderFactoryClass(config.getXmlDocumentBuilderFactoryClass()); reqBean.setRespTime(new Date()); reqBean.setResultCode(Constants.RESULTCODE_SUCCESS); diff --git a/app/src/main/java/com/obs/services/ObsConfiguration.java b/app/src/main/java/com/obs/services/ObsConfiguration.java index 9e8ea09..d2d6fcb 100644 --- a/app/src/main/java/com/obs/services/ObsConfiguration.java +++ b/app/src/main/java/com/obs/services/ObsConfiguration.java @@ -22,6 +22,7 @@ import com.obs.services.model.HttpProtocolTypeEnum; import okhttp3.Dispatcher; +import okhttp3.Dns; import java.security.SecureRandom; @@ -96,6 +97,8 @@ public class ObsConfiguration implements Cloneable { private HttpProtocolTypeEnum httpProtocolType; private Dispatcher httpDispatcher; + + private Dns customizedDnsImpl; private String xmlDocumentBuilderFactoryClass; @@ -878,6 +881,26 @@ public void setHttpDispatcher(Dispatcher httpDispatcher) { this.httpDispatcher = httpDispatcher; } + + /** + * Obtain the customized Dns. + * + * @return customizedDnsImpl + * + */ + public Dns getCustomizedDnsImpl() { + return customizedDnsImpl; + } + + /** + * set the customized Dns. + * + * @param customizedDnsImpl + * Customized Dns + */ + public void setCustomizedDnsImpl(Dns customizedDnsImpl) { + this.customizedDnsImpl = customizedDnsImpl; + } public String getXmlDocumentBuilderFactoryClass() { return xmlDocumentBuilderFactoryClass; } diff --git a/app/src/main/java/com/obs/services/internal/Constants.java b/app/src/main/java/com/obs/services/internal/Constants.java index c1b9a80..5295eb1 100644 --- a/app/src/main/java/com/obs/services/internal/Constants.java +++ b/app/src/main/java/com/obs/services/internal/Constants.java @@ -213,7 +213,7 @@ public static class ObsRequestParams { public static final TimeZone GMT_TIMEZONE = TimeZone.getTimeZone("GMT"); - public static final String OBS_SDK_VERSION = "3.23.9"; + public static final String OBS_SDK_VERSION = "3.23.9.1"; public static final String USER_AGENT_VALUE = "obs-sdk-java/" + Constants.OBS_SDK_VERSION; diff --git a/app/src/main/java/com/obs/services/internal/RestConnectionService.java b/app/src/main/java/com/obs/services/internal/RestConnectionService.java index 39dfc2d..384c506 100644 --- a/app/src/main/java/com/obs/services/internal/RestConnectionService.java +++ b/app/src/main/java/com/obs/services/internal/RestConnectionService.java @@ -32,6 +32,7 @@ import com.obs.services.internal.utils.ServiceUtils; import com.obs.services.model.HttpMethodEnum; import okhttp3.Dispatcher; +import okhttp3.Dns; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; @@ -55,10 +56,10 @@ public class RestConnectionService { protected volatile ProviderCredentials credentials; - protected void initHttpClient(Dispatcher httpDispatcher) { + protected void initHttpClient(Dispatcher httpDispatcher, Dns customizedDnsImpl) { OkHttpClient.Builder builder = RestUtils.initHttpClientBuilder(obsProperties, keyManagerFactory, - trustManagerFactory, httpDispatcher, credentials.getSecureRandom()); + trustManagerFactory, httpDispatcher, customizedDnsImpl, credentials.getSecureRandom()); if (this.obsProperties.getBoolProperty(ObsConstraint.PROXY_ISABLE, true)) { String proxyHostAddress = this.obsProperties.getStringProperty(ObsConstraint.PROXY_HOST, null); diff --git a/app/src/main/java/com/obs/services/internal/utils/RestUtils.java b/app/src/main/java/com/obs/services/internal/utils/RestUtils.java index 4658785..8c477fc 100644 --- a/app/src/main/java/com/obs/services/internal/utils/RestUtils.java +++ b/app/src/main/java/com/obs/services/internal/utils/RestUtils.java @@ -14,6 +14,37 @@ package com.obs.services.internal.utils; +import com.obs.log.ILogger; +import com.obs.log.LoggerBuilder; +import com.obs.services.exception.ObsException; +import com.obs.services.internal.Constants; +import com.obs.services.internal.Constants.CommonHeaders; +import com.obs.services.internal.ObsConstraint; +import com.obs.services.internal.ObsProperties; +import com.obs.services.internal.ServiceException; +import com.obs.services.internal.ext.ExtObsConstraint; +import com.obs.services.model.HttpProtocolTypeEnum; +import okhttp3.Authenticator; +import okhttp3.ConnectionPool; +import okhttp3.Credentials; +import okhttp3.Dispatcher; +import okhttp3.Dns; +import okhttp3.OkHttpClient; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.Route; +import org.jetbrains.annotations.NotNull; + +import javax.net.SocketFactory; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.lang.reflect.Method; @@ -36,38 +67,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.net.SocketFactory; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - -import com.obs.log.ILogger; -import com.obs.log.LoggerBuilder; -import com.obs.services.exception.ObsException; -import com.obs.services.internal.Constants; -import com.obs.services.internal.Constants.CommonHeaders; -import com.obs.services.internal.ObsConstraint; -import com.obs.services.internal.ObsProperties; -import com.obs.services.internal.ServiceException; -import com.obs.services.internal.ext.ExtObsConstraint; -import com.obs.services.model.HttpProtocolTypeEnum; - -import okhttp3.Authenticator; -import okhttp3.ConnectionPool; -import okhttp3.Credentials; -import okhttp3.Dispatcher; -import okhttp3.Dns; -import okhttp3.OkHttpClient; -import okhttp3.Protocol; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.Route; - public class RestUtils { private static final ILogger log = LoggerBuilder.getLogger(RestUtils.class); @@ -330,7 +329,7 @@ public Socket createSocket(InetAddress address, int port, InetAddress localAddre public static OkHttpClient.Builder initHttpClientBuilder(ObsProperties obsProperties, KeyManagerFactory keyManagerFactory, TrustManagerFactory trustManagerFactory, - Dispatcher httpDispatcher, SecureRandom secureRandom) { + Dispatcher httpDispatcher, Dns customizedDnsImpl, SecureRandom secureRandom) { List protocols = new ArrayList(2); protocols.add(Protocol.HTTP_1_1); @@ -351,6 +350,8 @@ public static OkHttpClient.Builder initHttpClientBuilder(ObsProperties obsProper ObsConstraint.DEFAULT_IDLE_CONNECTION_TIME), TimeUnit.MILLISECONDS); + Dns dns = customizedDnsImpl == null ? new DefaultObsDns() : customizedDnsImpl; + builder.protocols(protocols).followRedirects(false).followSslRedirects(false) .retryOnConnectionFailure( obsProperties.getBoolProperty(ExtObsConstraint.IS_RETRY_ON_CONNECTION_FAILURE_IN_OKHTTP, false)) @@ -364,11 +365,7 @@ public static OkHttpClient.Builder initHttpClientBuilder(ObsProperties obsProper .connectionPool(pool) .hostnameVerifier((hostname, session) -> !obsProperties.getBoolProperty(ObsConstraint.HTTP_STRICT_HOSTNAME_VERIFICATION, false) || HttpsURLConnection.getDefaultHostnameVerifier().verify(obsProperties.getStringProperty(ObsConstraint.END_POINT, ""), session)) - .dns(hostname -> { - List adds = Dns.SYSTEM.lookup(hostname); - log.info("internet host address:" + adds); - return adds; - }); + .dns(dns); int socketReadBufferSize = obsProperties.getIntProperty(ObsConstraint.SOCKET_READ_BUFFER_SIZE, -1); int socketWriteBufferSize = obsProperties.getIntProperty(ObsConstraint.SOCKET_WRITE_BUFFER_SIZE, -1); @@ -479,4 +476,22 @@ public static String readBodyFromResponse(Response response) { } return body; } + public static class DefaultObsDns implements Dns { + public DefaultObsDns() { + log.info("use Default Dns"); + } + + /** + * @param hostname + * @return + * @throws UnknownHostException + */ + @NotNull + @Override + public List lookup(@NotNull String hostname) throws UnknownHostException { + List adds = Dns.SYSTEM.lookup(hostname); + log.info("internet host address:" + adds); + return adds; + } + } } diff --git a/app/src/main/java/com/obs/services/internal/xml/OBSXMLBuilder.java b/app/src/main/java/com/obs/services/internal/xml/OBSXMLBuilder.java index 1bc4db3..44c4b97 100644 --- a/app/src/main/java/com/obs/services/internal/xml/OBSXMLBuilder.java +++ b/app/src/main/java/com/obs/services/internal/xml/OBSXMLBuilder.java @@ -3,54 +3,69 @@ * Licensed 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 com.obs.services.internal.xml; -import com.jamesmurty.utils.BaseXMLBuilder; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import javax.xml.namespace.NamespaceContext; +import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; -import javax.xml.xpath.XPathExpressionException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import java.io.IOException; +import java.io.StringWriter; import java.security.AccessController; import java.security.PrivilegedAction; -public class OBSXMLBuilder extends BaseXMLBuilder { - +public class OBSXMLBuilder { private static final String DEFAULT_PACKAGE = "com.sun.org.apache.xerces.internal"; - private static String xmlDocumentBuilderFactoryClass = + private static String xmlDocumentBuilderFactoryClass = "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"; - + + private Document xmlDocument; + private Node xmlNode; + public static void setXmlDocumentBuilderFactoryClass(String className) { - if (null != className - && !className.trim().equals("")) { + if (null != className && !className.trim().equals("")) { xmlDocumentBuilderFactoryClass = className; } } - + protected OBSXMLBuilder(Document xmlDocument) { - super(xmlDocument); + this.xmlDocument = xmlDocument; + this.xmlNode = xmlDocument.getDocumentElement(); } protected OBSXMLBuilder(Node myNode, Node parentNode) { - super(myNode, parentNode); + this.xmlNode = myNode; + if (myNode instanceof Document) { + this.xmlDocument = (Document) myNode; + } else { + this.xmlDocument = myNode.getOwnerDocument(); + } + + if (parentNode != null) { + parentNode.appendChild(myNode); + } } private static DocumentBuilderFactory findDocumentBuilderFactory() { @@ -61,14 +76,18 @@ private static DocumentBuilderFactory findDocumentBuilderFactory() { return newInstance(DocumentBuilderFactory.class, xmlDocumentBuilderFactoryClass, null, true, false); } - protected static Document createDocumentImpl(String name, String namespaceURI, boolean enableExternalEntities, - boolean isNamespaceAware) throws ParserConfigurationException, FactoryConfigurationError { + protected static Document createDocumentImpl( + String name, String namespaceURI, boolean isNamespaceAware) + throws ParserConfigurationException, FactoryConfigurationError { DocumentBuilderFactory factory = OBSXMLBuilder.findDocumentBuilderFactory(); + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + factory.setFeature("http://xml.org/sax/features/external-general-entities", false); + factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); factory.setNamespaceAware(isNamespaceAware); - enableOrDisableExternalEntityParsing(factory, enableExternalEntities); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.newDocument(); - Element rootElement = null; + Element rootElement; if (namespaceURI != null && namespaceURI.length() > 0) { rootElement = document.createElementNS(namespaceURI, name); } else { @@ -78,36 +97,37 @@ protected static Document createDocumentImpl(String name, String namespaceURI, b return document; } - protected static Document parseDocumentImpl(InputSource inputSource, boolean enableExternalEntities, - boolean isNamespaceAware) throws ParserConfigurationException, SAXException, IOException { + protected static Document parseDocumentImpl( + InputSource inputSource, boolean isNamespaceAware) + throws ParserConfigurationException, SAXException, IOException { DocumentBuilderFactory factory = OBSXMLBuilder.findDocumentBuilderFactory(); factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); factory.setFeature("http://xml.org/sax/features/external-general-entities", false); factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); factory.setNamespaceAware(isNamespaceAware); - enableOrDisableExternalEntityParsing(factory, enableExternalEntities); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(inputSource); return document; } private static ClassLoader getContextClassLoader() throws SecurityException { - return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - cl = Thread.currentThread().getContextClassLoader(); - - if (cl == null) { - cl = ClassLoader.getSystemClassLoader(); - } - return cl; - } - }); - } - - private static Class getProviderClass(String className, ClassLoader cl, boolean doFallback, - boolean useBSClsLoader) throws ClassNotFoundException { + return (ClassLoader) + AccessController.doPrivileged( + (PrivilegedAction) + () -> { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + + if (cl == null) { + cl = ClassLoader.getSystemClassLoader(); + } + return cl; + }); + } + + private static Class getProviderClass( + String className, ClassLoader cl, boolean doFallback, boolean useBSClsLoader) + throws ClassNotFoundException { try { if (cl == null) { if (useBSClsLoader) { @@ -130,8 +150,9 @@ private static Class getProviderClass(String className, ClassLoader cl, boole } } - private static T newInstance(Class type, String className, ClassLoader cl, boolean doFallback, - boolean useBSClsLoader) throws FactoryConfigurationError { + private static T newInstance( + Class type, String className, ClassLoader cl, boolean doFallback, boolean useBSClsLoader) + throws FactoryConfigurationError { if (System.getSecurityManager() != null) { if (className != null && className.startsWith(DEFAULT_PACKAGE)) { cl = null; @@ -154,224 +175,103 @@ private static T newInstance(Class type, String className, ClassLoader cl } public static OBSXMLBuilder create(String name) throws ParserConfigurationException, FactoryConfigurationError { - return new OBSXMLBuilder(createDocumentImpl(name, null, false, true)); + return new OBSXMLBuilder(createDocumentImpl(name, null, true)); } - public static OBSXMLBuilder parse(InputSource inputSource, boolean enableExternalEntities, boolean isNamespaceAware) + public static OBSXMLBuilder parse(InputSource inputSource, boolean isNamespaceAware) throws ParserConfigurationException, SAXException, IOException { - return new OBSXMLBuilder(parseDocumentImpl(inputSource, enableExternalEntities, isNamespaceAware)); + return new OBSXMLBuilder(parseDocumentImpl(inputSource, isNamespaceAware)); } public static OBSXMLBuilder parse(InputSource inputSource) throws ParserConfigurationException, SAXException, IOException { - return OBSXMLBuilder.parse(inputSource, false, true); - } - - @Override - public OBSXMLBuilder stripWhitespaceOnlyTextNodes() throws XPathExpressionException { - super.stripWhitespaceOnlyTextNodesImpl(); - return this; + return OBSXMLBuilder.parse(inputSource, true); } - @Override - public OBSXMLBuilder importXMLBuilder(BaseXMLBuilder builder) { - super.importXMLBuilderImpl(builder); + public OBSXMLBuilder importXMLBuilder(OBSXMLBuilder builder) { + Node importedNode = this.getDocument().importNode(builder.getDocument().getDocumentElement(), true); + this.xmlNode.appendChild(importedNode); return this; } - @Override - public OBSXMLBuilder root() { - return new OBSXMLBuilder(getDocument()); - } - - @Override - public OBSXMLBuilder xpathFind(String xpath, NamespaceContext nsContext) throws XPathExpressionException { - Node foundNode = super.xpathFindImpl(xpath, nsContext); - return new OBSXMLBuilder(foundNode, null); - } - - @Override - public OBSXMLBuilder xpathFind(String xpath) throws XPathExpressionException { - return xpathFind(xpath, null); - } - - @Override public OBSXMLBuilder element(String name) { - String namespaceURI = super.lookupNamespaceURIImpl(name); + String namespaceURI = lookupNamespaceURI(name); return element(name, namespaceURI); } - @Override public OBSXMLBuilder elem(String name) { return element(name); } - @Override public OBSXMLBuilder e(String name) { return element(name); } - @Override public OBSXMLBuilder element(String name, String namespaceURI) { - Element elem = super.elementImpl(name, namespaceURI); + Element elem = elementImpl(name, namespaceURI); return new OBSXMLBuilder(elem, this.getElement()); } - @Override - public OBSXMLBuilder elementBefore(String name) { - Element newElement = super.elementBeforeImpl(name); - return new OBSXMLBuilder(newElement, null); - } - - @Override - public OBSXMLBuilder elementBefore(String name, String namespaceURI) { - Element newElement = super.elementBeforeImpl(name, namespaceURI); - return new OBSXMLBuilder(newElement, null); + public Element elementImpl(String name, String namespaceURI) { + return namespaceURI == null + ? this.getDocument().createElement(name) + : this.getDocument().createElementNS(namespaceURI, name); } - @Override public OBSXMLBuilder attribute(String name, String value) { - super.attributeImpl(name, value); + attributeImpl(name, value); return this; } - @Override - public OBSXMLBuilder attr(String name, String value) { - return attribute(name, value); + public void textImpl(String value, boolean replaceText) { + if (value == null) { + throw new IllegalArgumentException("Illegal null text value"); + } else { + if (replaceText) { + this.xmlNode.setTextContent(value); + } else { + this.xmlNode.appendChild(this.getDocument().createTextNode(value)); + } + } } - @Override - public OBSXMLBuilder a(String name, String value) { + public void attributeImpl(String name, String value) { + if (!(this.xmlNode instanceof Element)) { + throw new RuntimeException("Cannot add an attribute to non-Element underlying node: " + this.xmlNode); + } else { + ((Element) this.xmlNode).setAttribute(name, value); + } + } + + public OBSXMLBuilder attr(String name, String value) { return attribute(name, value); } - @Override public OBSXMLBuilder text(String value, boolean replaceText) { - super.textImpl(value, replaceText); + textImpl(value, replaceText); return this; } - @Override public OBSXMLBuilder text(String value) { return this.text(value, false); } - @Override public OBSXMLBuilder t(String value) { return text(value); } - @Override - public OBSXMLBuilder cdata(String data) { - super.cdataImpl(data); - return this; - } - - @Override - public OBSXMLBuilder data(String data) { - return cdata(data); - } - - @Override - public OBSXMLBuilder d(String data) { - return cdata(data); - } + protected Node upImpl(int steps) { + Node currNode = this.xmlNode; - @Override - public OBSXMLBuilder cdata(byte[] data) { - super.cdataImpl(data); - return this; - } - - @Override - public OBSXMLBuilder data(byte[] data) { - return cdata(data); - } - - @Override - public OBSXMLBuilder d(byte[] data) { - return cdata(data); - } - - @Override - public OBSXMLBuilder comment(String comment) { - super.commentImpl(comment); - return this; - } - - @Override - public OBSXMLBuilder cmnt(String comment) { - return comment(comment); - } - - @Override - public OBSXMLBuilder c(String comment) { - return comment(comment); - } - - @Override - public OBSXMLBuilder instruction(String target, String data) { - super.instructionImpl(target, data); - return this; - } - - @Override - public OBSXMLBuilder inst(String target, String data) { - return instruction(target, data); - } - - @Override - public OBSXMLBuilder i(String target, String data) { - return instruction(target, data); - } - - @Override - public OBSXMLBuilder insertInstruction(String target, String data) { - super.insertInstructionImpl(target, data); - return this; - } - - @Override - public OBSXMLBuilder reference(String name) { - super.referenceImpl(name); - return this; - } - - @Override - public OBSXMLBuilder ref(String name) { - return reference(name); - } - - @Override - public OBSXMLBuilder r(String name) { - return reference(name); - } - - @Override - public OBSXMLBuilder namespace(String prefix, String namespaceURI) { - super.namespaceImpl(prefix, namespaceURI); - return this; - } - - @Override - public OBSXMLBuilder ns(String prefix, String namespaceURI) { - return attribute(prefix, namespaceURI); - } - - @Override - public OBSXMLBuilder namespace(String namespaceURI) { - this.namespace(null, namespaceURI); - return this; - } + for (int stepCount = 0; currNode.getParentNode() != null && stepCount < steps; ++stepCount) { + currNode = currNode.getParentNode(); + } - @Override - public OBSXMLBuilder ns(String namespaceURI) { - return namespace(namespaceURI); + return currNode; } - @Override public OBSXMLBuilder up(int steps) { - Node currNode = super.upImpl(steps); + Node currNode = upImpl(steps); if (currNode instanceof Document) { return new OBSXMLBuilder((Document) currNode); } else { @@ -379,24 +279,44 @@ public OBSXMLBuilder up(int steps) { } } - @Override public OBSXMLBuilder up() { return up(1); } - @Override - public OBSXMLBuilder document() { - return new OBSXMLBuilder(getDocument(), null); + public Element getElement() { + return this.xmlNode instanceof Element ? (Element) this.xmlNode : null; + } + + protected String lookupNamespaceURI(String name) { + String prefix = this.getPrefixFromQualifiedName(name); + return this.xmlNode.lookupNamespaceURI(prefix); + } + + protected String getPrefixFromQualifiedName(String qualifiedName) { + int colonPos = qualifiedName.indexOf(58); + return colonPos > 0 ? qualifiedName.substring(0, colonPos) : null; + } + + public Document getDocument() { + return this.xmlDocument; + } + + public String asString() throws TransformerException { + TransformerFactory tf = TransformerFactory.newInstance(); + tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + Transformer transformer = tf.newTransformer(); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + StringWriter writer = new StringWriter(); + transformer.transform(new DOMSource(this.getDocument()), new StreamResult(writer)); + return writer.getBuffer().toString().replaceAll("|\r", ""); } - @Override public int hashCode() throws UnsupportedOperationException { throw new UnsupportedOperationException(); } - @Override public boolean equals(Object obj) { return obj == this; } - } diff --git a/app/src/test/java/com/obs/test/TestTools.java b/app/src/test/java/com/obs/test/TestTools.java index 1db481f..7898cb0 100644 --- a/app/src/test/java/com/obs/test/TestTools.java +++ b/app/src/test/java/com/obs/test/TestTools.java @@ -1,12 +1,15 @@ package com.obs.test; +import static org.junit.Assert.assertTrue; + import com.obs.services.ObsClient; import com.obs.services.ObsConfiguration; +import com.obs.services.crypto.CryptoObsClient; +import com.obs.services.crypto.CtrRSACipherGenerator; import com.obs.services.model.AbortMultipartUploadRequest; import com.obs.services.model.AuthTypeEnum; import com.obs.services.model.BucketTypeEnum; import com.obs.services.model.CreateBucketRequest; -import com.obs.services.model.DeleteObjectsRequest; import com.obs.services.model.HeaderResponse; import com.obs.services.model.ListMultipartUploadsRequest; import com.obs.services.model.ListVersionsRequest; @@ -15,6 +18,8 @@ import com.obs.services.model.MultipartUploadListing; import com.obs.services.model.VersionOrDeleteMarker; import com.obs.test.tools.PropertiesTools; + +import okhttp3.Dns; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.Appender; import org.apache.logging.log4j.core.LoggerContext; @@ -30,12 +35,15 @@ import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.util.Arrays; +import java.util.Collections; import java.util.List; -import static org.junit.Assert.assertTrue; - public class TestTools { - private static final File file = new File("app/src/test/resource/test_data.properties"); public static File getPropertiesFile() { @@ -97,6 +105,63 @@ public static ObsClient getPipelineEnvironment() { return null; } + public static ObsClient getPipelineEnvironmentWithCustomisedDns(Dns customizedDns) { + try { + String endPoint = PropertiesTools.getInstance(file).getProperties("environment.endpoint"); + String ak = PropertiesTools.getInstance(file).getProperties("environment.ak"); + String sk = PropertiesTools.getInstance(file).getProperties("environment.sk"); + String authType = PropertiesTools.getInstance(file).getProperties("environment.authType"); + ObsConfiguration config = new ObsConfiguration(); + config.setSocketTimeout(30000); + config.setConnectionTimeout(10000); + config.setEndPoint(endPoint); + config.setAuthTypeNegotiation(false); + config.setCustomizedDnsImpl(customizedDns); + if (authType.equals("v2")) { + config.setAuthType(AuthTypeEnum.V2); + } else { + config.setAuthType(AuthTypeEnum.OBS); + } + return new ObsClient(ak, sk, config); + + } catch (IllegalArgumentException | IOException e) { + e.printStackTrace(); + } + + return null; + } + + public static CryptoObsClient getPipelineCryptoEnvironment() { + try { + String endPoint = PropertiesTools.getInstance(file).getProperties("environment.endpoint"); + String ak = PropertiesTools.getInstance(file).getProperties("environment.ak"); + String sk = PropertiesTools.getInstance(file).getProperties("environment.sk"); + String authType = PropertiesTools.getInstance(file).getProperties("environment.authType"); + String privateKeyPath = PropertiesTools.getInstance(file).getProperties("rsa.privateKeyPath"); + String publicKeyPath = PropertiesTools.getInstance(file).getProperties("rsa.publicKeyPath"); + ObsConfiguration config = new ObsConfiguration(); + config.setSocketTimeout(30000); + config.setConnectionTimeout(10000); + config.setEndPoint(endPoint); + config.setAuthTypeNegotiation(false); + if (authType.equals("v2")) { + config.setAuthType(AuthTypeEnum.V2); + } else { + config.setAuthType(AuthTypeEnum.OBS); + } + PrivateKey privateKeyObj = CtrRSACipherGenerator.importPKCS8PrivateKey(privateKeyPath); + PublicKey publicKeyObj = CtrRSACipherGenerator.importPublicKey(publicKeyPath); + CtrRSACipherGenerator ctrRSACipherGenerator = + new CtrRSACipherGenerator( + "test_master_key", true, config.getSecureRandom(), privateKeyObj, publicKeyObj); + return new CryptoObsClient(ak, sk, config, ctrRSACipherGenerator); + + } catch (IllegalArgumentException | IOException | NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + + return null; + } public static String getKMSID() { try { @@ -198,7 +263,8 @@ public static ObsClient getExternalEnvironment() { config.setSocketTimeout(30000); config.setConnectionTimeout(10000); config.setEndPoint(endPoint); - config.setHttpProxy(PropertiesTools.getInstance(file).getProperties("environment.me.proxyaddr"), + config.setHttpProxy( + PropertiesTools.getInstance(file).getProperties("environment.me.proxyaddr"), Integer.parseInt(PropertiesTools.getInstance(file).getProperties("environment.me.proxyport")), PropertiesTools.getInstance(file).getProperties("environment.me.username"), PropertiesTools.getInstance(file).getProperties("environment.me.password")); @@ -260,12 +326,12 @@ public static void deleteObjects(ObsClient obsClient, String bucketName) { if (result.getVersions().length == 0) { break; } - DeleteObjectsRequest deleteRequest = new DeleteObjectsRequest(bucketName); - deleteRequest.setEncodingType("url"); - for (VersionOrDeleteMarker v : result.getVersions()) { - deleteRequest.addKeyAndVersion(v.getKey(), v.getVersionId()); + // 文件桶使用批删会有问题,所以此处改成遍历单个删除,兼容对象桶和文件桶(但是一次列举最大为一千个,超过一千个在文件桶来说也会有问题) + List versionOrDeleteMarkerLists = Arrays.asList(result.getVersions()); + Collections.reverse(versionOrDeleteMarkerLists); + for (VersionOrDeleteMarker v : versionOrDeleteMarkerLists) { + obsClient.deleteObject(bucketName, v.getKey()); } - obsClient.deleteObjects(deleteRequest); request.setKeyMarker(result.getNextKeyMarker()); request.setVersionIdMarker(result.getNextVersionIdMarker()); @@ -284,7 +350,8 @@ public static HeaderResponse delete_bucket(ObsClient obsClient, String bucketNam return obsClient.deleteBucket(bucketName); } - public static HeaderResponse createBucket(ObsClient obsClient, String bucketName, String location, boolean isPosix) { + public static HeaderResponse createBucket( + ObsClient obsClient, String bucketName, String location, boolean isPosix) { CreateBucketRequest request = new CreateBucketRequest(); request.setBucketName(bucketName); request.setBucketType(BucketTypeEnum.OBJECT); @@ -295,7 +362,7 @@ public static HeaderResponse createBucket(ObsClient obsClient, String bucketName return obsClient.createBucket(request); } - public static void genTestFile(String filePath, int fileSize) throws IOException { + public static void genTestFile(String filePath, int fileSizeKb) throws IOException { File testFile = new File(filePath); if (!testFile.exists()) { assertTrue(testFile.createNewFile()); @@ -305,7 +372,7 @@ public static void genTestFile(String filePath, int fileSize) throws IOException stringBuilder.append("TestOBS!"); } FileOutputStream outputStream = new FileOutputStream(filePath); - for (int i = 0; i < fileSize; i++) { + for (int i = 0; i < fileSizeKb; i++) { outputStream.write(stringBuilder.toString().getBytes(StandardCharsets.UTF_8)); } outputStream.close(); @@ -316,14 +383,12 @@ public static void initLog(StringWriter writer) { Configuration config = context.getConfiguration(); LoggerConfig LoggerConfig = config.getLoggerConfig("com.obs.services.internal.RestStorageService"); if (!LoggerConfig.getName().equals("com.obs.services.internal.RestStorageService")) { - LoggerConfig = new LoggerConfig("com.obs.services.internal.RestStorageService", - Level.DEBUG, true); + LoggerConfig = new LoggerConfig("com.obs.services.internal.RestStorageService", Level.DEBUG, true); } config.addLogger("com.obs.services.internal.RestStorageService", LoggerConfig); PatternLayout layout = PatternLayout.createDefaultLayout(config); - Appender appender = WriterAppender.createAppender(layout, null, writer, "StringWriter", - false, true); + Appender appender = WriterAppender.createAppender(layout, null, writer, "StringWriter", false, true); config.addAppender(appender); LoggerConfig.addAppender(appender, Level.DEBUG, null); appender.start(); diff --git a/pom-android.xml b/pom-android.xml index 339ead9..5edf591 100644 --- a/pom-android.xml +++ b/pom-android.xml @@ -4,7 +4,7 @@ com.huaweicloud esdk-obs-android - 3.23.9 + 3.23.9.1 jar OBS SDK for Android @@ -16,18 +16,6 @@ - - - com.jamesmurty.utils - java-xmlbuilder - 1.3 - - - net.iharder - base64 - - - com.squareup.okhttp3 okhttp diff --git a/pom-dependencies.xml b/pom-dependencies.xml index 3a0324c..e5e2ad2 100644 --- a/pom-dependencies.xml +++ b/pom-dependencies.xml @@ -15,18 +15,6 @@ - - com.jamesmurty.utils - java-xmlbuilder - 1.3 - - - net.iharder - base64 - - - - com.squareup.okhttp3 okhttp diff --git a/pom-java-optimization.xml b/pom-java-optimization.xml index 377c817..0eb819d 100644 --- a/pom-java-optimization.xml +++ b/pom-java-optimization.xml @@ -4,7 +4,7 @@ com.huaweicloud esdk-obs-java-optimised - 3.23.9 + 3.23.9.1 jar OBS SDK for Java Optimised @@ -15,17 +15,6 @@ - - com.jamesmurty.utils - java-xmlbuilder - 1.3 - - - net.iharder - base64 - - - com.squareup.okhttp3 okhttp diff --git a/pom-java.xml b/pom-java.xml index a27629d..01f63a7 100644 --- a/pom-java.xml +++ b/pom-java.xml @@ -4,7 +4,7 @@ com.huaweicloud esdk-obs-java - 3.23.9 + 3.23.9.1 jar OBS SDK for Java @@ -15,17 +15,6 @@ - - com.jamesmurty.utils - java-xmlbuilder - 1.3 - - - net.iharder - base64 - - - com.squareup.okhttp3 okhttp diff --git a/pom.xml b/pom.xml index f8bd487..8753994 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.huaweicloud esdk-obs-java - 3.23.9 + 3.23.9.1 jar OBS SDK for Java @@ -15,18 +15,6 @@ - - com.jamesmurty.utils - java-xmlbuilder - 1.3 - - - net.iharder - base64 - - - - com.squareup.okhttp3 okhttp