test.java 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package com.r0ysue.learnokhttp;
  2. /*
  3. * Copyright (C) 2015 Square, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. import android.util.Log;
  18. import java.io.EOFException;
  19. import java.io.IOException;
  20. import java.nio.charset.Charset;
  21. import java.util.concurrent.TimeUnit;
  22. import okhttp3.Connection;
  23. import okhttp3.Headers;
  24. import okhttp3.Interceptor;
  25. import okhttp3.MediaType;
  26. import okhttp3.Request;
  27. import okhttp3.RequestBody;
  28. import okhttp3.Response;
  29. import okhttp3.ResponseBody;
  30. import okhttp3.internal.http.HttpHeaders;
  31. import okio.Buffer;
  32. import okio.BufferedSource;
  33. import okio.GzipSource;
  34. public final class okhttp3Logging implements Interceptor {
  35. private static final String TAG = "okhttpGET";
  36. private static final Charset UTF8 = Charset.forName("UTF-8");
  37. @Override public Response intercept(Chain chain) throws IOException {
  38. Request request = chain.request();
  39. RequestBody requestBody = request.body();
  40. boolean hasRequestBody = requestBody != null;
  41. Connection connection = chain.connection();
  42. String requestStartMessage = "--> "
  43. + request.method()
  44. + ' ' + request.url();
  45. Log.e(TAG, requestStartMessage);
  46. if (hasRequestBody) {
  47. // Request body headers are only present when installed as a network interceptor. Force
  48. // them to be included (when available) so there values are known.
  49. if (requestBody.contentType() != null) {
  50. Log.e(TAG, "Content-Type: " + requestBody.contentType());
  51. }
  52. if (requestBody.contentLength() != -1) {
  53. Log.e(TAG, "Content-Length: " + requestBody.contentLength());
  54. }
  55. }
  56. Headers headers = request.headers();
  57. for (int i = 0, count = headers.size(); i < count; i++) {
  58. String name = headers.name(i);
  59. // Skip headers from the request body as they are explicitly logged above.
  60. if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
  61. Log.e(TAG, name + ": " + headers.value(i));
  62. }
  63. }
  64. if (!hasRequestBody) {
  65. Log.e(TAG, "--> END " + request.method());
  66. } else if (bodyHasUnknownEncoding(request.headers())) {
  67. Log.e(TAG, "--> END " + request.method() + " (encoded body omitted)");
  68. } else {
  69. Buffer buffer = new Buffer();
  70. requestBody.writeTo(buffer);
  71. Charset charset = UTF8;
  72. MediaType contentType = requestBody.contentType();
  73. if (contentType != null) {
  74. charset = contentType.charset(UTF8);
  75. }
  76. Log.e(TAG, "");
  77. if (isPlaintext(buffer)) {
  78. Log.e(TAG, buffer.readString(charset));
  79. Log.e(TAG, "--> END " + request.method()
  80. + " (" + requestBody.contentLength() + "-byte body)");
  81. } else {
  82. Log.e(TAG, "--> END " + request.method() + " (binary "
  83. + requestBody.contentLength() + "-byte body omitted)");
  84. }
  85. }
  86. long startNs = System.nanoTime();
  87. Response response;
  88. try {
  89. response = chain.proceed(request);
  90. } catch (Exception e) {
  91. Log.e(TAG, "<-- HTTP FAILED: " + e);
  92. throw e;
  93. }
  94. long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
  95. ResponseBody responseBody = response.body();
  96. long contentLength = responseBody.contentLength();
  97. String bodySize = contentLength != -1 ? contentLength + "-byte" : "unknown-length";
  98. Log.e(TAG, "<-- "
  99. + response.code()
  100. + (response.message().isEmpty() ? "" : ' ' + response.message())
  101. + ' ' + response.request().url()
  102. + " (" + tookMs + "ms" + (", " + bodySize + " body:" + "") + ')');
  103. Headers myheaders = response.headers();
  104. for (int i = 0, count = myheaders.size(); i < count; i++) {
  105. Log.e(TAG, myheaders.name(i) + ": " + myheaders.value(i));
  106. }
  107. if (!HttpHeaders.hasBody(response)) {
  108. Log.e(TAG, "<-- END HTTP");
  109. } else if (bodyHasUnknownEncoding(response.headers())) {
  110. Log.e(TAG, "<-- END HTTP (encoded body omitted)");
  111. } else {
  112. BufferedSource source = responseBody.source();
  113. source.request(Long.MAX_VALUE); // Buffer the entire body.
  114. Buffer buffer = source.buffer();
  115. Long gzippedLength = null;
  116. if ("gzip".equalsIgnoreCase(myheaders.get("Content-Encoding"))) {
  117. gzippedLength = buffer.size();
  118. GzipSource gzippedResponseBody = null;
  119. try {
  120. gzippedResponseBody = new GzipSource(buffer.clone());
  121. buffer = new Buffer();
  122. buffer.writeAll(gzippedResponseBody);
  123. } finally {
  124. if (gzippedResponseBody != null) {
  125. gzippedResponseBody.close();
  126. }
  127. }
  128. }
  129. Charset charset = UTF8;
  130. MediaType contentType = responseBody.contentType();
  131. if (contentType != null) {
  132. charset = contentType.charset(UTF8);
  133. }
  134. if (!isPlaintext(buffer)) {
  135. Log.e(TAG, "");
  136. Log.e(TAG, "<-- END HTTP (binary " + buffer.size() + "-byte body omitted)");
  137. return response;
  138. }
  139. if (contentLength != 0) {
  140. Log.e(TAG, "");
  141. Log.e(TAG, buffer.clone().readString(charset));
  142. }
  143. if (gzippedLength != null) {
  144. Log.e(TAG, "<-- END HTTP (" + buffer.size() + "-byte, "
  145. + gzippedLength + "-gzipped-byte body)");
  146. } else {
  147. Log.e(TAG, "<-- END HTTP (" + buffer.size() + "-byte body)");
  148. }
  149. }
  150. return response;
  151. }
  152. /**
  153. * Returns true if the body in question probably contains human readable text. Uses a small sample
  154. * of code points to detect unicode control characters commonly used in binary file signatures.
  155. */
  156. static boolean isPlaintext(Buffer buffer) {
  157. try {
  158. Buffer prefix = new Buffer();
  159. long byteCount = buffer.size() < 64 ? buffer.size() : 64;
  160. buffer.copyTo(prefix, 0, byteCount);
  161. for (int i = 0; i < 16; i++) {
  162. if (prefix.exhausted()) {
  163. break;
  164. }
  165. int codePoint = prefix.readUtf8CodePoint();
  166. if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) {
  167. return false;
  168. }
  169. }
  170. return true;
  171. } catch (EOFException e) {
  172. return false; // Truncated UTF-8 sequence.
  173. }
  174. }
  175. private boolean bodyHasUnknownEncoding(Headers myheaders) {
  176. String contentEncoding = myheaders.get("Content-Encoding");
  177. return contentEncoding != null
  178. && !contentEncoding.equalsIgnoreCase("identity")
  179. && !contentEncoding.equalsIgnoreCase("gzip");
  180. }
  181. }