1
0
mirror of https://github.com/square/okhttp.git synced 2026-01-25 16:01:38 +03:00

Add factory methods to create request bodies

This commit is contained in:
jwilson
2013-07-05 14:06:58 -07:00
parent eb3a162c77
commit 1bd4dd1a55
4 changed files with 198 additions and 3 deletions

View File

@@ -92,6 +92,13 @@ class Dispatcher {
Request.Body body = request.body();
if (body != null) {
connection.setDoOutput(true);
long contentLength = body.contentLength();
if (contentLength == -1 || contentLength > Integer.MAX_VALUE) {
connection.setChunkedStreamingMode(0);
} else {
// Don't call setFixedLengthStreamingMode(long); that's only available on Java 1.7+.
connection.setFixedLengthStreamingMode((int) contentLength);
}
body.writeTo(connection.getOutputStream());
}
return connection;

View File

@@ -15,9 +15,14 @@
*/
package com.squareup.okhttp;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.http.RawHeaders;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
@@ -89,9 +94,12 @@ public final class Request {
return tag;
}
public abstract class Body {
/** Returns the Content-Type header for this body, or null if the content type is unknown. */
public String contentType() {
public abstract static class Body {
/**
* Returns the Content-Type header for this body, or null if the content
* type is unknown.
*/
public MediaType contentType() {
return null;
}
@@ -100,7 +108,76 @@ public final class Request {
return -1;
}
/** Writes the content of this request to {@code out}. */
public abstract void writeTo(OutputStream out) throws IOException;
/**
* Returns a new request body that transmits {@code content}. If {@code
* contentType} lacks a charset, this will use UTF-8.
*/
public static Body create(MediaType contentType, String content) {
contentType = contentType.charset() != null
? contentType
: MediaType.parse(contentType + "; charset=utf-8");
try {
byte[] bytes = content.getBytes(contentType.charset().name());
return create(contentType, bytes);
} catch (UnsupportedEncodingException e) {
throw new AssertionError();
}
}
/** Returns a new request body that transmits {@code content}. */
public static Body create(final MediaType contentType, final byte[] content) {
if (contentType == null) throw new NullPointerException("contentType == null");
if (content == null) throw new NullPointerException("content == null");
return new Body() {
@Override public MediaType contentType() {
return contentType;
}
@Override public long contentLength() {
return content.length;
}
@Override public void writeTo(OutputStream out) throws IOException {
out.write(content);
}
};
}
/** Returns a new request body that transmits the content of {@code file}. */
public static Body create(final MediaType contentType, final File file) {
if (contentType == null) throw new NullPointerException("contentType == null");
if (file == null) throw new NullPointerException("content == null");
return new Body() {
@Override public MediaType contentType() {
return contentType;
}
@Override public long contentLength() {
return file.length();
}
@Override public void writeTo(OutputStream out) throws IOException {
long length = contentLength();
if (length == 0) return;
InputStream in = null;
try {
in = new FileInputStream(file);
byte[] buffer = new byte[(int) Math.min(8192, length)];
for (int c; (c = in.read(buffer)) != -1; ) {
out.write(buffer, 0, c);
}
} finally {
Util.closeQuietly(in);
}
}
};
}
}
public static class Builder {

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2013 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.okhttp;
import com.squareup.okhttp.internal.Util;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public final class RequestTest {
@Test public void string() throws Exception {
MediaType contentType = MediaType.parse("text/plain; charset=utf-8");
Request.Body body = Request.Body.create(contentType, "abc".getBytes(Util.UTF_8));
assertEquals(contentType, body.contentType());
assertEquals(3, body.contentLength());
assertEquals("616263", bodyToHex(body));
assertEquals("Retransmit body", "616263", bodyToHex(body));
}
@Test public void stringWithDefaultCharsetAdded() throws Exception {
MediaType contentType = MediaType.parse("text/plain");
Request.Body body = Request.Body.create(contentType, "\u0800");
assertEquals(MediaType.parse("text/plain; charset=utf-8"), body.contentType());
assertEquals(3, body.contentLength());
assertEquals("e0a080", bodyToHex(body));
}
@Test public void stringWithNonDefaultCharsetSpecified() throws Exception {
MediaType contentType = MediaType.parse("text/plain; charset=utf-16be");
Request.Body body = Request.Body.create(contentType, "\u0800");
assertEquals(contentType, body.contentType());
assertEquals(2, body.contentLength());
assertEquals("0800", bodyToHex(body));
}
@Test public void byteArray() throws Exception {
MediaType contentType = MediaType.parse("text/plain");
Request.Body body = Request.Body.create(contentType, "abc".getBytes(Util.UTF_8));
assertEquals(contentType, body.contentType());
assertEquals(3, body.contentLength());
assertEquals("616263", bodyToHex(body));
assertEquals("Retransmit body", "616263", bodyToHex(body));
}
@Test public void file() throws Exception {
File file = File.createTempFile("RequestTest", "tmp");
FileWriter writer = new FileWriter(file);
writer.write("abc");
writer.close();
MediaType contentType = MediaType.parse("text/plain");
Request.Body body = Request.Body.create(contentType, file);
assertEquals(contentType, body.contentType());
assertEquals(3, body.contentLength());
assertEquals("616263", bodyToHex(body));
assertEquals("Retransmit body", "616263", bodyToHex(body));
}
private String bodyToHex(Request.Body body) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
body.writeTo(bytes);
return bytesToHex(bytes.toByteArray());
}
private String bytesToHex(byte[] bytes) {
StringBuilder hex = new StringBuilder();
for (byte b : bytes) {
if ((b & 0xff) < 0x10) hex.append('0');
hex.append(Integer.toHexString(b & 0xff));
}
return hex.toString();
}
}

View File

@@ -17,11 +17,14 @@ package com.squareup.okhttp.internal;
import com.google.mockwebserver.MockResponse;
import com.google.mockwebserver.MockWebServer;
import com.google.mockwebserver.RecordedRequest;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import org.junit.After;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public final class AsyncApiTest {
@@ -51,4 +54,22 @@ public final class AsyncApiTest {
assertTrue(server.takeRequest().getHeaders().contains("User-Agent: AsyncApiTest"));
}
@Test public void post() throws Exception {
server.enqueue(new MockResponse().setBody("abc"));
server.play();
Request request = new Request.Builder(server.getUrl("/"))
.post(Request.Body.create(MediaType.parse("text/plain"), "def"))
.build();
client.enqueue(request, receiver);
receiver.await(request)
.assertCode(200)
.assertBody("abc");
RecordedRequest recordedRequest = server.takeRequest();
assertEquals("def", recordedRequest.getUtf8Body());
assertEquals("3", recordedRequest.getHeader("Content-Length"));
}
}