1package eu.siacs.conversations.http;
2
3import java.io.BufferedInputStream;
4import java.io.IOException;
5import java.io.OutputStream;
6import java.net.HttpURLConnection;
7import java.net.MalformedURLException;
8import java.net.URL;
9
10import javax.net.ssl.HttpsURLConnection;
11
12import android.content.Intent;
13import android.graphics.BitmapFactory;
14import android.net.Uri;
15
16import eu.siacs.conversations.entities.Downloadable;
17import eu.siacs.conversations.entities.DownloadableFile;
18import eu.siacs.conversations.entities.Message;
19import eu.siacs.conversations.services.XmppConnectionService;
20
21public class HttpConnection implements Downloadable {
22
23 private HttpConnectionManager mHttpConnectionManager;
24 private XmppConnectionService mXmppConnectionService;
25
26 private URL mUrl;
27 private Message message;
28 private DownloadableFile file;
29 private int mStatus = Downloadable.STATUS_UNKNOWN;
30 private boolean mAutostart = true;
31
32 public HttpConnection(HttpConnectionManager manager) {
33 this.mHttpConnectionManager = manager;
34 this.mXmppConnectionService = manager.getXmppConnectionService();
35 }
36
37 @Override
38 public void start() {
39 changeStatus(STATUS_DOWNLOADING);
40 new Thread(new FileDownloader()).start();
41 }
42
43 public void init(Message message) {
44 this.message = message;
45 this.message.setDownloadable(this);
46 try {
47 mUrl = new URL(message.getBody());
48 this.file = mXmppConnectionService.getFileBackend()
49 .getFile(message, false);
50 this.mAutostart = true;
51 checkFileSize();
52 } catch (MalformedURLException e) {
53 this.cancel();
54 }
55 }
56
57 private void checkFileSize() {
58 changeStatus(STATUS_CHECKING);
59 new Thread(new FileSizeChecker()).start();
60 }
61
62 public void cancel() {
63 mHttpConnectionManager.finishConnection(this);
64 message.setDownloadable(null);
65 mXmppConnectionService.updateConversationUi();
66 }
67
68 private void finish() {
69 Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
70 intent.setData(Uri.fromFile(file));
71 mXmppConnectionService.sendBroadcast(intent);
72 message.setDownloadable(null);
73 mHttpConnectionManager.finishConnection(this);
74 }
75
76 private void changeStatus(int status) {
77 this.mStatus = status;
78 mXmppConnectionService.updateConversationUi();
79 }
80
81 private class FileSizeChecker implements Runnable {
82
83 @Override
84 public void run() {
85 long size;
86 try {
87 size = retrieveFileSize();
88 } catch (IOException e) {
89 cancel();
90 return;
91 }
92 file.setExpectedSize(size);
93 if (size <= mHttpConnectionManager.getAutoAcceptFileSize() && mAutostart) {
94 start();
95 } else {
96 changeStatus(STATUS_OFFER);
97 }
98 }
99
100 private long retrieveFileSize() throws IOException {
101 HttpURLConnection connection = (HttpURLConnection) mUrl
102 .openConnection();
103 connection.setRequestMethod("HEAD");
104 if (connection instanceof HttpsURLConnection) {
105
106 }
107 String contentLength = connection.getHeaderField("Content-Length");
108 if (contentLength == null) {
109 throw new IOException();
110 }
111 try {
112 return Long.parseLong(contentLength, 10);
113 } catch (NumberFormatException e) {
114 throw new IOException();
115 }
116 }
117
118 }
119
120 private class FileDownloader implements Runnable {
121
122 @Override
123 public void run() {
124 try {
125 download();
126 updateImageBounds();
127 finish();
128 } catch (IOException e) {
129 cancel();
130 }
131 }
132
133 private void download() throws IOException {
134 HttpURLConnection connection = (HttpURLConnection) mUrl
135 .openConnection();
136 if (connection instanceof HttpsURLConnection) {
137
138 }
139 BufferedInputStream is = new BufferedInputStream(
140 connection.getInputStream());
141 OutputStream os = file.createOutputStream();
142 int count = -1;
143 byte[] buffer = new byte[1024];
144 while ((count = is.read(buffer)) != -1) {
145 os.write(buffer, 0, count);
146 }
147 os.flush();
148 os.close();
149 is.close();
150 }
151
152 private void updateImageBounds() {
153 BitmapFactory.Options options = new BitmapFactory.Options();
154 options.inJustDecodeBounds = true;
155 BitmapFactory.decodeFile(file.getAbsolutePath(), options);
156 int imageHeight = options.outHeight;
157 int imageWidth = options.outWidth;
158 message.setBody(mUrl.toString() + "," + file.getSize() + ','
159 + imageWidth + ',' + imageHeight);
160 message.setType(Message.TYPE_IMAGE);
161 mXmppConnectionService.updateMessage(message);
162 }
163
164 }
165
166 @Override
167 public int getStatus() {
168 return this.mStatus;
169 }
170
171 @Override
172 public long getFileSize() {
173 if (this.file != null) {
174 return this.file.getExpectedSize();
175 } else {
176 return 0;
177 }
178 }
179}