1 /* 2 * Copyright (C) 2014 Square, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.squareup.okhttp; 17 18 import com.squareup.okhttp.internal.Util; 19 import java.io.File; 20 import java.io.IOException; 21 import java.nio.charset.Charset; 22 import okio.BufferedSink; 23 import okio.ByteString; 24 import okio.Okio; 25 import okio.Source; 26 27 public abstract class RequestBody { 28 /** Returns the Content-Type header for this body. */ contentType()29 public abstract MediaType contentType(); 30 31 /** 32 * Returns the number of bytes that will be written to {@code out} in a call 33 * to {@link #writeTo}, or -1 if that count is unknown. 34 */ contentLength()35 public long contentLength() throws IOException { 36 return -1; 37 } 38 39 /** Writes the content of this request to {@code out}. */ writeTo(BufferedSink sink)40 public abstract void writeTo(BufferedSink sink) throws IOException; 41 42 /** 43 * Returns a new request body that transmits {@code content}. If {@code 44 * contentType} is non-null and lacks a charset, this will use UTF-8. 45 */ create(MediaType contentType, String content)46 public static RequestBody create(MediaType contentType, String content) { 47 Charset charset = Util.UTF_8; 48 if (contentType != null) { 49 charset = contentType.charset(); 50 if (charset == null) { 51 charset = Util.UTF_8; 52 contentType = MediaType.parse(contentType + "; charset=utf-8"); 53 } 54 } 55 byte[] bytes = content.getBytes(charset); 56 return create(contentType, bytes); 57 } 58 59 /** Returns a new request body that transmits {@code content}. */ create(final MediaType contentType, final ByteString content)60 public static RequestBody create(final MediaType contentType, final ByteString content) { 61 return new RequestBody() { 62 @Override public MediaType contentType() { 63 return contentType; 64 } 65 66 @Override public long contentLength() throws IOException { 67 return content.size(); 68 } 69 70 @Override public void writeTo(BufferedSink sink) throws IOException { 71 sink.write(content); 72 } 73 }; 74 } 75 76 /** Returns a new request body that transmits {@code content}. */ 77 public static RequestBody create(final MediaType contentType, final byte[] content) { 78 return create(contentType, content, 0, content.length); 79 } 80 81 /** Returns a new request body that transmits {@code content}. */ 82 public static RequestBody create(final MediaType contentType, final byte[] content, 83 final int offset, final int byteCount) { 84 if (content == null) throw new NullPointerException("content == null"); 85 Util.checkOffsetAndCount(content.length, offset, byteCount); 86 return new RequestBody() { 87 @Override public MediaType contentType() { 88 return contentType; 89 } 90 91 @Override public long contentLength() { 92 return byteCount; 93 } 94 95 @Override public void writeTo(BufferedSink sink) throws IOException { 96 sink.write(content, offset, byteCount); 97 } 98 }; 99 } 100 101 /** Returns a new request body that transmits the content of {@code file}. */ 102 public static RequestBody create(final MediaType contentType, final File file) { 103 if (file == null) throw new NullPointerException("content == null"); 104 105 return new RequestBody() { 106 @Override public MediaType contentType() { 107 return contentType; 108 } 109 110 @Override public long contentLength() { 111 return file.length(); 112 } 113 114 @Override public void writeTo(BufferedSink sink) throws IOException { 115 Source source = null; 116 try { 117 source = Okio.source(file); 118 sink.writeAll(source); 119 } finally { 120 Util.closeQuietly(source); 121 } 122 } 123 }; 124 } 125 } 126