package eu.siacs.conversations.http; import java.io.BufferedInputStream; import java.io.IOException; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import javax.net.ssl.HttpsURLConnection; import android.graphics.BitmapFactory; import eu.siacs.conversations.entities.Downloadable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.XmppConnectionService; public class HttpConnection implements Downloadable { private HttpConnectionManager mHttpConnectionManager; private XmppConnectionService mXmppConnectionService; private URL mUrl; private Message message; private DownloadableFile file; private long mPreviousFileSize = Long.MIN_VALUE; public HttpConnection(HttpConnectionManager manager) { this.mHttpConnectionManager = manager; this.mXmppConnectionService = manager.getXmppConnectionService(); } @Override public void start() { new Thread(new FileDownloader()).start(); } public void init(Message message) { this.message = message; this.message.setDownloadable(this); try { mUrl = new URL(message.getBody()); this.file = mXmppConnectionService.getFileBackend().getConversationsFile(message,false); message.setType(Message.TYPE_IMAGE); message.setStatus(Message.STATUS_RECEIVED_CHECKING); mXmppConnectionService.updateConversationUi(); checkFileSize(); } catch (MalformedURLException e) { this.cancel(); } } public void init(Message message, URL url) { this.message = message; this.message.setDownloadable(this); this.mUrl = url; this.file = mXmppConnectionService.getFileBackend().getConversationsFile(message,false); this.mPreviousFileSize = message.getImageParams().size; message.setType(Message.TYPE_IMAGE); message.setStatus(Message.STATUS_RECEIVED_CHECKING); mXmppConnectionService.updateConversationUi(); checkFileSize(); } private void checkFileSize() { new Thread(new FileSizeChecker()).start(); } public void cancel() { mXmppConnectionService.markMessage(message, Message.STATUS_RECEPTION_FAILED); mHttpConnectionManager.finishConnection(this); } private void finish() { message.setStatus(Message.STATUS_RECEIVED); mXmppConnectionService.updateMessage(message); mHttpConnectionManager.finishConnection(this); } private class FileSizeChecker implements Runnable { @Override public void run() { long size; try { size = retrieveFileSize(); } catch (IOException e) { cancel(); return; } file.setExpectedSize(size); message.setBody(mUrl.toString()+","+String.valueOf(size)); if (size <= mHttpConnectionManager.getAutoAcceptFileSize() || size == mPreviousFileSize) { mXmppConnectionService.updateMessage(message); start(); } else { message.setStatus(Message.STATUS_RECEIVED_OFFER); mXmppConnectionService.updateMessage(message); } } private long retrieveFileSize() throws IOException { HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); connection.setRequestMethod("HEAD"); if (connection instanceof HttpsURLConnection) { } String contentLength = connection.getHeaderField("Content-Length"); if (contentLength == null) { throw new IOException(); } try { return Long.parseLong(contentLength, 10); } catch (NumberFormatException e) { throw new IOException(); } } } private class FileDownloader implements Runnable { @Override public void run() { try { mXmppConnectionService.markMessage(message, Message.STATUS_RECEIVING); download(); updateImageBounds(); finish(); } catch (IOException e) { cancel(); } } private void download() throws IOException { HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); if (connection instanceof HttpsURLConnection) { } BufferedInputStream is = new BufferedInputStream(connection.getInputStream()); OutputStream os = file.createOutputStream(); int count = -1; byte[] buffer = new byte[1024]; while ((count = is.read(buffer)) != -1) { os.write(buffer, 0, count); } os.flush(); os.close(); is.close(); } private void updateImageBounds() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(file.getAbsolutePath(), options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; message.setBody(mUrl.toString()+","+file.getSize() + ',' + imageWidth + ',' + imageHeight); } } }