HttpUploadConnection.java

  1package eu.siacs.conversations.http;
  2
  3import android.util.Log;
  4
  5import java.io.IOException;
  6import java.io.InputStream;
  7import java.io.OutputStream;
  8import java.net.HttpURLConnection;
  9import java.net.MalformedURLException;
 10import java.net.URL;
 11
 12import eu.siacs.conversations.Config;
 13import eu.siacs.conversations.entities.Account;
 14import eu.siacs.conversations.entities.Downloadable;
 15import eu.siacs.conversations.entities.DownloadableFile;
 16import eu.siacs.conversations.entities.Message;
 17import eu.siacs.conversations.persistance.FileBackend;
 18import eu.siacs.conversations.services.XmppConnectionService;
 19import eu.siacs.conversations.utils.Xmlns;
 20import eu.siacs.conversations.xml.Element;
 21import eu.siacs.conversations.xmpp.OnIqPacketReceived;
 22import eu.siacs.conversations.xmpp.jid.Jid;
 23import eu.siacs.conversations.xmpp.stanzas.IqPacket;
 24
 25public class HttpUploadConnection implements Downloadable {
 26
 27	private HttpConnectionManager mHttpConnectionManager;
 28	private XmppConnectionService mXmppConnectionService;
 29
 30	private boolean canceled = false;
 31	private Account account;
 32	private DownloadableFile file;
 33	private Message message;
 34	private URL mGetUrl;
 35	private URL mPutUrl;
 36
 37	private long transmitted = 0;
 38	private long expected = 1;
 39
 40	public HttpUploadConnection(HttpConnectionManager httpConnectionManager) {
 41		this.mHttpConnectionManager = httpConnectionManager;
 42		this.mXmppConnectionService = httpConnectionManager.getXmppConnectionService();
 43	}
 44
 45	@Override
 46	public boolean start() {
 47		return false;
 48	}
 49
 50	@Override
 51	public int getStatus() {
 52		return STATUS_UPLOADING;
 53	}
 54
 55	@Override
 56	public long getFileSize() {
 57		return this.file.getExpectedSize();
 58	}
 59
 60	@Override
 61	public int getProgress() {
 62		return (int) ((((double) transmitted) / expected) * 100);
 63	}
 64
 65	@Override
 66	public void cancel() {
 67		this.canceled = true;
 68	}
 69
 70	private void fail() {
 71		mHttpConnectionManager.finishUploadConnection(this);
 72		message.setDownloadable(null);
 73		mXmppConnectionService.markMessage(message,Message.STATUS_SEND_FAILED);
 74	}
 75
 76	public void init(Message message) {
 77		this.message = message;
 78		message.setDownloadable(this);
 79		mXmppConnectionService.markMessage(message,Message.STATUS_UNSEND);
 80		this.account = message.getConversation().getAccount();
 81		this.file = mXmppConnectionService.getFileBackend().getFile(message, false);
 82		this.file.setExpectedSize(this.file.getSize());
 83		Jid host = account.getXmppConnection().findDiscoItemByFeature(Xmlns.HTTP_UPLOAD);
 84		IqPacket request = mXmppConnectionService.getIqGenerator().requestHttpUploadSlot(host,file);
 85		mXmppConnectionService.sendIqPacket(account, request, new OnIqPacketReceived() {
 86			@Override
 87			public void onIqPacketReceived(Account account, IqPacket packet) {
 88				if (packet.getType() == IqPacket.TYPE.RESULT) {
 89					Element slot = packet.findChild("slot",Xmlns.HTTP_UPLOAD);
 90					if (slot != null) {
 91						try {
 92							mGetUrl = new URL(slot.findChildContent("get"));
 93							mPutUrl = new URL(slot.findChildContent("put"));
 94							if (!canceled) {
 95								new Thread(new FileUploader()).start();
 96							}
 97						} catch (MalformedURLException e) {
 98							fail();
 99						}
100					} else {
101						fail();
102					}
103				} else {
104					fail();
105				}
106			}
107		});
108	}
109
110	private class FileUploader implements Runnable {
111
112		@Override
113		public void run() {
114			this.upload();
115		}
116
117		private void upload() {
118			OutputStream os = null;
119			InputStream is = null;
120			HttpURLConnection connection = null;
121			try {
122				Log.d(Config.LOGTAG, "uploading to " + mPutUrl.toString());
123				connection = (HttpURLConnection) mPutUrl.openConnection();
124				connection.setRequestMethod("PUT");
125				connection.setFixedLengthStreamingMode((int) file.getExpectedSize());
126				connection.setDoOutput(true);
127				connection.connect();
128				os = connection.getOutputStream();
129				is = file.createInputStream();
130				transmitted = 0;
131				expected = file.getExpectedSize();
132				int count = -1;
133				byte[] buffer = new byte[4096];
134				while (((count = is.read(buffer)) != -1) && !canceled) {
135					transmitted += count;
136					os.write(buffer, 0, count);
137					mXmppConnectionService.updateConversationUi();
138				}
139				os.flush();
140				os.close();
141				is.close();
142				int code = connection.getResponseCode();
143				if (code == 200) {
144					Log.d(Config.LOGTAG, "finished uploading file");
145					Message.ImageParams params = message.getImageParams();
146					message.setBody(mGetUrl.toString()+"|"+String.valueOf(params.size)+"|"+String.valueOf(params.width)+"|"+String.valueOf(params.height));
147					message.setDownloadable(null);
148					mXmppConnectionService.resendMessage(message);
149				} else {
150					fail();
151				}
152			} catch (IOException e) {
153				Log.d(Config.LOGTAG, e.getMessage());
154				fail();
155			} finally {
156				FileBackend.close(is);
157				FileBackend.close(os);
158				if (connection != null) {
159					connection.disconnect();
160				}
161			}
162		}
163	}
164}