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;
15import android.util.Log;
16
17import eu.siacs.conversations.Config;
18import eu.siacs.conversations.entities.Downloadable;
19import eu.siacs.conversations.entities.DownloadableFile;
20import eu.siacs.conversations.entities.Message;
21import eu.siacs.conversations.services.XmppConnectionService;
22
23public class HttpConnection implements Downloadable {
24
25 private HttpConnectionManager mHttpConnectionManager;
26 private XmppConnectionService mXmppConnectionService;
27
28 private URL mUrl;
29 private Message message;
30 private DownloadableFile file;
31 private int mStatus = Downloadable.STATUS_UNKNOWN;
32 private boolean mAutostart = true;
33
34 public HttpConnection(HttpConnectionManager manager) {
35 this.mHttpConnectionManager = manager;
36 this.mXmppConnectionService = manager.getXmppConnectionService();
37 }
38
39 @Override
40 public boolean start() {
41 if (mXmppConnectionService.hasInternetConnection()) {
42 changeStatus(STATUS_DOWNLOADING);
43 new Thread(new FileDownloader()).start();
44 return true;
45 } else {
46 return false;
47 }
48 }
49
50 public void init(Message message) {
51 this.message = message;
52 this.message.setDownloadable(this);
53 try {
54 mUrl = new URL(message.getBody());
55 this.file = mXmppConnectionService.getFileBackend()
56 .getFile(message, false);
57 this.mAutostart = true;
58 checkFileSize();
59 } catch (MalformedURLException e) {
60 this.cancel();
61 }
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 mXmppConnectionService.updateConversationUi();
73 }
74
75 private void finish() {
76 Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
77 intent.setData(Uri.fromFile(file));
78 mXmppConnectionService.sendBroadcast(intent);
79 message.setDownloadable(null);
80 mHttpConnectionManager.finishConnection(this);
81 }
82
83 private void changeStatus(int status) {
84 this.mStatus = status;
85 mXmppConnectionService.updateConversationUi();
86 }
87
88 private class FileSizeChecker implements Runnable {
89
90 @Override
91 public void run() {
92 long size;
93 try {
94 size = retrieveFileSize();
95 } catch (IOException e) {
96 cancel();
97 return;
98 }
99 file.setExpectedSize(size);
100 if (size <= mHttpConnectionManager.getAutoAcceptFileSize() && mAutostart) {
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 message.setType(Message.TYPE_IMAGE);
168 mXmppConnectionService.updateMessage(message);
169 }
170
171 }
172
173 @Override
174 public int getStatus() {
175 return this.mStatus;
176 }
177
178 @Override
179 public long getFileSize() {
180 if (this.file != null) {
181 return this.file.getExpectedSize();
182 } else {
183 return 0;
184 }
185 }
186}