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 message.setBody(mUrl.toString());
66 mXmppConnectionService.updateMessage(message);
67 }
68
69 private void finish() {
70 Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
71 intent.setData(Uri.fromFile(file));
72 mXmppConnectionService.sendBroadcast(intent);
73 message.setDownloadable(null);
74 mHttpConnectionManager.finishConnection(this);
75 }
76
77 private void changeStatus(int status) {
78 this.mStatus = status;
79 mXmppConnectionService.updateConversationUi();
80 }
81
82 private class FileSizeChecker implements Runnable {
83
84 @Override
85 public void run() {
86 long size;
87 try {
88 size = retrieveFileSize();
89 } catch (IOException e) {
90 cancel();
91 return;
92 }
93 file.setExpectedSize(size);
94 message.setType(Message.TYPE_IMAGE);
95 if (size <= mHttpConnectionManager.getAutoAcceptFileSize() && mAutostart) {
96 start();
97 } else {
98 changeStatus(STATUS_OFFER);
99 }
100 }
101
102 private long retrieveFileSize() throws IOException {
103 HttpURLConnection connection = (HttpURLConnection) mUrl
104 .openConnection();
105 connection.setRequestMethod("HEAD");
106 if (connection instanceof HttpsURLConnection) {
107
108 }
109 String contentLength = connection.getHeaderField("Content-Length");
110 if (contentLength == null) {
111 throw new IOException();
112 }
113 try {
114 return Long.parseLong(contentLength, 10);
115 } catch (NumberFormatException e) {
116 throw new IOException();
117 }
118 }
119
120 }
121
122 private class FileDownloader implements Runnable {
123
124 @Override
125 public void run() {
126 try {
127 download();
128 updateImageBounds();
129 finish();
130 } catch (IOException e) {
131 cancel();
132 }
133 }
134
135 private void download() throws IOException {
136 HttpURLConnection connection = (HttpURLConnection) mUrl
137 .openConnection();
138 if (connection instanceof HttpsURLConnection) {
139
140 }
141 BufferedInputStream is = new BufferedInputStream(
142 connection.getInputStream());
143 OutputStream os = file.createOutputStream();
144 int count = -1;
145 byte[] buffer = new byte[1024];
146 while ((count = is.read(buffer)) != -1) {
147 os.write(buffer, 0, count);
148 }
149 os.flush();
150 os.close();
151 is.close();
152 }
153
154 private void updateImageBounds() {
155 BitmapFactory.Options options = new BitmapFactory.Options();
156 options.inJustDecodeBounds = true;
157 BitmapFactory.decodeFile(file.getAbsolutePath(), options);
158 int imageHeight = options.outHeight;
159 int imageWidth = options.outWidth;
160 message.setBody(mUrl.toString() + "," + file.getSize() + ','
161 + imageWidth + ',' + imageHeight);
162 mXmppConnectionService.updateMessage(message);
163 }
164
165 }
166
167 @Override
168 public int getStatus() {
169 return this.mStatus;
170 }
171
172 @Override
173 public long getFileSize() {
174 if (this.file != null) {
175 return this.file.getExpectedSize();
176 } else {
177 return 0;
178 }
179 }
180}