Android Open Source - HockeySDK-Android Simple Multipart Entity






From Project

Back to project page HockeySDK-Android.

License

The source code is released under:

Apache License

If you think the Android project HockeySDK-Android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package net.hockeyapp.android.utils;
//from   ww w  .java2  s.  c  o  m
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.message.BasicHeader;

import java.io.*;
import java.util.Random;

/**
 * <h3>Description</h3>
 * 
 * To avoid external apache library "httpmime" this is a simple implementation for a MultipartEntity.
 * Please note that first all key value pairs have to be written and then at least one file part has to be added.
 * Otherwise the boundaries are not written correctly.
 *
 * Based on:
 * http://derivedcode.wordpress.com/2014/11/04/android-uploading-files-to-server-over-http-using-multipart-entity/
 * 
 * <h3>License</h3>
 * 
 * <pre>
 * Copyright (c) 2011-2014 Bit Stadium GmbH
 * 
 * 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.
 * </pre>
 *
 * @author Patrick Eschenbach
 */
public class SimpleMultipartEntity implements HttpEntity {

  private final static char[] BOUNDARY_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();

  private boolean isSetLast;

  private boolean isSetFirst;

  private ByteArrayOutputStream out;

  private String boundary;

  public SimpleMultipartEntity() {
    this.isSetFirst = false;
    this.isSetLast  = false;
    this.out = new ByteArrayOutputStream();

    /** Create boundary String */
    final StringBuffer buffer = new StringBuffer();
    final Random rand = new Random();

    for (int i = 0; i < 30; i++) {
      buffer.append(BOUNDARY_CHARS[rand.nextInt(BOUNDARY_CHARS.length)]);
    }
    this.boundary = buffer.toString();
  }

  public String getBoundary() {
    return boundary;
  }

  public void writeFirstBoundaryIfNeeds() throws IOException {
    if (!isSetFirst) {
      out.write(("--" + boundary + "\r\n").getBytes());
    }
    isSetFirst = true;
  }

  public void writeLastBoundaryIfNeeds() {
    if (isSetLast) {
      return;
    }
    try {
      out.write(("\r\n--" + boundary + "--\r\n").getBytes());

    } catch (final IOException e) {
      e.printStackTrace();
    }
    isSetLast = true;
  }

  public void addPart(final String key, final String value) throws IOException {
    writeFirstBoundaryIfNeeds();

    out.write(("Content-Disposition: form-data; name=\"" + key + "\"\r\n").getBytes());
    out.write("Content-Type: text/plain; charset=UTF-8\r\n".getBytes());
    out.write("Content-Transfer-Encoding: 8bit\r\n\r\n".getBytes());
    out.write(value.getBytes());
    out.write(("\r\n--" + boundary + "\r\n").getBytes());
  }

  public void addPart(final String key, final File value, boolean lastFile) throws IOException {
    addPart(key, value.getName(), new FileInputStream(value), lastFile);
  }

  public void addPart(final String key, final String fileName, final InputStream fin, boolean lastFile) throws IOException {
    addPart(key, fileName, fin, "application/octet-stream", lastFile);
  }

  public void addPart(final String key, final String fileName, final InputStream fin, String type, boolean lastFile) throws IOException {
    writeFirstBoundaryIfNeeds();
    try {
      type = "Content-Type: " + type + "\r\n";
      out.write(("Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" + fileName + "\"\r\n").getBytes());
      out.write(type.getBytes());
      out.write("Content-Transfer-Encoding: binary\r\n\r\n".getBytes());

      final byte[] tmp = new byte[4096];
      int l = 0;
      while ((l = fin.read(tmp)) != -1) {
        out.write(tmp, 0, l);
      }
      out.flush();

      if (lastFile) {
        /** This is the last file: write last boundary. */
        writeLastBoundaryIfNeeds();

      } else {
        /** Another file will follow: write normal boundary. */
        out.write(("\r\n--" + boundary + "\r\n").getBytes());
      }

    } finally {
      try {
        fin.close();
      } catch (final IOException e) {
        e.printStackTrace();
      }
    }
  }

  @Override
  public long getContentLength() {
    writeLastBoundaryIfNeeds();
    return out.toByteArray().length;
  }

  @Override
  public Header getContentType() {
    return new BasicHeader("Content-Type", "multipart/form-data; boundary=" + getBoundary());
  }

  @Override
  public boolean isChunked() {
    return false;
  }

  @Override
  public boolean isRepeatable() {
    return false;
  }

  @Override
  public boolean isStreaming() {
    return false;
  }

  @Override
  public void writeTo(final OutputStream outstream) throws IOException {
    outstream.write(out.toByteArray());
  }

  @Override
  public Header getContentEncoding() {
    return null;
  }

  @Override
  public void consumeContent() throws IOException, UnsupportedOperationException {
    if (isStreaming()) {
      throw new UnsupportedOperationException("Streaming entity does not implement #consumeContent()");
    }
  }

  @Override
  public InputStream getContent() throws IOException, UnsupportedOperationException {
    return new ByteArrayInputStream(out.toByteArray());
  }
}




Java Source Code List

net.hockeyapp.android.Constants.java
net.hockeyapp.android.CrashManagerListener.java
net.hockeyapp.android.CrashManager.java
net.hockeyapp.android.ExceptionHandler.java
net.hockeyapp.android.ExpiryInfoActivity.java
net.hockeyapp.android.FeedbackActivityInterface.java
net.hockeyapp.android.FeedbackActivity.java
net.hockeyapp.android.FeedbackManagerListener.java
net.hockeyapp.android.FeedbackManager.java
net.hockeyapp.android.LocaleManager.java
net.hockeyapp.android.LoginActivity.java
net.hockeyapp.android.LoginManagerListener.java
net.hockeyapp.android.LoginManager.java
net.hockeyapp.android.PaintActivity.java
net.hockeyapp.android.StringListener.java
net.hockeyapp.android.Strings.java
net.hockeyapp.android.Tracking.java
net.hockeyapp.android.UpdateActivityInterface.java
net.hockeyapp.android.UpdateActivity.java
net.hockeyapp.android.UpdateFragment.java
net.hockeyapp.android.UpdateInfoListener.java
net.hockeyapp.android.UpdateManagerListener.java
net.hockeyapp.android.UpdateManager.java
net.hockeyapp.android.adapters.MessagesAdapter.java
net.hockeyapp.android.listeners.DownloadFileListener.java
net.hockeyapp.android.listeners.SendFeedbackListener.java
net.hockeyapp.android.objects.ErrorObject.java
net.hockeyapp.android.objects.FeedbackAttachment.java
net.hockeyapp.android.objects.FeedbackMessage.java
net.hockeyapp.android.objects.FeedbackResponse.java
net.hockeyapp.android.objects.Feedback.java
net.hockeyapp.android.tasks.AttachmentDownloader.java
net.hockeyapp.android.tasks.CheckUpdateTaskWithUI.java
net.hockeyapp.android.tasks.CheckUpdateTask.java
net.hockeyapp.android.tasks.DownloadFileTask.java
net.hockeyapp.android.tasks.GetFileSizeTask.java
net.hockeyapp.android.tasks.LoginTask.java
net.hockeyapp.android.tasks.ParseFeedbackTask.java
net.hockeyapp.android.tasks.SendFeedbackTask.java
net.hockeyapp.android.utils.AsyncTaskUtils.java
net.hockeyapp.android.utils.Base64.java
net.hockeyapp.android.utils.ConnectionManager.java
net.hockeyapp.android.utils.DeviceUtils.java
net.hockeyapp.android.utils.FeedbackParser.java
net.hockeyapp.android.utils.ImageUtils.java
net.hockeyapp.android.utils.PrefsUtil.java
net.hockeyapp.android.utils.SimpleMultipartEntity.java
net.hockeyapp.android.utils.UiThreadUtil.java
net.hockeyapp.android.utils.Util.java
net.hockeyapp.android.utils.VersionCache.java
net.hockeyapp.android.utils.VersionHelper.java
net.hockeyapp.android.utils.ViewHelper.java
net.hockeyapp.android.views.AttachmentListView.java
net.hockeyapp.android.views.AttachmentView.java
net.hockeyapp.android.views.ExpiryInfoView.java
net.hockeyapp.android.views.FeedbackMessageView.java
net.hockeyapp.android.views.FeedbackView.java
net.hockeyapp.android.views.LoginView.java
net.hockeyapp.android.views.PaintView.java
net.hockeyapp.android.views.UpdateView.java