mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-14 17:26:22 +01:00
start implementation of a new advanced http client, in order to fix issue #709
This commit is contained in:
189
scm-core/src/main/java/sonia/scm/net/ahc/AdvancedHttpClient.java
Normal file
189
scm-core/src/main/java/sonia/scm/net/ahc/AdvancedHttpClient.java
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advanced client for http operations. The {@link AdvancedHttpClient} replaces
|
||||||
|
* the much more simpler implementation {@link sonia.scm.net.HttpClient}. The
|
||||||
|
* {@link AdvancedHttpClient} offers a fluid interface for handling most common
|
||||||
|
* http operations. The {@link AdvancedHttpClient} can be injected by the
|
||||||
|
* default injection mechanism of SCM-Manager.
|
||||||
|
* <p> </p>
|
||||||
|
* <b>Http GET example:</b>
|
||||||
|
*
|
||||||
|
* <pre><code>
|
||||||
|
* AdvancedHttpResponse response = client.get("https://www.scm-manager.org")
|
||||||
|
* .decodeGZip(true)
|
||||||
|
* .request();
|
||||||
|
*
|
||||||
|
* System.out.println(response.contentAsString());
|
||||||
|
* </code></pre>
|
||||||
|
*
|
||||||
|
* <p> </p>
|
||||||
|
* <b>Http POST example:</b>
|
||||||
|
*
|
||||||
|
* <pre><code>
|
||||||
|
* AdvancedHttpResponse response = client.post("https://www.scm-manager.org")
|
||||||
|
* .formContent()
|
||||||
|
* .field("firstname", "Tricia")
|
||||||
|
* .field("lastname", "McMillan")
|
||||||
|
* .build()
|
||||||
|
* .request();
|
||||||
|
*
|
||||||
|
* if (response.isSuccessful()){
|
||||||
|
* System.out.println("success");
|
||||||
|
* }
|
||||||
|
* </code></pre>
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*
|
||||||
|
* @apiviz.landmark
|
||||||
|
*/
|
||||||
|
public abstract class AdvancedHttpClient
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the given request and returns the http response. Implementation
|
||||||
|
* have to check, if the instance if from type
|
||||||
|
* {@link AdvancedHttpRequestWithBody} in order to handle request contents.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param request request to execute
|
||||||
|
*
|
||||||
|
* @return http response
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected abstract AdvancedHttpResponse request(BaseHttpRequest<?> request)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a builder for a DELETE request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param url request url
|
||||||
|
*
|
||||||
|
* @return request builder
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody delete(String url)
|
||||||
|
{
|
||||||
|
return new AdvancedHttpRequestWithBody(this, HttpMethod.DELETE, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a builder for a HEAD request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param url request url
|
||||||
|
*
|
||||||
|
* @return request builder
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequest head(String url)
|
||||||
|
{
|
||||||
|
return new AdvancedHttpRequest(this, HttpMethod.HEAD, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a request builder with a custom method. <strong>Note:</strong> not
|
||||||
|
* every method is supported by the underlying implementation of the http
|
||||||
|
* client.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param method http method
|
||||||
|
* @param url request url
|
||||||
|
*
|
||||||
|
* @return request builder
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody method(String method, String url)
|
||||||
|
{
|
||||||
|
return new AdvancedHttpRequestWithBody(this, method, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a builder for a OPTIONS request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param url request url
|
||||||
|
*
|
||||||
|
* @return request builder
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody options(String url)
|
||||||
|
{
|
||||||
|
return new AdvancedHttpRequestWithBody(this, HttpMethod.OPTIONS, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a builder for a POST request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param url request url
|
||||||
|
*
|
||||||
|
* @return request builder
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody post(String url)
|
||||||
|
{
|
||||||
|
return new AdvancedHttpRequestWithBody(this, HttpMethod.POST, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a builder for a PUT request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param url request url
|
||||||
|
*
|
||||||
|
* @return request builder
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody put(String url)
|
||||||
|
{
|
||||||
|
return new AdvancedHttpRequestWithBody(this, HttpMethod.PUT, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a builder for a GET request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param url request url
|
||||||
|
*
|
||||||
|
* @return request builder
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequest get(String url)
|
||||||
|
{
|
||||||
|
return new AdvancedHttpRequest(this, HttpMethod.GET, url);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An http request without {@link Content} for example a GET or HEAD request.
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public class AdvancedHttpRequest extends BaseHttpRequest<AdvancedHttpRequest>
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link AdvancedHttpRequest}
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* @param method
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
AdvancedHttpRequest(AdvancedHttpClient client, String method,
|
||||||
|
String url)
|
||||||
|
{
|
||||||
|
super(client, method, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code this}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected AdvancedHttpRequest self()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Http request with body.
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public class AdvancedHttpRequestWithBody
|
||||||
|
extends BaseHttpRequest<AdvancedHttpRequestWithBody>
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link AdvancedHttpRequestWithBody}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param client http client
|
||||||
|
* @param method http method
|
||||||
|
* @param url url
|
||||||
|
*/
|
||||||
|
AdvancedHttpRequestWithBody(AdvancedHttpClient client, String method,
|
||||||
|
String url)
|
||||||
|
{
|
||||||
|
super(client, method, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the content length for the request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param length content length
|
||||||
|
*
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody contentLength(long length)
|
||||||
|
{
|
||||||
|
return header("Content-Length", String.valueOf(length));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the content type for the request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param contentType content type
|
||||||
|
*
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody contentType(String contentType)
|
||||||
|
{
|
||||||
|
return header("Content-Type", contentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the content of the file as request content.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param file file
|
||||||
|
*
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody fileContent(File file)
|
||||||
|
{
|
||||||
|
this.content = new FileContent(file);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link FormContentBuilder}. The builder can be used to add form
|
||||||
|
* parameters as content for the request. <strong>Note:</strong> you have to
|
||||||
|
* call {@link FormContentBuilder#build()} in order to apply the form content
|
||||||
|
* to the request.
|
||||||
|
*
|
||||||
|
* @return form content builder
|
||||||
|
*/
|
||||||
|
public FormContentBuilder formContent()
|
||||||
|
{
|
||||||
|
return new FormContentBuilder(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the raw data as request content.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param data raw data
|
||||||
|
*
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody rawContent(byte[] data)
|
||||||
|
{
|
||||||
|
this.content = new RawContent(data);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the raw data as request content.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param source byte source
|
||||||
|
*
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody rawContent(ByteSource source)
|
||||||
|
{
|
||||||
|
this.content = new ByteSourceContent(source);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the string as request content.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param content string content
|
||||||
|
*
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody stringContent(String content)
|
||||||
|
{
|
||||||
|
return stringContent(content, Charsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the string as request content.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param content string content
|
||||||
|
* @param charset charset of content
|
||||||
|
*
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody stringContent(String content,
|
||||||
|
Charset charset)
|
||||||
|
{
|
||||||
|
this.content = new StringContent(content, charset);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the content or the request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return request content
|
||||||
|
*/
|
||||||
|
public Content getContent()
|
||||||
|
{
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code this}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected AdvancedHttpRequestWithBody self()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** request content */
|
||||||
|
private Content content;
|
||||||
|
}
|
||||||
@@ -0,0 +1,199 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Http response. The response of a {@link AdvancedHttpRequest} or
|
||||||
|
* {@link AdvancedHttpRequestWithBody}.
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public abstract class AdvancedHttpResponse
|
||||||
|
{
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the content of the response as byte array.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return content as byte array
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public byte[] content() throws IOException
|
||||||
|
{
|
||||||
|
ByteSource content = contentAsByteSource();
|
||||||
|
byte[] data = null;
|
||||||
|
|
||||||
|
if (content != null)
|
||||||
|
{
|
||||||
|
data = content.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a reader for the content of the response.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return read of response content
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public BufferedReader contentAsReader() throws IOException
|
||||||
|
{
|
||||||
|
ByteSource content = contentAsByteSource();
|
||||||
|
BufferedReader reader = null;
|
||||||
|
if (content != null)
|
||||||
|
{
|
||||||
|
reader = content.asCharSource(Charsets.UTF_8).openBufferedStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns response content as stream.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return response content as stram
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public InputStream contentAsStream() throws IOException
|
||||||
|
{
|
||||||
|
ByteSource content = contentAsByteSource();
|
||||||
|
InputStream stream = null;
|
||||||
|
if (content != null)
|
||||||
|
{
|
||||||
|
stream = content.openBufferedStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the response content as byte source.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return response content as byte source
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract ByteSource contentAsByteSource() throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the response content as string.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return response content
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public String contentAsString() throws IOException
|
||||||
|
{
|
||||||
|
ByteSource content = contentAsByteSource();
|
||||||
|
String value = null;
|
||||||
|
if (content != null)
|
||||||
|
{
|
||||||
|
value = content.asCharSource(Charsets.UTF_8).read();
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the first header value for the given header name or {@code null}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param name header name
|
||||||
|
*
|
||||||
|
* @return header value or {@code null}
|
||||||
|
*/
|
||||||
|
public String getFirstHeader(String name)
|
||||||
|
{
|
||||||
|
return Iterables.getFirst(getHeaders().get(name), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the response headers.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return response headers
|
||||||
|
*/
|
||||||
|
public abstract Multimap<String, String> getHeaders();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if the response was successful. A response is
|
||||||
|
* successful, if the status code is greater than 199 and lower than 400.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the response was successful
|
||||||
|
*/
|
||||||
|
public boolean isSuccessful()
|
||||||
|
{
|
||||||
|
int status = getStatus();
|
||||||
|
return status > 199 && status < 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the status code of the response.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return status code
|
||||||
|
*/
|
||||||
|
public abstract int getStatus();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the status text of the response.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return status text
|
||||||
|
*/
|
||||||
|
public abstract String getStatusText();
|
||||||
|
}
|
||||||
408
scm-core/src/main/java/sonia/scm/net/ahc/BaseHttpRequest.java
Normal file
408
scm-core/src/main/java/sonia/scm/net/ahc/BaseHttpRequest.java
Normal file
@@ -0,0 +1,408 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
import org.apache.shiro.codec.Base64;
|
||||||
|
|
||||||
|
import sonia.scm.util.HttpUtil;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for http requests.
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @param <T> request implementation
|
||||||
|
*
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public abstract class BaseHttpRequest<T extends BaseHttpRequest>
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link BaseHttpRequest}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param client http client
|
||||||
|
* @param method http method
|
||||||
|
* @param url url
|
||||||
|
*/
|
||||||
|
public BaseHttpRequest(AdvancedHttpClient client, String method, String url)
|
||||||
|
{
|
||||||
|
this.client = client;
|
||||||
|
this.method = method;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the request and returns the http response.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return http response
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public AdvancedHttpResponse request() throws IOException
|
||||||
|
{
|
||||||
|
return client.request(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementing classes should return {@code this}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return request instance
|
||||||
|
*/
|
||||||
|
protected abstract T self();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enabled http basic authentication.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param username username for http basic authentication
|
||||||
|
* @param password password for http basic authentication
|
||||||
|
*
|
||||||
|
* @return http request instance
|
||||||
|
*/
|
||||||
|
public T basicAuth(String username, String password)
|
||||||
|
{
|
||||||
|
String auth = Strings.nullToEmpty(username).concat(":").concat(
|
||||||
|
Strings.nullToEmpty(password));
|
||||||
|
|
||||||
|
auth = Base64.encodeToString(auth.getBytes(Charsets.ISO_8859_1));
|
||||||
|
headers.put("Authorization", "Basic ".concat(auth));
|
||||||
|
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disabled gzip decoding. The default value is false.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param decodeGZip true to enable gzip decoding
|
||||||
|
*
|
||||||
|
* @return request instance
|
||||||
|
*/
|
||||||
|
public T decodeGZip(boolean decodeGZip)
|
||||||
|
{
|
||||||
|
this.decodeGZip = decodeGZip;
|
||||||
|
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable certificate validation of ssl certificates. The default
|
||||||
|
* value is false.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param disableCertificateValidation true to disable certificate validation
|
||||||
|
*
|
||||||
|
* @return request instance
|
||||||
|
*/
|
||||||
|
public T disableCertificateValidation(boolean disableCertificateValidation)
|
||||||
|
{
|
||||||
|
this.disableCertificateValidation = disableCertificateValidation;
|
||||||
|
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable the validation of ssl hostnames. The default value is
|
||||||
|
* false.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param disableHostnameValidation true to disable ssl hostname validation
|
||||||
|
*
|
||||||
|
* @return request instance
|
||||||
|
*/
|
||||||
|
public T disableHostnameValidation(boolean disableHostnameValidation)
|
||||||
|
{
|
||||||
|
this.disableHostnameValidation = disableHostnameValidation;
|
||||||
|
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add http headers to request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param name header name
|
||||||
|
* @param values header values
|
||||||
|
*
|
||||||
|
* @return request instance
|
||||||
|
*/
|
||||||
|
public T header(String name, Object... values)
|
||||||
|
{
|
||||||
|
for (Object v : values)
|
||||||
|
{
|
||||||
|
headers.put(name, toString(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add http headers to request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param name header name
|
||||||
|
* @param values header values
|
||||||
|
*
|
||||||
|
* @return request instance
|
||||||
|
*/
|
||||||
|
public T headers(String name, Iterable<? extends Object> values)
|
||||||
|
{
|
||||||
|
for (Object v : values)
|
||||||
|
{
|
||||||
|
headers.put(name, toString(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignore proxy settings. The default value is false.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param ignoreProxySettings true to ignore proxy settings.
|
||||||
|
*
|
||||||
|
* @return request instance
|
||||||
|
*/
|
||||||
|
public T ignoreProxySettings(boolean ignoreProxySettings)
|
||||||
|
{
|
||||||
|
this.ignoreProxySettings = ignoreProxySettings;
|
||||||
|
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a query parameter to the request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param name name of query parameter
|
||||||
|
* @param values query parameter values
|
||||||
|
*
|
||||||
|
* @return request instance
|
||||||
|
*/
|
||||||
|
public T queryString(String name, Object... values)
|
||||||
|
{
|
||||||
|
for (Object v : values)
|
||||||
|
{
|
||||||
|
appendQueryString(name, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a query parameter to the request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param name name of query parameter
|
||||||
|
* @param values query parameter values
|
||||||
|
*
|
||||||
|
* @return request instance
|
||||||
|
*/
|
||||||
|
public T queryStrings(String name, Iterable<? extends Object> values)
|
||||||
|
{
|
||||||
|
for (Object v : values)
|
||||||
|
{
|
||||||
|
appendQueryString(name, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a map with http headers used for the request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return map with http headers
|
||||||
|
*/
|
||||||
|
public Multimap<String, String> getHeaders()
|
||||||
|
{
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the http method for the request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return http method of request
|
||||||
|
*/
|
||||||
|
public String getMethod()
|
||||||
|
{
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the url for the request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return url of the request
|
||||||
|
*/
|
||||||
|
public String getUrl()
|
||||||
|
{
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the request decodes gzip compression.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return true if the request decodes gzip compression
|
||||||
|
*/
|
||||||
|
public boolean isDecodeGZip()
|
||||||
|
{
|
||||||
|
return decodeGZip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the verification of ssl certificates is disabled.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return true if certificate verification is disabled
|
||||||
|
*/
|
||||||
|
public boolean isDisableCertificateValidation()
|
||||||
|
{
|
||||||
|
return disableCertificateValidation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the ssl hostname validation is disabled.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return true if the ssl hostname validation is disabled
|
||||||
|
*/
|
||||||
|
public boolean isDisableHostnameValidation()
|
||||||
|
{
|
||||||
|
return disableHostnameValidation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the proxy settings are ignored.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return true if the proxy settings are ignored
|
||||||
|
*/
|
||||||
|
public boolean isIgnoreProxySettings()
|
||||||
|
{
|
||||||
|
return ignoreProxySettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value url encoded.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param value value to encode
|
||||||
|
*
|
||||||
|
* @return encoded value
|
||||||
|
*/
|
||||||
|
protected String encoded(Object value)
|
||||||
|
{
|
||||||
|
return HttpUtil.encode(Strings.nullToEmpty(toString(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns string representation of the given object or {@code null}, if the
|
||||||
|
* object is {@code null}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param object object
|
||||||
|
*
|
||||||
|
* @return string representation or {@code null}
|
||||||
|
*/
|
||||||
|
protected String toString(Object object)
|
||||||
|
{
|
||||||
|
return (object != null)
|
||||||
|
? object.toString()
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendQueryString(String name, Object value)
|
||||||
|
{
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
|
||||||
|
if (url.contains("?"))
|
||||||
|
{
|
||||||
|
buffer.append("&");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer.append("?");
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.append(encoded(name)).append("=").append(encoded(value));
|
||||||
|
url = url.concat(buffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** http client */
|
||||||
|
protected final AdvancedHttpClient client;
|
||||||
|
|
||||||
|
/** http header */
|
||||||
|
private final Multimap<String, String> headers = HashMultimap.create();
|
||||||
|
|
||||||
|
/** http method */
|
||||||
|
private final String method;
|
||||||
|
|
||||||
|
/** ignore proxy settings */
|
||||||
|
private boolean ignoreProxySettings = false;
|
||||||
|
|
||||||
|
/** disable ssl hostname validation */
|
||||||
|
private boolean disableHostnameValidation = false;
|
||||||
|
|
||||||
|
/** disable ssl certificate validation */
|
||||||
|
private boolean disableCertificateValidation = false;
|
||||||
|
|
||||||
|
/** decode gzip */
|
||||||
|
private boolean decodeGZip = false;
|
||||||
|
|
||||||
|
/** url of request */
|
||||||
|
private String url;
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ByteSource} content for {@link AdvancedHttpRequestWithBody}.
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public class ByteSourceContent implements Content
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link ByteSourceContent}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param byteSource byte source
|
||||||
|
*/
|
||||||
|
public ByteSourceContent(ByteSource byteSource)
|
||||||
|
{
|
||||||
|
this.byteSource = byteSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the content length for the request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param request http request
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void prepare(AdvancedHttpRequestWithBody request) throws IOException
|
||||||
|
{
|
||||||
|
request.contentLength(byteSource.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the content of the byte source to the output stream.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param output output stream
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void process(OutputStream output) throws IOException
|
||||||
|
{
|
||||||
|
byteSource.copyTo(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** byte source */
|
||||||
|
private final ByteSource byteSource;
|
||||||
|
}
|
||||||
69
scm-core/src/main/java/sonia/scm/net/ahc/Content.java
Normal file
69
scm-core/src/main/java/sonia/scm/net/ahc/Content.java
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Content of a {@link AdvancedHttpRequestWithBody}.
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public interface Content
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares the {@link AdvancedHttpRequestWithBody} for the request content.
|
||||||
|
* Implementations can set the content type, content length or custom headers
|
||||||
|
* for the request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param request request
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void prepare(AdvancedHttpRequestWithBody request) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the content to the output stream.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param output output stream
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void process(OutputStream output) throws IOException;
|
||||||
|
}
|
||||||
109
scm-core/src/main/java/sonia/scm/net/ahc/FileContent.java
Normal file
109
scm-core/src/main/java/sonia/scm/net/ahc/FileContent.java
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
import com.google.common.io.Closeables;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the content of the file to the request.
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public class FileContent implements Content
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link FileContent}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param file file
|
||||||
|
*/
|
||||||
|
public FileContent(File file)
|
||||||
|
{
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the content length of the file as request header.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param request request
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void prepare(AdvancedHttpRequestWithBody request)
|
||||||
|
{
|
||||||
|
request.contentLength(file.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the content of the file to the output stream.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param output output stream
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void process(OutputStream output) throws IOException
|
||||||
|
{
|
||||||
|
InputStream stream = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
stream = new FileInputStream(file);
|
||||||
|
ByteStreams.copy(stream, output);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Closeables.close(stream, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** file */
|
||||||
|
private final File file;
|
||||||
|
}
|
||||||
139
scm-core/src/main/java/sonia/scm/net/ahc/FormContentBuilder.java
Normal file
139
scm-core/src/main/java/sonia/scm/net/ahc/FormContentBuilder.java
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
|
import sonia.scm.util.HttpUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The form builder is able to add form parameters to a request.
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public class FormContentBuilder
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link FormContentBuilder}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param request request
|
||||||
|
*/
|
||||||
|
public FormContentBuilder(AdvancedHttpRequestWithBody request)
|
||||||
|
{
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the formular content and append it to the request.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return request instance
|
||||||
|
*/
|
||||||
|
public AdvancedHttpRequestWithBody build()
|
||||||
|
{
|
||||||
|
request.contentType("application/x-www-form-urlencoded");
|
||||||
|
request.stringContent(builder.toString());
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a formular parameter.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param name parameter name
|
||||||
|
* @param values parameter values
|
||||||
|
*
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
public FormContentBuilder fields(String name, Iterable<? extends Object> values)
|
||||||
|
{
|
||||||
|
for (Object v : values)
|
||||||
|
{
|
||||||
|
append(name, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a formular parameter.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param name parameter name
|
||||||
|
* @param values parameter values
|
||||||
|
*
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
public FormContentBuilder field(String name, Object... values)
|
||||||
|
{
|
||||||
|
for (Object v : values)
|
||||||
|
{
|
||||||
|
append(name, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void append(String name, Object value)
|
||||||
|
{
|
||||||
|
if (!Strings.isNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
if (builder.length() > 0)
|
||||||
|
{
|
||||||
|
builder.append("&");
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append(HttpUtil.encode(name)).append("=");
|
||||||
|
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
builder.append(HttpUtil.encode(value.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** content builder */
|
||||||
|
private final StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
/** request */
|
||||||
|
private final AdvancedHttpRequestWithBody request;
|
||||||
|
}
|
||||||
64
scm-core/src/main/java/sonia/scm/net/ahc/HttpMethod.java
Normal file
64
scm-core/src/main/java/sonia/scm/net/ahc/HttpMethod.java
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Http methods.
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public final class HttpMethod
|
||||||
|
{
|
||||||
|
|
||||||
|
/** http delete method */
|
||||||
|
public static final String DELETE = "DELETE";
|
||||||
|
|
||||||
|
/** http get method */
|
||||||
|
public static final String GET = "GET";
|
||||||
|
|
||||||
|
/** http head method */
|
||||||
|
public static final String HEAD = "HEAD";
|
||||||
|
|
||||||
|
/** http options method */
|
||||||
|
public static final String OPTIONS = "OPTIONS";
|
||||||
|
|
||||||
|
/** http post method */
|
||||||
|
public static final String POST = "POST";
|
||||||
|
|
||||||
|
/** http put method */
|
||||||
|
public static final String PUT = "PUT";
|
||||||
|
|
||||||
|
//~--- constructors ---------------------------------------------------------
|
||||||
|
|
||||||
|
private HttpMethod() {}
|
||||||
|
}
|
||||||
109
scm-core/src/main/java/sonia/scm/net/ahc/RawContent.java
Normal file
109
scm-core/src/main/java/sonia/scm/net/ahc/RawContent.java
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Byte array content for {@link AdvancedHttpRequestWithBody}.
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public class RawContent implements Content
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link RawContent}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param data data
|
||||||
|
*/
|
||||||
|
public RawContent(byte[] data)
|
||||||
|
{
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the length of the byte array as http header.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param request request
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void prepare(AdvancedHttpRequestWithBody request)
|
||||||
|
{
|
||||||
|
request.contentLength(data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the byte array to the output stream.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param output output stream
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void process(OutputStream output) throws IOException
|
||||||
|
{
|
||||||
|
output.write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns content data.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return content data
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
byte[] getData()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** byte array */
|
||||||
|
private final byte[] data;
|
||||||
|
}
|
||||||
58
scm-core/src/main/java/sonia/scm/net/ahc/StringContent.java
Normal file
58
scm-core/src/main/java/sonia/scm/net/ahc/StringContent.java
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String content for {@link AdvancedHttpRequestWithBody}.
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public class StringContent extends RawContent
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link StringContent}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param content content
|
||||||
|
* @param charset charset
|
||||||
|
*/
|
||||||
|
public StringContent(String content, Charset charset)
|
||||||
|
{
|
||||||
|
super(content.getBytes(charset));
|
||||||
|
}
|
||||||
|
}
|
||||||
36
scm-core/src/main/java/sonia/scm/net/ahc/package-info.java
Normal file
36
scm-core/src/main/java/sonia/scm/net/ahc/package-info.java
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advanced http client.
|
||||||
|
*/
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
public class AdvancedHttpClientTest {
|
||||||
|
|
||||||
|
private final AdvancedHttpClient client = new AdvancedHttpClient()
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AdvancedHttpResponse request(
|
||||||
|
BaseHttpRequest<?> request) throws IOException
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final String URL = "https://www.scm-manager.org";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGet()
|
||||||
|
{
|
||||||
|
AdvancedHttpRequest request = client.get(URL);
|
||||||
|
assertEquals(URL, request.getUrl());
|
||||||
|
assertEquals(HttpMethod.GET, request.getMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDelete()
|
||||||
|
{
|
||||||
|
AdvancedHttpRequestWithBody request = client.delete(URL);
|
||||||
|
assertEquals(URL, request.getUrl());
|
||||||
|
assertEquals(HttpMethod.DELETE, request.getMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPut()
|
||||||
|
{
|
||||||
|
AdvancedHttpRequestWithBody request = client.put(URL);
|
||||||
|
assertEquals(URL, request.getUrl());
|
||||||
|
assertEquals(HttpMethod.PUT, request.getMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPost()
|
||||||
|
{
|
||||||
|
AdvancedHttpRequestWithBody request = client.post(URL);
|
||||||
|
assertEquals(URL, request.getUrl());
|
||||||
|
assertEquals(HttpMethod.POST, request.getMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOptions()
|
||||||
|
{
|
||||||
|
AdvancedHttpRequestWithBody request = client.options(URL);
|
||||||
|
assertEquals(URL, request.getUrl());
|
||||||
|
assertEquals(HttpMethod.OPTIONS, request.getMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHead()
|
||||||
|
{
|
||||||
|
AdvancedHttpRequest request = client.head(URL);
|
||||||
|
assertEquals(URL, request.getUrl());
|
||||||
|
assertEquals(HttpMethod.HEAD, request.getMethod());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class AdvancedHttpRequestTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AdvancedHttpClient ahc;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSelf()
|
||||||
|
{
|
||||||
|
AdvancedHttpRequest ahr = new AdvancedHttpRequest(ahc, HttpMethod.GET, "https://www.scm-manager.org");
|
||||||
|
assertEquals(AdvancedHttpRequest.class, ahr.self().getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class AdvancedHttpRequestWithBodyTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AdvancedHttpClient ahc;
|
||||||
|
|
||||||
|
private AdvancedHttpRequestWithBody request;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public TemporaryFolder tempFolder = new TemporaryFolder();
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before(){
|
||||||
|
request = new AdvancedHttpRequestWithBody(ahc, HttpMethod.PUT, "https://www.scm-manager.org");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContentLength()
|
||||||
|
{
|
||||||
|
request.contentLength(12l);
|
||||||
|
assertEquals("12", request.getHeaders().get("Content-Length").iterator().next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContentType(){
|
||||||
|
request.contentType("text/plain");
|
||||||
|
assertEquals("text/plain", request.getHeaders().get("Content-Type").iterator().next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFileContent() throws IOException{
|
||||||
|
File file = tempFolder.newFile();
|
||||||
|
request.fileContent(file);
|
||||||
|
assertThat(request.getContent(), instanceOf(FileContent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRawContent() throws IOException {
|
||||||
|
request.rawContent("test".getBytes(Charsets.UTF_8));
|
||||||
|
assertThat(request.getContent(), instanceOf(RawContent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRawContentWithByteSource() throws IOException {
|
||||||
|
ByteSource bs = ByteSource.wrap("test".getBytes(Charsets.UTF_8));
|
||||||
|
request.rawContent(bs);
|
||||||
|
assertThat(request.getContent(), instanceOf(ByteSourceContent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFormContent(){
|
||||||
|
FormContentBuilder builder = request.formContent();
|
||||||
|
assertNotNull(builder);
|
||||||
|
builder.build();
|
||||||
|
assertThat(request.getContent(), instanceOf(StringContent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringContent(){
|
||||||
|
request.stringContent("test");
|
||||||
|
assertThat(request.getContent(), instanceOf(StringContent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringContentWithCharset(){
|
||||||
|
request.stringContent("test", Charsets.UTF_8);
|
||||||
|
assertThat(request.getContent(), instanceOf(StringContent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSelf()
|
||||||
|
{
|
||||||
|
assertEquals(AdvancedHttpRequestWithBody.class, request.self().getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
import com.google.common.io.CharStreams;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Answers;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class AdvancedHttpResponseTest {
|
||||||
|
|
||||||
|
@Mock(answer = Answers.CALLS_REAL_METHODS)
|
||||||
|
private AdvancedHttpResponse response;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContent() throws IOException
|
||||||
|
{
|
||||||
|
ByteSource bs = ByteSource.wrap("test123".getBytes(Charsets.UTF_8));
|
||||||
|
when(response.contentAsByteSource()).thenReturn(bs);
|
||||||
|
byte[] data = response.content();
|
||||||
|
assertEquals("test123", new String(data, Charsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContentAsString() throws IOException
|
||||||
|
{
|
||||||
|
ByteSource bs = ByteSource.wrap("123test".getBytes(Charsets.UTF_8));
|
||||||
|
when(response.contentAsByteSource()).thenReturn(bs);
|
||||||
|
assertEquals("123test", response.contentAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContentAsReader() throws IOException
|
||||||
|
{
|
||||||
|
ByteSource bs = ByteSource.wrap("abc123".getBytes(Charsets.UTF_8));
|
||||||
|
when(response.contentAsByteSource()).thenReturn(bs);
|
||||||
|
assertEquals("abc123", CharStreams.toString(response.contentAsReader()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContentAsStream() throws IOException
|
||||||
|
{
|
||||||
|
ByteSource bs = ByteSource.wrap("cde456".getBytes(Charsets.UTF_8));
|
||||||
|
when(response.contentAsByteSource()).thenReturn(bs);
|
||||||
|
byte[] data = ByteStreams.toByteArray(response.contentAsStream());
|
||||||
|
assertEquals("cde456", new String(data, Charsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class BaseHttpRequestTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AdvancedHttpClient ahc;
|
||||||
|
|
||||||
|
private BaseHttpRequest<AdvancedHttpRequest> request;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before(){
|
||||||
|
request = new AdvancedHttpRequest(ahc, HttpMethod.GET, "https://www.scm-manager.org");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBasicAuth()
|
||||||
|
{
|
||||||
|
request.basicAuth("tricia", "mcmillian123");
|
||||||
|
Multimap<String,String> headers = request.getHeaders();
|
||||||
|
assertEquals("Basic dHJpY2lhOm1jbWlsbGlhbjEyMw==", headers.get("Authorization").iterator().next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQueryString(){
|
||||||
|
request.queryString("a", "b");
|
||||||
|
assertEquals("https://www.scm-manager.org?a=b", request.getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQueryStringMultiple(){
|
||||||
|
request.queryString("a", "b");
|
||||||
|
request.queryString("c", "d", "e");
|
||||||
|
assertEquals("https://www.scm-manager.org?a=b&c=d&c=e", request.getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQueryStringEncoded(){
|
||||||
|
request.queryString("a", "äüö");
|
||||||
|
assertEquals("https://www.scm-manager.org?a=%C3%A4%C3%BC%C3%B6", request.getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQueryStrings(){
|
||||||
|
Iterable<? extends Object> i1 = Lists.newArrayList("b");
|
||||||
|
Iterable<? extends Object> i2 = Lists.newArrayList("d", "e");
|
||||||
|
request.queryStrings("a", i1);
|
||||||
|
request.queryStrings("c", i2);
|
||||||
|
assertEquals("https://www.scm-manager.org?a=b&c=d&c=e", request.getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQuerqStringNullValue(){
|
||||||
|
request.queryString("a", null, "b");
|
||||||
|
assertEquals("https://www.scm-manager.org?a=&a=b", request.getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHeader(){
|
||||||
|
request.header("a", "b");
|
||||||
|
assertEquals("b", request.getHeaders().get("a").iterator().next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHeaderMultiple(){
|
||||||
|
request.header("a", "b", "c", "d");
|
||||||
|
Collection<String> values = request.getHeaders().get("a");
|
||||||
|
assertThat(values, containsInAnyOrder("b", "c", "d"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRequest() throws IOException{
|
||||||
|
request.request();
|
||||||
|
verify(ahc).request(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuilderMethods(){
|
||||||
|
Iterable<? extends Object> i1 = Lists.newArrayList("b");
|
||||||
|
assertThat(request.decodeGZip(true), instanceOf(AdvancedHttpRequest.class));
|
||||||
|
assertTrue(request.isDecodeGZip());
|
||||||
|
assertThat(request.disableCertificateValidation(true), instanceOf(AdvancedHttpRequest.class));
|
||||||
|
assertTrue(request.isDisableCertificateValidation());
|
||||||
|
assertThat(request.disableHostnameValidation(true), instanceOf(AdvancedHttpRequest.class));
|
||||||
|
assertTrue(request.isDisableHostnameValidation());
|
||||||
|
assertThat(request.ignoreProxySettings(true), instanceOf(AdvancedHttpRequest.class));
|
||||||
|
assertTrue(request.isIgnoreProxySettings());
|
||||||
|
assertThat(request.header("a", "b"), instanceOf(AdvancedHttpRequest.class));
|
||||||
|
assertThat(request.headers("a", i1), instanceOf(AdvancedHttpRequest.class));
|
||||||
|
assertThat(request.queryString("a", "b"), instanceOf(AdvancedHttpRequest.class));
|
||||||
|
assertThat(request.queryStrings("a", i1), instanceOf(AdvancedHttpRequest.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ByteSourceContentTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AdvancedHttpRequestWithBody request;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPrepareRequest() throws IOException
|
||||||
|
{
|
||||||
|
ByteSource source = ByteSource.wrap("abc".getBytes(Charsets.UTF_8));
|
||||||
|
ByteSourceContent content = new ByteSourceContent(source);
|
||||||
|
content.prepare(request);
|
||||||
|
verify(request).contentLength(3l);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProcess() throws IOException{
|
||||||
|
ByteSource source = ByteSource.wrap("abc".getBytes(Charsets.UTF_8));
|
||||||
|
ByteSourceContent content = new ByteSourceContent(source);
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
content.process(baos);
|
||||||
|
assertEquals("abc", baos.toString("UTF-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
116
scm-core/src/test/java/sonia/scm/net/ahc/FileContentTest.java
Normal file
116
scm-core/src/test/java/sonia/scm/net/ahc/FileContentTest.java
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class FileContentTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testPrepareRequest() throws IOException
|
||||||
|
{
|
||||||
|
FileContent content = create("abc");
|
||||||
|
|
||||||
|
content.prepare(request);
|
||||||
|
verify(request).contentLength(3l);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testProcess() throws IOException
|
||||||
|
{
|
||||||
|
FileContent content = create("abc");
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
content.process(baos);
|
||||||
|
assertEquals("abc", baos.toString("UTF-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileContent create(String value) throws IOException
|
||||||
|
{
|
||||||
|
File file = temp.newFile();
|
||||||
|
|
||||||
|
Files.write("abc", file, Charsets.UTF_8);
|
||||||
|
|
||||||
|
return new FileContent(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
@Rule
|
||||||
|
public TemporaryFolder temp = new TemporaryFolder();
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
@Mock
|
||||||
|
private AdvancedHttpRequestWithBody request;
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class FormContentBuilderTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AdvancedHttpRequestWithBody request;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private FormContentBuilder builder;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldEncoding()
|
||||||
|
{
|
||||||
|
builder.field("a", "ü", "ä", "ö").build();
|
||||||
|
assertContent("a=%C3%BC&a=%C3%A4&a=%C3%B6");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuild()
|
||||||
|
{
|
||||||
|
builder.field("a", "b").build();
|
||||||
|
assertContent("a=b");
|
||||||
|
verify(request).contentType("application/x-www-form-urlencoded");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldWithArray()
|
||||||
|
{
|
||||||
|
builder.field("a", "b").field("c", "d", "e").build();
|
||||||
|
assertContent("a=b&c=d&c=e");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldWithIterable()
|
||||||
|
{
|
||||||
|
Iterable<? extends Object> i1 = Lists.newArrayList("b");
|
||||||
|
builder.fields("a", i1)
|
||||||
|
.fields("c", Lists.newArrayList("d", "e"))
|
||||||
|
.build();
|
||||||
|
assertContent("a=b&c=d&c=e");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertContent(String content){
|
||||||
|
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||||
|
verify(request).stringContent(captor.capture());
|
||||||
|
assertEquals(content, captor.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
72
scm-core/src/test/java/sonia/scm/net/ahc/RawContentTest.java
Normal file
72
scm-core/src/test/java/sonia/scm/net/ahc/RawContentTest.java
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class RawContentTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AdvancedHttpRequestWithBody request;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPrepareRequest()
|
||||||
|
{
|
||||||
|
RawContent raw = new RawContent("abc".getBytes(Charsets.UTF_8));
|
||||||
|
raw.prepare(request);
|
||||||
|
verify(request).contentLength(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProcess() throws IOException
|
||||||
|
{
|
||||||
|
RawContent raw = new RawContent("abc".getBytes(Charsets.UTF_8));
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
raw.process(baos);
|
||||||
|
assertEquals("abc", baos.toString("UTF-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
*/
|
||||||
|
public class StringContentTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringContent()
|
||||||
|
{
|
||||||
|
StringContent sc = new StringContent("abc", Charsets.UTF_8);
|
||||||
|
assertEquals("abc", new String(sc.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringContentWithCharset()
|
||||||
|
{
|
||||||
|
StringContent sc = new StringContent("üäö", Charsets.ISO_8859_1);
|
||||||
|
assertEquals("üäö", new String(sc.getData(), Charsets.ISO_8859_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,319 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.common.io.Closeables;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
import org.apache.shiro.codec.Base64;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
import sonia.scm.net.Proxies;
|
||||||
|
import sonia.scm.net.TrustAllHostnameVerifier;
|
||||||
|
import sonia.scm.net.TrustAllTrustManager;
|
||||||
|
import sonia.scm.util.HttpUtil;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.ProtocolException;
|
||||||
|
import java.net.Proxy;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import java.security.KeyManagementException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public class DefaultAdvancedHttpClient extends AdvancedHttpClient
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String CREDENTIAL_SEPARATOR = ":";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String HEADER_PROXY_AUTHORIZATION = "Proxy-Authorization";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String PREFIX_BASIC_AUTHENTICATION = "Basic ";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final int TIMEOUT_CONNECTION = 30000;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final int TIMEOUT_RAED = 1200000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the logger for DefaultAdvancedHttpClient
|
||||||
|
*/
|
||||||
|
private static final Logger logger =
|
||||||
|
LoggerFactory.getLogger(DefaultAdvancedHttpClient.class);
|
||||||
|
|
||||||
|
//~--- constructors ---------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs ...
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param configuration
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
public DefaultAdvancedHttpClient(ScmConfiguration configuration)
|
||||||
|
{
|
||||||
|
this.configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected AdvancedHttpResponse request(BaseHttpRequest<?> request)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
HttpURLConnection connection = openConnection(request,
|
||||||
|
new URL(request.getUrl()));
|
||||||
|
|
||||||
|
applyBaseSettings(request, connection);
|
||||||
|
|
||||||
|
if (connection instanceof HttpsURLConnection)
|
||||||
|
{
|
||||||
|
applySSLSettings(request, (HttpsURLConnection) connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
Content content = null;
|
||||||
|
|
||||||
|
if (request instanceof AdvancedHttpRequestWithBody)
|
||||||
|
{
|
||||||
|
AdvancedHttpRequestWithBody ahrwb = (AdvancedHttpRequestWithBody) request;
|
||||||
|
|
||||||
|
content = ahrwb.getContent();
|
||||||
|
|
||||||
|
if (content != null)
|
||||||
|
{
|
||||||
|
content.prepare(ahrwb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request.header(HttpUtil.HEADER_CONTENT_LENGTH, "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request.header(HttpUtil.HEADER_CONTENT_LENGTH, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
applyHeaders(request, connection);
|
||||||
|
|
||||||
|
if (content != null)
|
||||||
|
{
|
||||||
|
applyContent(connection, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DefaultAdvancedHttpResponse(connection,
|
||||||
|
connection.getResponseCode(), connection.getResponseMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendProxyAuthentication(HttpURLConnection connection)
|
||||||
|
{
|
||||||
|
String username = configuration.getProxyUser();
|
||||||
|
String password = configuration.getProxyPassword();
|
||||||
|
|
||||||
|
if (!Strings.isNullOrEmpty(username) ||!Strings.isNullOrEmpty(password))
|
||||||
|
{
|
||||||
|
logger.debug("append proxy authentication header for user {}", username);
|
||||||
|
|
||||||
|
String auth = username.concat(CREDENTIAL_SEPARATOR).concat(password);
|
||||||
|
|
||||||
|
auth = Base64.encodeToString(auth.getBytes());
|
||||||
|
connection.addRequestProperty(HEADER_PROXY_AUTHORIZATION,
|
||||||
|
PREFIX_BASIC_AUTHENTICATION.concat(auth));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyBaseSettings(BaseHttpRequest<?> request,
|
||||||
|
HttpURLConnection connection)
|
||||||
|
throws ProtocolException
|
||||||
|
{
|
||||||
|
connection.setRequestMethod(request.getMethod());
|
||||||
|
connection.setReadTimeout(TIMEOUT_RAED);
|
||||||
|
connection.setConnectTimeout(TIMEOUT_CONNECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyContent(HttpURLConnection connection, Content content)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
|
||||||
|
OutputStream output = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
output = connection.getOutputStream();
|
||||||
|
content.process(output);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Closeables.close(output, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyHeaders(BaseHttpRequest<?> request,
|
||||||
|
HttpURLConnection connection)
|
||||||
|
{
|
||||||
|
Multimap<String, String> headers = request.getHeaders();
|
||||||
|
|
||||||
|
for (String key : headers.keySet())
|
||||||
|
{
|
||||||
|
for (String value : headers.get(key))
|
||||||
|
{
|
||||||
|
connection.setRequestProperty(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applySSLSettings(BaseHttpRequest<?> request,
|
||||||
|
HttpsURLConnection connection)
|
||||||
|
{
|
||||||
|
if (request.isDisableCertificateValidation())
|
||||||
|
{
|
||||||
|
logger.trace("disable certificate validation");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TrustManager[] trustAllCerts = new TrustManager[] {
|
||||||
|
new TrustAllTrustManager() };
|
||||||
|
SSLContext sc = SSLContext.getInstance("SSL");
|
||||||
|
|
||||||
|
sc.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||||
|
connection.setSSLSocketFactory(sc.getSocketFactory());
|
||||||
|
}
|
||||||
|
catch (KeyManagementException ex)
|
||||||
|
{
|
||||||
|
logger.error("could not disable certificate validation", ex);
|
||||||
|
}
|
||||||
|
catch (NoSuchAlgorithmException ex)
|
||||||
|
{
|
||||||
|
logger.error("could not disable certificate validation", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.isDisableHostnameValidation())
|
||||||
|
{
|
||||||
|
logger.trace("disable hostname validation");
|
||||||
|
connection.setHostnameVerifier(new TrustAllHostnameVerifier());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpURLConnection openConnection(BaseHttpRequest<?> request, URL url)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
HttpURLConnection connection;
|
||||||
|
|
||||||
|
if (isProxyEnabled(request))
|
||||||
|
{
|
||||||
|
connection = openProxyConnection(request, url);
|
||||||
|
appendProxyAuthentication(connection);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (request.isIgnoreProxySettings())
|
||||||
|
{
|
||||||
|
logger.trace("ignore proxy settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("fetch {}", url.toExternalForm());
|
||||||
|
|
||||||
|
connection = (HttpURLConnection) url.openConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpURLConnection openProxyConnection(BaseHttpRequest<?> request,
|
||||||
|
URL url)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("fetch '{}' using proxy {}:{}", url.toExternalForm(),
|
||||||
|
configuration.getProxyServer(), configuration.getProxyPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
SocketAddress address =
|
||||||
|
new InetSocketAddress(configuration.getProxyServer(),
|
||||||
|
configuration.getProxyPort());
|
||||||
|
|
||||||
|
return (HttpURLConnection) url.openConnection(new Proxy(Proxy.Type.HTTP,
|
||||||
|
address));
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
private boolean isProxyEnabled(BaseHttpRequest<?> request)
|
||||||
|
{
|
||||||
|
return !request.isIgnoreProxySettings()
|
||||||
|
&& Proxies.isEnabled(configuration, request.getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private final ScmConfiguration configuration;
|
||||||
|
}
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||||
|
* nor the names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package sonia.scm.net.ahc;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Sdorra
|
||||||
|
* @since 1.46
|
||||||
|
*/
|
||||||
|
public class DefaultAdvancedHttpResponse extends AdvancedHttpResponse
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs ...
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param connection
|
||||||
|
* @param status
|
||||||
|
* @param statusText
|
||||||
|
*/
|
||||||
|
DefaultAdvancedHttpResponse(HttpURLConnection connection, int status,
|
||||||
|
String statusText)
|
||||||
|
{
|
||||||
|
this.connection = connection;
|
||||||
|
this.status = status;
|
||||||
|
this.statusText = statusText;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ByteSource contentAsByteSource() throws IOException
|
||||||
|
{
|
||||||
|
return new URLConnectionByteSource(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Multimap<String, String> getHeaders()
|
||||||
|
{
|
||||||
|
if (headers == null)
|
||||||
|
{
|
||||||
|
headers = HashMultimap.create();
|
||||||
|
|
||||||
|
for (Entry<String, List<String>> e :
|
||||||
|
connection.getHeaderFields().entrySet())
|
||||||
|
{
|
||||||
|
headers.putAll(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getStatus()
|
||||||
|
{
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getStatusText()
|
||||||
|
{
|
||||||
|
return statusText;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- inner classes --------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ByteSource} implementation of a http connection.
|
||||||
|
*/
|
||||||
|
private static class URLConnectionByteSource extends ByteSource
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link URLConnectionByteSource}.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param connection http connection
|
||||||
|
*/
|
||||||
|
private URLConnectionByteSource(HttpURLConnection connection)
|
||||||
|
{
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- methods ------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the http connection.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return http connection
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public InputStream openStream() throws IOException
|
||||||
|
{
|
||||||
|
return connection.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~--- fields -------------------------------------------------------------
|
||||||
|
|
||||||
|
/** http connection */
|
||||||
|
private final HttpURLConnection connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** http connection */
|
||||||
|
private final HttpURLConnection connection;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private final int status;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private final String statusText;
|
||||||
|
|
||||||
|
/** http headers */
|
||||||
|
private Multimap<String, String> headers;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user