//
// Copyright (c) 2014 VK.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
package com.vk.sdk.api.httpClient;
import android.webkit.MimeTypeMap;
import org.apache.http.Header;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.message.BasicHeader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
import java.util.Random;
/**
* Class used for build upload multipart data for VK servers
*/
public class VKMultipartEntity extends AbstractHttpEntity {
private static final String VK_BOUNDARY = "Boundary(======VK_SDK_%d======)";
private final String mBoundary;
private final File[] mFiles;
public VKMultipartEntity(File[] files) {
mBoundary = String.format(Locale.US, VK_BOUNDARY, new Random().nextInt());
mFiles = files;
}
@Override
public boolean isRepeatable() {
return true;
}
@Override
public long getContentLength() {
long length = 0;
for (int i = 0; i < mFiles.length; i++) {
File f = mFiles[i];
length += f.length();
length += getFileDescription(f, i).length();
}
length += getBoundaryEnd().length();
return length;
}
@Override
public Header getContentType() {
return new BasicHeader("Content-Type", String.format("multipart/form-data; boundary=%s", mBoundary));
}
@Override
public InputStream getContent() throws IOException, IllegalStateException {
throw new UnsupportedOperationException("Multipart form entity does not implement #getContent()");
}
private String getFileDescription(File uploadFile, int i) {
String fileName = String.format(Locale.US, "file%d", i + 1);
String extension = MimeTypeMap.getFileExtensionFromUrl(uploadFile.getAbsolutePath());
return String.format("\r\n--%s\r\n", mBoundary) +
String.format("Content-Disposition: form-data; name=\"%s\"; filename=\"%s.%s\"\r\n", fileName, fileName, extension) +
String.format("Content-Type: %s\r\n\r\n", getMimeType(uploadFile.getAbsolutePath()));
}
private String getBoundaryEnd() {
return String.format("\r\n--%s--\r\n", mBoundary);
}
@Override
public void writeTo(OutputStream outputStream) throws IOException {
for (int i = 0; i < mFiles.length; i++) {
File uploadFile = mFiles[i];
outputStream.write(getFileDescription(uploadFile, i).getBytes("UTF-8"));
FileInputStream reader = new FileInputStream(uploadFile);
byte[] fileBuffer = new byte[2048];
int bytesRead;
while ((bytesRead = reader.read(fileBuffer)) != -1) {
outputStream.write(fileBuffer, 0, bytesRead);
}
reader.close();
}
outputStream.write(getBoundaryEnd().getBytes("UTF-8"));
}
@Override
public boolean isStreaming() {
return true;
}
protected static String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
MimeTypeMap mime = MimeTypeMap.getSingleton();
type = mime.getMimeTypeFromExtension(extension);
}
return type;
}
}