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 if (request != null) { 111 request.abort(); 112 } 113 } catch (IOException ex) { 114 if (request != null) { 115 request.abort(); 116 } 117 } finally { 118 client.close(); 119 } 120 121 if (mimeType != null) { 122 if (mimeType.equalsIgnoreCase("text/plain") || 123 mimeType.equalsIgnoreCase("application/octet-stream")) { 124 String newMimeType = 125 MimeTypeMap.getSingleton().getMimeTypeFromExtension( 126 MimeTypeMap.getFileExtensionFromUrl(mUri)); 127 if (newMimeType != null) { 128 mimeType = newMimeType; 129 mRequest.setMimeType(newMimeType); 130 } 131 } 132 String filename = URLUtil.guessFileName(mUri, contentDisposition, 133 mimeType); 134 mRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); 135 } 136 137 // Start the download 138 DownloadManager manager = (DownloadManager) mContext.getSystemService( 139 Context.DOWNLOAD_SERVICE); 140 manager.enqueue(mRequest); 141 } 142 143} 144