Home | History | Annotate | Download | only in browser
      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 
     17 package com.android.browser;
     18 
     19 import android.content.ContentValues;
     20 import android.net.Uri;
     21 import android.net.http.AndroidHttpClient;
     22 
     23 import org.apache.http.HttpResponse;
     24 import org.apache.http.Header;
     25 import org.apache.http.client.methods.HttpHead;
     26 
     27 import java.io.IOException;
     28 
     29 import android.os.AsyncTask;
     30 import android.provider.Downloads;
     31 import android.webkit.MimeTypeMap;
     32 import android.webkit.URLUtil;
     33 
     34 /**
     35  * This class is used to pull down the http headers of a given URL so that
     36  * we can analyse the mimetype and make any correction needed before we give
     37  * the URL to the download manager. The ContentValues class holds the
     38  * content that would be provided to the download manager, so that on
     39  * completion of checking the mimetype, we can issue the download to
     40  * the download manager.
     41  * This operation is needed when the user long-clicks on a link or image and
     42  * we don't know the mimetype. If the user just clicks on the link, we will
     43  * do the same steps of correcting the mimetype down in
     44  * android.os.webkit.LoadListener rather than handling it here.
     45  *
     46  */
     47 class FetchUrlMimeType extends AsyncTask<ContentValues, String, String> {
     48 
     49     BrowserActivity mActivity;
     50     ContentValues mValues;
     51 
     52     public FetchUrlMimeType(BrowserActivity activity) {
     53         mActivity = activity;
     54     }
     55 
     56     @Override
     57     public String doInBackground(ContentValues... values) {
     58         mValues = values[0];
     59 
     60         // Check to make sure we have a URI to download
     61         String uri = mValues.getAsString(Downloads.Impl.COLUMN_URI);
     62         if (uri == null || uri.length() == 0) {
     63             return null;
     64         }
     65 
     66         // User agent is likely to be null, though the AndroidHttpClient
     67         // seems ok with that.
     68         AndroidHttpClient client = AndroidHttpClient.newInstance(
     69                 mValues.getAsString(Downloads.Impl.COLUMN_USER_AGENT));
     70         HttpHead request = new HttpHead(uri);
     71 
     72         String cookie = mValues.getAsString(Downloads.Impl.COLUMN_COOKIE_DATA);
     73         if (cookie != null && cookie.length() > 0) {
     74             request.addHeader("Cookie", cookie);
     75         }
     76 
     77         String referer = mValues.getAsString(Downloads.Impl.COLUMN_REFERER);
     78         if (referer != null && referer.length() > 0) {
     79             request.addHeader("Referer", referer);
     80         }
     81 
     82         HttpResponse response;
     83         String mimeType = null;
     84         try {
     85             response = client.execute(request);
     86             // We could get a redirect here, but if we do lets let
     87             // the download manager take care of it, and thus trust that
     88             // the server sends the right mimetype
     89             if (response.getStatusLine().getStatusCode() == 200) {
     90                 Header header = response.getFirstHeader("Content-Type");
     91                 if (header != null) {
     92                     mimeType = header.getValue();
     93                     final int semicolonIndex = mimeType.indexOf(';');
     94                     if (semicolonIndex != -1) {
     95                         mimeType = mimeType.substring(0, semicolonIndex);
     96                     }
     97                 }
     98             }
     99         } catch (IllegalArgumentException ex) {
    100             request.abort();
    101         } catch (IOException ex) {
    102             request.abort();
    103         } finally {
    104             client.close();
    105         }
    106 
    107         return mimeType;
    108     }
    109 
    110    @Override
    111     public void onPostExecute(String mimeType) {
    112        if (mimeType != null) {
    113            String url = mValues.getAsString(Downloads.Impl.COLUMN_URI);
    114            if (mimeType.equalsIgnoreCase("text/plain") ||
    115                    mimeType.equalsIgnoreCase("application/octet-stream")) {
    116                String newMimeType =
    117                        MimeTypeMap.getSingleton().getMimeTypeFromExtension(
    118                            MimeTypeMap.getFileExtensionFromUrl(url));
    119                if (newMimeType != null) {
    120                    mValues.put(Downloads.Impl.COLUMN_MIME_TYPE, newMimeType);
    121                }
    122            }
    123            String filename = URLUtil.guessFileName(url,
    124                    null, mimeType);
    125            mValues.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, filename);
    126        }
    127 
    128        // Start the download
    129        final Uri contentUri =
    130            mActivity.getContentResolver().insert(Downloads.Impl.CONTENT_URI, mValues);
    131     }
    132 
    133 }
    134