mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-23 18:02:15 -05:00
Handle "cid:" URIs in HTML message body
This commit is contained in:
parent
80221dace8
commit
1a20ca06f1
@ -20,7 +20,7 @@ public interface Part {
|
|||||||
|
|
||||||
String getDisposition() throws MessagingException;
|
String getDisposition() throws MessagingException;
|
||||||
|
|
||||||
String getContentId() throws MessagingException;
|
String getContentId();
|
||||||
|
|
||||||
String[] getHeader(String name) throws MessagingException;
|
String[] getHeader(String name) throws MessagingException;
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ public class MimeBodyPart extends BodyPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getContentId() throws MessagingException {
|
public String getContentId() {
|
||||||
String contentId = getFirstHeader(MimeHeader.HEADER_CONTENT_ID);
|
String contentId = getFirstHeader(MimeHeader.HEADER_CONTENT_ID);
|
||||||
if (contentId == null) {
|
if (contentId == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -174,7 +174,7 @@ public class MimeMessage extends Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getContentId() throws MessagingException {
|
public String getContentId() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,7 +518,7 @@ public class LocalMessageExtractor {
|
|||||||
return attachments;
|
return attachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AttachmentViewInfo extractAttachmentInfo(Context context, Part part) throws MessagingException {
|
public static AttachmentViewInfo extractAttachmentInfo(Context context, Part part) throws MessagingException {
|
||||||
if (part instanceof LocalPart) {
|
if (part instanceof LocalPart) {
|
||||||
LocalPart localPart = (LocalPart) part;
|
LocalPart localPart = (LocalPart) part;
|
||||||
String accountUuid = localPart.getAccountUuid();
|
String accountUuid = localPart.getAccountUuid();
|
||||||
|
@ -26,6 +26,7 @@ import android.view.View.OnCreateContextMenuListener;
|
|||||||
import android.view.ViewStub;
|
import android.view.ViewStub;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.WebView.HitTestResult;
|
import android.webkit.WebView.HitTestResult;
|
||||||
|
import android.webkit.WebViewClient;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@ -34,10 +35,12 @@ import com.fsck.k9.R;
|
|||||||
import com.fsck.k9.helper.ClipboardManager;
|
import com.fsck.k9.helper.ClipboardManager;
|
||||||
import com.fsck.k9.helper.Contacts;
|
import com.fsck.k9.helper.Contacts;
|
||||||
import com.fsck.k9.mail.Address;
|
import com.fsck.k9.mail.Address;
|
||||||
|
import com.fsck.k9.mail.Message;
|
||||||
import com.fsck.k9.mail.MessagingException;
|
import com.fsck.k9.mail.MessagingException;
|
||||||
import com.fsck.k9.mailstore.AttachmentViewInfo;
|
import com.fsck.k9.mailstore.AttachmentViewInfo;
|
||||||
import com.fsck.k9.mailstore.MessageViewInfo.MessageViewContainer;
|
import com.fsck.k9.mailstore.MessageViewInfo.MessageViewContainer;
|
||||||
|
|
||||||
|
import com.fsck.k9.view.K9WebViewClient;
|
||||||
import com.fsck.k9.view.MessageHeader.OnLayoutChangedListener;
|
import com.fsck.k9.view.MessageHeader.OnLayoutChangedListener;
|
||||||
import com.fsck.k9.view.MessageWebView;
|
import com.fsck.k9.view.MessageWebView;
|
||||||
import org.openintents.openpgp.OpenPgpError;
|
import org.openintents.openpgp.OpenPgpError;
|
||||||
@ -421,10 +424,13 @@ public class MessageContainerView extends LinearLayout implements OnClickListene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(MessageViewContainer messageViewContainer)
|
public void setMessageViewContainer(Message message, MessageViewContainer messageViewContainer)
|
||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
resetView();
|
resetView();
|
||||||
|
|
||||||
|
WebViewClient webViewClient = K9WebViewClient.newInstance(message);
|
||||||
|
mMessageContentView.setWebViewClient(webViewClient);
|
||||||
|
|
||||||
// Save the text so we can reset the WebView when the user clicks the "Show pictures" button
|
// Save the text so we can reset the WebView when the user clicks the "Show pictures" button
|
||||||
OpenPgpError error = messageViewContainer.pgpError;
|
OpenPgpError error = messageViewContainer.pgpError;
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.fsck.k9.ui.messageview;
|
package com.fsck.k9.ui.messageview;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@ -14,7 +13,6 @@ import android.widget.LinearLayout;
|
|||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
import com.fsck.k9.crypto.PgpData;
|
|
||||||
import com.fsck.k9.mail.Flag;
|
import com.fsck.k9.mail.Flag;
|
||||||
import com.fsck.k9.mail.Message;
|
import com.fsck.k9.mail.Message;
|
||||||
import com.fsck.k9.mail.MessagingException;
|
import com.fsck.k9.mail.MessagingException;
|
||||||
@ -67,11 +65,13 @@ public class MessageTopView extends LinearLayout {
|
|||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
resetView();
|
resetView();
|
||||||
|
|
||||||
|
Message message = messageViewInfo.message;
|
||||||
for (MessageViewContainer container : messageViewInfo.containers) {
|
for (MessageViewContainer container : messageViewInfo.containers) {
|
||||||
MessageContainerView view = (MessageContainerView) mInflater.inflate(R.layout.message_container, null);
|
MessageContainerView view = (MessageContainerView) mInflater.inflate(R.layout.message_container, null);
|
||||||
view.initialize(fragment, attachmentCallback, openPgpHeaderViewCallback,
|
view.initialize(fragment, attachmentCallback, openPgpHeaderViewCallback,
|
||||||
!Account.NO_OPENPGP_PROVIDER.equals(account.getOpenPgpProvider()));
|
!Account.NO_OPENPGP_PROVIDER.equals(account.getOpenPgpProvider()));
|
||||||
view.setMessage(container);
|
view.setMessageViewContainer(message, container);
|
||||||
|
|
||||||
containerViews.addView(view);
|
containerViews.addView(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
126
k9mail/src/main/java/com/fsck/k9/view/K9WebViewClient.java
Normal file
126
k9mail/src/main/java/com/fsck/k9/view/K9WebViewClient.java
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
package com.fsck.k9.view;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Build.VERSION_CODES;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.webkit.WebResourceRequest;
|
||||||
|
import android.webkit.WebResourceResponse;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
import android.webkit.WebViewClient;
|
||||||
|
|
||||||
|
import com.fsck.k9.K9;
|
||||||
|
import com.fsck.k9.mail.Body;
|
||||||
|
import com.fsck.k9.mail.Message;
|
||||||
|
import com.fsck.k9.mail.Multipart;
|
||||||
|
import com.fsck.k9.mail.Part;
|
||||||
|
import com.fsck.k9.mailstore.AttachmentViewInfo;
|
||||||
|
import com.fsck.k9.mailstore.LocalMessageExtractor;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link WebViewClient} that intercepts requests for {@code cid:} URIs to load the respective body part.
|
||||||
|
*/
|
||||||
|
public abstract class K9WebViewClient extends WebViewClient {
|
||||||
|
private static final String CID_SCHEME = "cid";
|
||||||
|
private static final WebResourceResponse RESULT_DO_NOT_INTERCEPT = null;
|
||||||
|
private static final WebResourceResponse RESULT_DUMMY_RESPONSE = new WebResourceResponse(null, null, null);
|
||||||
|
|
||||||
|
public static WebViewClient newInstance(Message message) {
|
||||||
|
if (Build.VERSION.SDK_INT < 21) {
|
||||||
|
return new PreLollipopWebViewClient(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LollipopWebViewClient(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final Message message;
|
||||||
|
|
||||||
|
private K9WebViewClient(Message message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected WebResourceResponse shouldInterceptRequest(WebView webView, Uri uri) {
|
||||||
|
if (!CID_SCHEME.equals(uri.getScheme())) {
|
||||||
|
return RESULT_DO_NOT_INTERCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
String cid = uri.getSchemeSpecificPart();
|
||||||
|
if (TextUtils.isEmpty(cid)) {
|
||||||
|
return RESULT_DUMMY_RESPONSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Part part = getPartForContentId(cid);
|
||||||
|
if (part == null) {
|
||||||
|
return RESULT_DUMMY_RESPONSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context context = webView.getContext();
|
||||||
|
ContentResolver contentResolver = context.getContentResolver();
|
||||||
|
try {
|
||||||
|
AttachmentViewInfo attachmentInfo = LocalMessageExtractor.extractAttachmentInfo(context, part);
|
||||||
|
String mimeType = attachmentInfo.mimeType;
|
||||||
|
InputStream inputStream = contentResolver.openInputStream(attachmentInfo.uri);
|
||||||
|
|
||||||
|
return new WebResourceResponse(mimeType, null, inputStream);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(K9.LOG_TAG, "Error while intercepting URI: " + uri, e);
|
||||||
|
return RESULT_DUMMY_RESPONSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Part getPartForContentId(String cid) {
|
||||||
|
Stack<Part> partsToCheck = new Stack<Part>();
|
||||||
|
partsToCheck.push(message);
|
||||||
|
|
||||||
|
while (!partsToCheck.isEmpty()) {
|
||||||
|
Part part = partsToCheck.pop();
|
||||||
|
|
||||||
|
Body body = part.getBody();
|
||||||
|
if (body instanceof Multipart) {
|
||||||
|
Multipart multipart = (Multipart) body;
|
||||||
|
for (Part bodyPart : multipart.getBodyParts()) {
|
||||||
|
partsToCheck.push(bodyPart);
|
||||||
|
}
|
||||||
|
} else if (cid.equals(part.getContentId())) {
|
||||||
|
return part;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class PreLollipopWebViewClient extends K9WebViewClient {
|
||||||
|
protected PreLollipopWebViewClient(Message message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public WebResourceResponse shouldInterceptRequest(WebView webView, String url) {
|
||||||
|
return shouldInterceptRequest(webView, Uri.parse(url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(VERSION_CODES.LOLLIPOP)
|
||||||
|
private static class LollipopWebViewClient extends K9WebViewClient {
|
||||||
|
protected LollipopWebViewClient(Message message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WebResourceResponse shouldInterceptRequest(WebView webView, WebResourceRequest request) {
|
||||||
|
return shouldInterceptRequest(webView, request.getUrl());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user