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