1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.browser;
18
19import org.apache.http.Header;
20import org.apache.http.HttpHost;
21import org.apache.http.HttpResponse;
22import org.apache.http.client.methods.HttpHead;
23import org.apache.http.conn.params.ConnRouteParams;
24
25import android.app.DownloadManager;
26import android.content.Context;
27import android.net.Proxy;
28import android.net.http.AndroidHttpClient;
29import android.os.Environment;
30import android.util.Log;
31import android.webkit.MimeTypeMap;
32import android.webkit.URLUtil;
33
34import java.io.IOException;
35
36/**
37 * This class is used to pull down the http headers of a given URL so that
38 * we can analyse the mimetype and make any correction needed before we give
39 * the URL to the download manager.
40 * This operation is needed when the user long-clicks on a link or image and
41 * we don't know the mimetype. If the user just clicks on the link, we will
42 * do the same steps of correcting the mimetype down in
43 * android.os.webkit.LoadListener rather than handling it here.
44 *
45 */
46class FetchUrlMimeType extends Thread {
47
48    private final static String LOGTAG = "FetchUrlMimeType";
49
50    private Context mContext;
51    private DownloadManager.Request mRequest;
52    private String mUri;
53    private String mCookies;
54    private String mUserAgent;
55
56    public FetchUrlMimeType(Context context, DownloadManager.Request request,
57            String uri, String cookies, String userAgent) {
58        mContext = context.getApplicationContext();
59        mRequest = request;
60        mUri = uri;
61        mCookies = cookies;
62        mUserAgent = userAgent;
63    }
64
65    @Override
66    public void run() {
67        // User agent is likely to be null, though the AndroidHttpClient
68        // seems ok with that.
69        AndroidHttpClient client = AndroidHttpClient.newInstance(mUserAgent);
70        HttpHost httpHost;
71        try {
72            httpHost = Proxy.getPreferredHttpHost(mContext, mUri);
73            if (httpHost != null) {
74                ConnRouteParams.setDefaultProxy(client.getParams(), httpHost);
75            }
76        } catch (IllegalArgumentException ex) {
77            Log.e(LOGTAG,"Download failed: " + ex);
78            client.close();
79            return;
80        }
81        HttpHead request = new HttpHead(mUri);
82
83        if (mCookies != null && mCookies.length() > 0) {
84            request.addHeader("Cookie", mCookies);
85        }
86
87        HttpResponse response;
88        String mimeType = null;
89        String contentDisposition = null;
90        try {
91            response = client.execute(request);
92            // We could get a redirect here, but if we do lets let
93            // the download manager take care of it, and thus trust that
94            // the server sends the right mimetype
95            if (response.getStatusLine().getStatusCode() == 200) {
96                Header header = response.getFirstHeader("Content-Type");
97                if (header != null) {
98                    mimeType = header.getValue();
99                    final int semicolonIndex = mimeType.indexOf(';');
100                    if (semicolonIndex != -1) {
101                        mimeType = mimeType.substring(0, semicolonIndex);
102                    }
103                }
104                Header contentDispositionHeader = response.getFirstHeader("Content-Disposition");
105                if (contentDispositionHeader != null) {
106                    contentDisposition = contentDispositionHeader.getValue();
107                }
108            }
109        } catch (IllegalArgumentException ex) {
110            request.abort();
111        } catch (IOException ex) {
112            request.abort();
113        } finally {
114            client.close();
115        }
116
117       if (mimeType != null) {
118           if (mimeType.equalsIgnoreCase("text/plain") ||
119                   mimeType.equalsIgnoreCase("application/octet-stream")) {
120               String newMimeType =
121                       MimeTypeMap.getSingleton().getMimeTypeFromExtension(
122                           MimeTypeMap.getFileExtensionFromUrl(mUri));
123               if (newMimeType != null) {
124                   mRequest.setMimeType(newMimeType);
125               }
126           }
127           String filename = URLUtil.guessFileName(mUri, contentDisposition,
128                mimeType);
129           mRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
130       }
131
132       // Start the download
133       DownloadManager manager = (DownloadManager) mContext.getSystemService(
134               Context.DOWNLOAD_SERVICE);
135       manager.enqueue(mRequest);
136    }
137
138}
139