1 /* 2 * Copyright (C) 2014 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.exchange.utility; 18 19 import android.util.Base64; 20 import android.util.Log; 21 22 import com.android.exchange.Eas; 23 import com.android.mail.utils.LogUtils; 24 25 import org.apache.http.Header; 26 import org.apache.http.HttpEntity; 27 import org.apache.http.entity.BufferedHttpEntity; 28 import org.apache.http.HttpResponse; 29 import org.apache.http.HttpResponseInterceptor; 30 import org.apache.http.protocol.HttpContext; 31 32 import java.io.ByteArrayOutputStream; 33 import java.io.IOException; 34 import java.io.InputStream; 35 import java.util.zip.GZIPInputStream; 36 37 /** 38 * Dumps the wbxml in base64 (much like {@link CurlLogger}) so that the 39 * response from Exchange can be viewed for debugging purposes. 40 */ 41 public class WbxmlResponseLogger implements HttpResponseInterceptor { 42 private static final String TAG = Eas.LOG_TAG; 43 protected static final int MAX_LENGTH = 1024; 44 45 protected static boolean shouldLogResponse(final long contentLength) { 46 // Not going to bother if there is a lot of content since most of that information 47 // will probably just be message contents anyways. 48 return contentLength < MAX_LENGTH; 49 } 50 51 protected static String processContentEncoding(final Header encodingHeader) { 52 if (encodingHeader != null) { 53 final String encodingValue = encodingHeader.getValue(); 54 return (encodingValue == null) ? "UTF-8" : encodingValue; 55 } 56 return "UTF-8"; 57 } 58 59 protected static byte[] getContentAsByteArray(InputStream is, int batchSize) 60 throws IOException { 61 // Start building our byte array to encode and dump. 62 int count; 63 final byte[] data = new byte[batchSize]; 64 final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 65 while ((count = is.read(data, 0, data.length)) != -1) { 66 buffer.write(data, 0, count); 67 } 68 buffer.flush(); 69 return buffer.toByteArray(); 70 } 71 72 @Override 73 public void process(HttpResponse response, HttpContext context) throws IOException { 74 if (Log.isLoggable(TAG, Log.DEBUG)) { 75 // Wrap the HttpEntity so the response InputStream can be requested and processed 76 // numerous times. 77 response.setEntity(new BufferedHttpEntity(response.getEntity())); 78 79 // Now grab the wrapped HttpEntity so that you safely can process the response w/o 80 // affecting the core response processing module. 81 final HttpEntity entity = response.getEntity(); 82 if (!shouldLogResponse(entity.getContentLength())) { 83 LogUtils.d(TAG, "wbxml response: [TOO MUCH DATA TO INCLUDE]"); 84 return; 85 } 86 87 // We need to figure out the encoding in the case that it is gzip and we need to 88 // inflate it during processing. 89 final Header encodingHeader = entity.getContentEncoding(); 90 final String encoding = processContentEncoding(encodingHeader); 91 92 final InputStream is; 93 if (encoding.equals("gzip")) { 94 // We need to inflate this first. 95 final InputStream unwrappedIs = response.getEntity().getContent(); 96 is = new GZIPInputStream(unwrappedIs); 97 } else { 98 is = response.getEntity().getContent(); 99 } 100 101 final byte currentXMLBytes[] = getContentAsByteArray(is, MAX_LENGTH); 102 103 // Now let's dump out the base 64 encoded bytes and the rest of the command that will 104 // tell us what the response is. 105 final String base64 = Base64.encodeToString(currentXMLBytes, Base64.NO_WRAP); 106 LogUtils.d(TAG, "wbxml response: echo '%s' | base64 -d | wbxml", base64); 107 } 108 } 109 110 } 111