mirror of https://github.com/apache/jclouds.git
added new annotation @PartParam for multipart form support
This commit is contained in:
parent
fae1a1930e
commit
ab5e8b3ab4
|
@ -18,12 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.blobstore.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
|
@ -32,9 +26,6 @@ import org.jclouds.http.MultipartForm;
|
|||
import org.jclouds.http.MultipartForm.Part;
|
||||
import org.jclouds.rest.Binder;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
|
@ -45,36 +36,14 @@ public class BindBlobToMultipartForm implements Binder {
|
|||
|
||||
public void bindToRequest(HttpRequest request, Object payload) {
|
||||
Blob object = (Blob) payload;
|
||||
File file = new File(object.getMetadata().getName());
|
||||
Multimap<String, String> partHeaders = ImmutableMultimap.of("Content-Disposition", String
|
||||
.format("form-data; name=\"%s\"; filename=\"%s\"", file.getName(), file.getName()),
|
||||
HttpHeaders.CONTENT_TYPE, checkNotNull(object.getMetadata().getContentType(),
|
||||
"object.metadata.contentType()"));
|
||||
Object data = checkNotNull(object.getPayload(), "object.getPayload()").getRawContent();
|
||||
|
||||
Part part;
|
||||
try {
|
||||
if (data instanceof byte[]) {
|
||||
part = new Part(partHeaders, (byte[]) data);
|
||||
} else if (data instanceof String) {
|
||||
part = new Part(partHeaders, (String) data);
|
||||
} else if (data instanceof File) {
|
||||
part = new Part(partHeaders, (File) data);
|
||||
} else if (data instanceof InputStream) {
|
||||
part = new Part(partHeaders, (InputStream) data, object.getContentLength());
|
||||
} else {
|
||||
throw new IllegalArgumentException("type of part not supported: "
|
||||
+ data.getClass().getCanonicalName() + "; " + object);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new IllegalArgumentException("file for part not found: " + object);
|
||||
}
|
||||
|
||||
Part part = Part.create(object.getMetadata().getName(), object.getPayload(), object
|
||||
.getMetadata().getContentType());
|
||||
|
||||
MultipartForm form = new MultipartForm(BOUNDARY, part);
|
||||
|
||||
request.setPayload(form.getData());
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_TYPE,
|
||||
"multipart/form-data; boundary=" + BOUNDARY);
|
||||
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, form.getSize() + "");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public class BindBlobToMultipartFormTest {
|
|||
|
||||
public void testSinglePart() throws IOException {
|
||||
|
||||
assertEquals(EXPECTS.length(), 131);
|
||||
assertEquals(EXPECTS.length(), 113);
|
||||
|
||||
BindBlobToMultipartForm binder = new BindBlobToMultipartForm();
|
||||
|
||||
|
@ -71,7 +71,7 @@ public class BindBlobToMultipartFormTest {
|
|||
|
||||
assertEquals(Utils.toStringAndClose((InputStream) request.getPayload().getRawContent()),
|
||||
EXPECTS);
|
||||
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH), 131 + "");
|
||||
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_LENGTH), 113 + "");
|
||||
|
||||
assertEquals(request.getFirstHeaderOrNull(HttpHeaders.CONTENT_TYPE),
|
||||
"multipart/form-data; boundary=" + BOUNDRY);
|
||||
|
@ -80,7 +80,7 @@ public class BindBlobToMultipartFormTest {
|
|||
private static void addData(String boundary, String data, StringBuilder builder) {
|
||||
builder.append(boundary).append("\r\n");
|
||||
builder.append("Content-Disposition").append(": ").append(
|
||||
"form-data; name=\"hello\"; filename=\"hello\"").append("\r\n");
|
||||
"form-data; name=\"hello\"").append("\r\n");
|
||||
builder.append("Content-Type").append(": ").append("text/plain").append("\r\n");
|
||||
builder.append("\r\n");
|
||||
builder.append(data).append("\r\n");
|
||||
|
|
|
@ -18,18 +18,24 @@
|
|||
*/
|
||||
package org.jclouds.http;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.jclouds.util.InputStreamChain;
|
||||
import org.jclouds.util.Utils;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.http.payloads.FilePayload;
|
||||
import org.jclouds.util.InputStreamChain;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -57,9 +63,9 @@ public class MultipartForm {
|
|||
}
|
||||
|
||||
private void addData(Part part) {
|
||||
chain.addInputStream(part.getData());
|
||||
chain.addInputStream(part.getContent());
|
||||
chain.addAsInputStream(rn);
|
||||
size += part.getSize() + rn.length();
|
||||
size += part.calculateSize() + rn.length();
|
||||
}
|
||||
|
||||
private void addHeaders(String boundaryrn, Part part) {
|
||||
|
@ -83,39 +89,112 @@ public class MultipartForm {
|
|||
this("__redrose__", parts);
|
||||
}
|
||||
|
||||
public static class Part {
|
||||
public static class Part implements Payload {
|
||||
private final Multimap<String, String> headers;
|
||||
private final InputStream data;
|
||||
private final long size;
|
||||
private final Payload delegate;
|
||||
|
||||
public Part(Multimap<String, String> headers, InputStream data, long size) {
|
||||
this.headers = headers;
|
||||
this.data = data;
|
||||
this.size = size;
|
||||
private static class PartMap extends LinkedHashMap<String, String> {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -287387556008320212L;
|
||||
|
||||
static PartMap create(String name) {
|
||||
PartMap map = new PartMap();
|
||||
map.put("Content-Disposition", String.format("form-data; name=\"%s\"", checkNotNull(
|
||||
name, "name")));
|
||||
return map;
|
||||
}
|
||||
|
||||
static PartMap create(String name, String filename) {
|
||||
PartMap map = new PartMap();
|
||||
map.put("Content-Disposition", String.format("form-data; name=\"%s\"; filename=\"%s\"",
|
||||
checkNotNull(name, "name"), checkNotNull(filename, "filename")));
|
||||
return map;
|
||||
}
|
||||
|
||||
PartMap contentType(@Nullable String type) {
|
||||
if (type != null)
|
||||
put(HttpHeaders.CONTENT_TYPE, checkNotNull(type, "type"));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Part(Multimap<String, String> headers, String data) {
|
||||
this(headers, Utils.toInputStream(data), data.length());
|
||||
private Part(PartMap map, Payload delegate) {
|
||||
this.delegate = checkNotNull(delegate, "delegate");
|
||||
this.headers = ImmutableMultimap.copyOf(Multimaps.forMap((checkNotNull(map, "headers"))));
|
||||
}
|
||||
|
||||
public Part(Multimap<String, String> headers, File data) throws FileNotFoundException {
|
||||
this(headers, new FileInputStream(data), data.length());
|
||||
public static Part create(String name, String value) {
|
||||
return new Part(PartMap.create(name), Payloads.newStringPayload(value));
|
||||
}
|
||||
|
||||
public Part(Multimap<String, String> headers, byte[] data) {
|
||||
this(headers, new ByteArrayInputStream(data), data.length);
|
||||
public static Part create(String name, Payload delegate, String contentType) {
|
||||
return new Part(PartMap.create(name).contentType(contentType), delegate);
|
||||
}
|
||||
|
||||
public static Part create(String name, FilePayload delegate, String contentType) {
|
||||
return new Part(PartMap.create(name, delegate.getRawContent().getName()).contentType(
|
||||
contentType), delegate);
|
||||
}
|
||||
|
||||
public Multimap<String, String> getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
public InputStream getData() {
|
||||
return data;
|
||||
@Override
|
||||
public Long calculateSize() {
|
||||
return delegate.calculateSize();
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return size;
|
||||
@Override
|
||||
public InputStream getContent() {
|
||||
return delegate.getContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRawContent() {
|
||||
return delegate.getContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRepeatable() {
|
||||
return delegate.isRepeatable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(OutputStream outstream) throws IOException {
|
||||
delegate.writeTo(outstream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((delegate == null) ? 0 : delegate.hashCode());
|
||||
result = prime * result + ((headers == null) ? 0 : headers.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Part other = (Part) obj;
|
||||
if (delegate == null) {
|
||||
if (other.delegate != null)
|
||||
return false;
|
||||
} else if (!delegate.equals(other.delegate))
|
||||
return false;
|
||||
if (headers == null) {
|
||||
if (other.headers != null)
|
||||
return false;
|
||||
} else if (!headers.equals(other.headers))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.jclouds.http.MultipartForm.Part;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
* Designates that this parameter will be bound to a multipart form.
|
||||
|
@ -36,17 +34,7 @@ import com.google.common.base.Function;
|
|||
@Target(PARAMETER)
|
||||
@Retention(RUNTIME)
|
||||
public @interface PartParam {
|
||||
String name();
|
||||
|
||||
public static class ALREADY_PART implements Function<Object, Part> {
|
||||
|
||||
@Override
|
||||
public Part apply(Object from) {
|
||||
return Part.class.cast(from);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* how to convert this to a part.
|
||||
*/
|
||||
Class<? extends Function<Object, Part>> value() default ALREADY_PART.class;
|
||||
String contentType() default MediaType.TEXT_PLAIN;
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ import org.jclouds.http.HttpRequestFilter;
|
|||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.MultipartForm;
|
||||
import org.jclouds.http.Payloads;
|
||||
import org.jclouds.http.MultipartForm.Part;
|
||||
import org.jclouds.http.functions.CloseContentAndReturn;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
|
@ -102,7 +103,6 @@ import com.google.common.annotations.VisibleForTesting;
|
|||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.LinkedListMultimap;
|
||||
|
@ -195,8 +195,7 @@ public class RestAnnotationProcessor<T> {
|
|||
|
||||
@Override
|
||||
public Part apply(Entry<String, String> from) {
|
||||
return new Part(ImmutableMultimap.of("Content-Disposition", String.format(
|
||||
"form-data; name=\"%s\"", from.getKey())), from.getValue());
|
||||
return Part.create(from.getKey(), from.getValue());
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -1012,8 +1011,9 @@ public class RestAnnotationProcessor<T> {
|
|||
.get(method);
|
||||
for (Entry<Integer, Set<Annotation>> entry : indexToPartParam.entrySet()) {
|
||||
for (Annotation key : entry.getValue()) {
|
||||
PartParam extractor = (PartParam) key;
|
||||
Part part = injector.getInstance(extractor.value()).apply(args[entry.getKey()]);
|
||||
PartParam param = (PartParam) key;
|
||||
Part part = Part.create(param.name(), Payloads.newPayload(args[entry.getKey()]), param
|
||||
.contentType());
|
||||
parts.add(part);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,19 +18,24 @@
|
|||
*/
|
||||
package org.jclouds.http;
|
||||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.http.MultipartForm.Part;
|
||||
import org.jclouds.http.payloads.FilePayload;
|
||||
import org.jclouds.http.payloads.StringPayload;
|
||||
import org.jclouds.util.Utils;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
|
||||
/**
|
||||
* Tests parsing of a request
|
||||
*
|
||||
|
@ -54,10 +59,47 @@ public class MultipartFormTest {
|
|||
assertEquals(multipartForm.getSize(), 199);
|
||||
}
|
||||
|
||||
public static class MockFilePayload extends FilePayload {
|
||||
|
||||
private final StringPayload realPayload;
|
||||
|
||||
public MockFilePayload(String content) {
|
||||
super(createMockFile(content));
|
||||
this.realPayload = Payloads.newStringPayload(content);
|
||||
}
|
||||
|
||||
private static File createMockFile(String content) {
|
||||
File file = createMock(File.class);
|
||||
expect(file.exists()).andReturn(true);
|
||||
expect(file.getName()).andReturn("testfile.txt");
|
||||
replay(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long calculateSize() {
|
||||
return realPayload.calculateSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getContent() {
|
||||
return realPayload.getContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRepeatable() {
|
||||
return realPayload.isRepeatable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(OutputStream outstream) throws IOException {
|
||||
realPayload.writeTo(outstream);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Part newPart(String data) {
|
||||
return new MultipartForm.Part(ImmutableMultimap.of("Content-Disposition",
|
||||
"form-data; name=\"file\"; filename=\"testfile.txt\"", HttpHeaders.CONTENT_TYPE,
|
||||
MediaType.TEXT_PLAIN), data);
|
||||
return Part.create("file", new MockFilePayload(data), MediaType.TEXT_PLAIN);
|
||||
}
|
||||
|
||||
private void addData(String boundary, String data, StringBuilder builder) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor
|
|||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
@ -98,6 +99,7 @@ import org.jclouds.rest.annotations.MapPayloadParam;
|
|||
import org.jclouds.rest.annotations.MatrixParams;
|
||||
import org.jclouds.rest.annotations.OverrideRequestFilters;
|
||||
import org.jclouds.rest.annotations.ParamParser;
|
||||
import org.jclouds.rest.annotations.PartParam;
|
||||
import org.jclouds.rest.annotations.QueryParams;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
|
@ -114,6 +116,7 @@ import org.testng.annotations.BeforeClass;
|
|||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
@ -123,6 +126,7 @@ import com.google.common.collect.Iterables;
|
|||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.LinkedListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.ConfigurationException;
|
||||
|
@ -612,6 +616,115 @@ public class RestAnnotationProcessorTest {
|
|||
assertEquals(httpMethod.getPayload().toString(), expected);
|
||||
}
|
||||
|
||||
@Endpoint(Localhost.class)
|
||||
static interface TestMultipartForm {
|
||||
@POST
|
||||
public void withStringPart(@PartParam(name = "fooble") String path);
|
||||
|
||||
@POST
|
||||
public void withParamStringPart(@FormParam("name") String name,
|
||||
@PartParam(name = "file") String path);
|
||||
|
||||
@POST
|
||||
public void withParamFilePart(@FormParam("name") String name,
|
||||
@PartParam(name = "file") File path);
|
||||
|
||||
@POST
|
||||
public void withParamFileBinaryPart(@FormParam("name") String name,
|
||||
@PartParam(name = "file", contentType = MediaType.APPLICATION_OCTET_STREAM) File path);
|
||||
}
|
||||
|
||||
public void testMultipartWithStringPart() throws SecurityException, NoSuchMethodException,
|
||||
IOException {
|
||||
Method method = TestMultipartForm.class.getMethod("withStringPart", String.class);
|
||||
GeneratedHttpRequest<TestMultipartForm> httpRequest = factory(TestMultipartForm.class)
|
||||
.createRequest(method, "foobledata");
|
||||
assertRequestLineEquals(httpRequest, "POST http://localhost:9999 HTTP/1.1");
|
||||
assertHeadersEqual(httpRequest,
|
||||
"Content-Length: 119\nContent-Type: multipart/form-data; boundary=--JCLOUDS--\n");
|
||||
assertPayloadEquals(httpRequest,//
|
||||
"----JCLOUDS--\r\n" + //
|
||||
"Content-Disposition: form-data; name=\"fooble\"\r\n" + //
|
||||
"Content-Type: text/plain\r\n" + //
|
||||
"\r\n" + //
|
||||
"foobledata\r\n" + //
|
||||
"----JCLOUDS----\r\n");
|
||||
}
|
||||
|
||||
public void testMultipartWithParamStringPart() throws SecurityException, NoSuchMethodException,
|
||||
IOException {
|
||||
Method method = TestMultipartForm.class.getMethod("withParamStringPart", String.class,
|
||||
String.class);
|
||||
GeneratedHttpRequest<TestMultipartForm> httpRequest = factory(TestMultipartForm.class)
|
||||
.createRequest(method, "name", "foobledata");
|
||||
assertRequestLineEquals(httpRequest, "POST http://localhost:9999 HTTP/1.1");
|
||||
assertHeadersEqual(httpRequest,
|
||||
"Content-Length: 185\nContent-Type: multipart/form-data; boundary=--JCLOUDS--\n");
|
||||
assertPayloadEquals(httpRequest,//
|
||||
"----JCLOUDS--\r\n" + //
|
||||
"Content-Disposition: form-data; name=\"name\"\r\n" + //
|
||||
"\r\n" + //
|
||||
"name\r\n" + // /
|
||||
"----JCLOUDS--\r\n" + //
|
||||
"Content-Disposition: form-data; name=\"file\"\r\n" + //
|
||||
"Content-Type: text/plain\r\n" + //
|
||||
"\r\n" + //
|
||||
"foobledata\r\n" + //
|
||||
"----JCLOUDS----\r\n");
|
||||
}
|
||||
|
||||
public void testMultipartWithParamFilePart() throws SecurityException, NoSuchMethodException,
|
||||
IOException {
|
||||
Method method = TestMultipartForm.class.getMethod("withParamFilePart", String.class,
|
||||
File.class);
|
||||
File file = File.createTempFile("foo", "bar");
|
||||
Files.append("foobledata", file, Charsets.UTF_8);
|
||||
file.deleteOnExit();
|
||||
|
||||
GeneratedHttpRequest<TestMultipartForm> httpRequest = factory(TestMultipartForm.class)
|
||||
.createRequest(method, "name", file);
|
||||
assertRequestLineEquals(httpRequest, "POST http://localhost:9999 HTTP/1.1");
|
||||
assertHeadersEqual(httpRequest,
|
||||
"Content-Length: 185\nContent-Type: multipart/form-data; boundary=--JCLOUDS--\n");
|
||||
assertPayloadEquals(httpRequest,//
|
||||
"----JCLOUDS--\r\n" + //
|
||||
"Content-Disposition: form-data; name=\"name\"\r\n" + //
|
||||
"\r\n" + //
|
||||
"name\r\n" + // /
|
||||
"----JCLOUDS--\r\n" + //
|
||||
"Content-Disposition: form-data; name=\"file\"\r\n" + //
|
||||
"Content-Type: text/plain\r\n" + //
|
||||
"\r\n" + //
|
||||
"foobledata\r\n" + //
|
||||
"----JCLOUDS----\r\n");
|
||||
}
|
||||
|
||||
public void testMultipartWithParamFileBinaryPart() throws SecurityException,
|
||||
NoSuchMethodException, IOException {
|
||||
Method method = TestMultipartForm.class.getMethod("withParamFileBinaryPart", String.class,
|
||||
File.class);
|
||||
File file = File.createTempFile("foo", "bar");
|
||||
Files.write(new byte[] { 17, 26, 39, 40, 50 }, file);
|
||||
file.deleteOnExit();
|
||||
|
||||
GeneratedHttpRequest<TestMultipartForm> httpRequest = factory(TestMultipartForm.class)
|
||||
.createRequest(method, "name", file);
|
||||
assertRequestLineEquals(httpRequest, "POST http://localhost:9999 HTTP/1.1");
|
||||
assertHeadersEqual(httpRequest,
|
||||
"Content-Length: 194\nContent-Type: multipart/form-data; boundary=--JCLOUDS--\n");
|
||||
assertPayloadEquals(httpRequest,//
|
||||
"----JCLOUDS--\r\n" + //
|
||||
"Content-Disposition: form-data; name=\"name\"\r\n" + //
|
||||
"\r\n" + //
|
||||
"name\r\n" + // /
|
||||
"----JCLOUDS--\r\n" + //
|
||||
"Content-Disposition: form-data; name=\"file\"\r\n" + //
|
||||
"Content-Type: application/octet-stream\r\n" + //
|
||||
"\r\n" + //
|
||||
"'(2\r\n" + //
|
||||
"----JCLOUDS----\r\n");
|
||||
}
|
||||
|
||||
@Endpoint(Localhost.class)
|
||||
public class TestPut {
|
||||
@PUT
|
||||
|
|
|
@ -164,7 +164,7 @@ public class PCSAsyncClientTest extends RestClientTest<PCSAsyncClient> {
|
|||
|
||||
assertRequestLineEquals(httpMethod, "POST http://localhost/mycontainer/contents HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod,
|
||||
"Content-Length: 131\nContent-Type: multipart/form-data; boundary=--JCLOUDS--\n");
|
||||
"Content-Length: 113\nContent-Type: multipart/form-data; boundary=--JCLOUDS--\n");
|
||||
assertPayloadEquals(httpMethod, BindBlobToMultipartFormTest.EXPECTS);
|
||||
|
||||
assertResponseParserClassEquals(method, httpMethod,
|
||||
|
|
|
@ -92,14 +92,14 @@
|
|||
<category name="jclouds.headers">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
</category><!--
|
||||
</category>
|
||||
|
||||
<category name="jclouds.wire">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
</category>
|
||||
|
||||
--><!-- ======================= -->
|
||||
<!-- ======================= -->
|
||||
<!-- Setup the Root category -->
|
||||
<!-- ======================= -->
|
||||
|
||||
|
|
|
@ -84,10 +84,10 @@ public class SDNAsyncClientTest extends RestClientTest<SDNAsyncClient> {
|
|||
httpMethod,
|
||||
"POST http://uploader/Upload.ashx?output=json&destFolderPath=adriansmovies&uploadToken=token HTTP/1.1");
|
||||
assertHeadersEqual(httpMethod,
|
||||
"Content-Length: 131\nContent-Type: multipart/form-data; boundary=--JCLOUDS--\n");
|
||||
"Content-Length: 113\nContent-Type: multipart/form-data; boundary=--JCLOUDS--\n");
|
||||
StringBuffer expects = new StringBuffer();
|
||||
expects.append("----JCLOUDS--\r\n");
|
||||
expects.append("Content-Disposition: form-data; name=\"hello\"; filename=\"hello\"\r\n");
|
||||
expects.append("Content-Disposition: form-data; name=\"hello\"\r\n");
|
||||
expects.append("Content-Type: text/plain\r\n\r\n");
|
||||
expects.append("hello\r\n");
|
||||
expects.append("----JCLOUDS----\r\n");
|
||||
|
|
Loading…
Reference in New Issue