use of okhttp3.logging.HttpLoggingInterceptor.Level in project okhttp by square.
the class CallTest method asyncLeakedResponseBodyLogsStackTrace.
@Test
public void asyncLeakedResponseBodyLogsStackTrace() throws Exception {
server.enqueue(new MockResponse().setBody("This gets leaked."));
client = defaultClient().newBuilder().connectionPool(new ConnectionPool(0, 10, TimeUnit.MILLISECONDS)).build();
Request request = new Request.Builder().url(server.url("/")).build();
Level original = logger.getLevel();
logger.setLevel(Level.FINE);
logHandler.setFormatter(new SimpleFormatter());
try {
final CountDownLatch latch = new CountDownLatch(1);
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
fail();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// Ignore the response so it gets leaked then GC'd.
latch.countDown();
}
});
latch.await();
// There's some flakiness when triggering a GC for objects in a separate thread. Adding a
// small delay appears to ensure the objects will get GC'd.
Thread.sleep(200);
awaitGarbageCollection();
String message = logHandler.take();
assertTrue(message.contains("A connection to " + server.url("/") + " was leaked." + " Did you forget to close a response body?"));
assertTrue(message.contains("okhttp3.RealCall.enqueue("));
assertTrue(message.contains("okhttp3.CallTest.asyncLeakedResponseBodyLogsStackTrace("));
} finally {
logger.setLevel(original);
}
}
use of okhttp3.logging.HttpLoggingInterceptor.Level in project okhttp by square.
the class CallTest method leakedResponseBodyLogsStackTrace.
@Test
public void leakedResponseBodyLogsStackTrace() throws Exception {
server.enqueue(new MockResponse().setBody("This gets leaked."));
client = defaultClient().newBuilder().connectionPool(new ConnectionPool(0, 10, TimeUnit.MILLISECONDS)).build();
Request request = new Request.Builder().url(server.url("/")).build();
Level original = logger.getLevel();
logger.setLevel(Level.FINE);
logHandler.setFormatter(new SimpleFormatter());
try {
// Ignore the response so it gets leaked then GC'd.
client.newCall(request).execute();
awaitGarbageCollection();
String message = logHandler.take();
assertTrue(message.contains("A connection to " + server.url("/") + " was leaked." + " Did you forget to close a response body?"));
assertTrue(message.contains("okhttp3.RealCall.execute("));
assertTrue(message.contains("okhttp3.CallTest.leakedResponseBodyLogsStackTrace("));
} finally {
logger.setLevel(original);
}
}
use of okhttp3.logging.HttpLoggingInterceptor.Level in project nifi by apache.
the class InvokeHTTP method onTrigger.
@Override
public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
OkHttpClient okHttpClient = okHttpClientAtomicReference.get();
FlowFile requestFlowFile = session.get();
// Checking to see if the property to put the body of the response in an attribute was set
boolean putToAttribute = context.getProperty(PROP_PUT_OUTPUT_IN_ATTRIBUTE).isSet();
if (requestFlowFile == null) {
if (context.hasNonLoopConnection()) {
return;
}
String request = context.getProperty(PROP_METHOD).evaluateAttributeExpressions().getValue().toUpperCase();
if ("POST".equals(request) || "PUT".equals(request) || "PATCH".equals(request)) {
return;
} else if (putToAttribute) {
requestFlowFile = session.create();
}
}
// Setting some initial variables
final int maxAttributeSize = context.getProperty(PROP_PUT_ATTRIBUTE_MAX_LENGTH).asInteger();
final ComponentLog logger = getLogger();
// log ETag cache metrics
final boolean eTagEnabled = context.getProperty(PROP_USE_ETAG).asBoolean();
if (eTagEnabled && logger.isDebugEnabled()) {
final Cache cache = okHttpClient.cache();
logger.debug("OkHttp ETag cache metrics :: Request Count: {} | Network Count: {} | Hit Count: {}", new Object[] { cache.requestCount(), cache.networkCount(), cache.hitCount() });
}
// Every request/response cycle has a unique transaction id which will be stored as a flowfile attribute.
final UUID txId = UUID.randomUUID();
FlowFile responseFlowFile = null;
try {
// read the url property from the context
final String urlstr = trimToEmpty(context.getProperty(PROP_URL).evaluateAttributeExpressions(requestFlowFile).getValue());
final URL url = new URL(urlstr);
Request httpRequest = configureRequest(context, session, requestFlowFile, url);
// log request
logRequest(logger, httpRequest);
// emit send provenance event if successfully sent to the server
if (httpRequest.body() != null) {
session.getProvenanceReporter().send(requestFlowFile, url.toExternalForm(), true);
}
final long startNanos = System.nanoTime();
Response responseHttp = okHttpClient.newCall(httpRequest).execute();
// output the raw response headers (DEBUG level only)
logResponse(logger, url, responseHttp);
// store the status code and message
int statusCode = responseHttp.code();
String statusMessage = responseHttp.message();
if (statusCode == 0) {
throw new IllegalStateException("Status code unknown, connection hasn't been attempted.");
}
// Create a map of the status attributes that are always written to the request and response FlowFiles
Map<String, String> statusAttributes = new HashMap<>();
statusAttributes.put(STATUS_CODE, String.valueOf(statusCode));
statusAttributes.put(STATUS_MESSAGE, statusMessage);
statusAttributes.put(REQUEST_URL, url.toExternalForm());
statusAttributes.put(TRANSACTION_ID, txId.toString());
if (requestFlowFile != null) {
requestFlowFile = session.putAllAttributes(requestFlowFile, statusAttributes);
}
// If the property to add the response headers to the request flowfile is true then add them
if (context.getProperty(PROP_ADD_HEADERS_TO_REQUEST).asBoolean() && requestFlowFile != null) {
// write the response headers as attributes
// this will overwrite any existing flowfile attributes
requestFlowFile = session.putAllAttributes(requestFlowFile, convertAttributesFromHeaders(url, responseHttp));
}
boolean outputBodyToRequestAttribute = (!isSuccess(statusCode) || putToAttribute) && requestFlowFile != null;
boolean outputBodyToResponseContent = (isSuccess(statusCode) && !putToAttribute) || context.getProperty(PROP_OUTPUT_RESPONSE_REGARDLESS).asBoolean();
ResponseBody responseBody = responseHttp.body();
boolean bodyExists = responseBody != null;
InputStream responseBodyStream = null;
SoftLimitBoundedByteArrayOutputStream outputStreamToRequestAttribute = null;
TeeInputStream teeInputStream = null;
try {
responseBodyStream = bodyExists ? responseBody.byteStream() : null;
if (responseBodyStream != null && outputBodyToRequestAttribute && outputBodyToResponseContent) {
outputStreamToRequestAttribute = new SoftLimitBoundedByteArrayOutputStream(maxAttributeSize);
teeInputStream = new TeeInputStream(responseBodyStream, outputStreamToRequestAttribute);
}
if (outputBodyToResponseContent) {
// clone the flowfile to capture the response
if (requestFlowFile != null) {
responseFlowFile = session.create(requestFlowFile);
} else {
responseFlowFile = session.create();
}
// write attributes to response flowfile
responseFlowFile = session.putAllAttributes(responseFlowFile, statusAttributes);
// write the response headers as attributes
// this will overwrite any existing flowfile attributes
responseFlowFile = session.putAllAttributes(responseFlowFile, convertAttributesFromHeaders(url, responseHttp));
// can potentially be null in edge cases
if (bodyExists) {
// write content type attribute to response flowfile if it is available
if (responseBody.contentType() != null) {
responseFlowFile = session.putAttribute(responseFlowFile, CoreAttributes.MIME_TYPE.key(), responseBody.contentType().toString());
}
if (teeInputStream != null) {
responseFlowFile = session.importFrom(teeInputStream, responseFlowFile);
} else {
responseFlowFile = session.importFrom(responseBodyStream, responseFlowFile);
}
// emit provenance event
final long millis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos);
if (requestFlowFile != null) {
session.getProvenanceReporter().fetch(responseFlowFile, url.toExternalForm(), millis);
} else {
session.getProvenanceReporter().receive(responseFlowFile, url.toExternalForm(), millis);
}
}
}
// if not successful and request flowfile is not null, store the response body into a flowfile attribute
if (outputBodyToRequestAttribute && bodyExists) {
String attributeKey = context.getProperty(PROP_PUT_OUTPUT_IN_ATTRIBUTE).evaluateAttributeExpressions(requestFlowFile).getValue();
if (attributeKey == null) {
attributeKey = RESPONSE_BODY;
}
byte[] outputBuffer;
int size;
if (outputStreamToRequestAttribute != null) {
outputBuffer = outputStreamToRequestAttribute.getBuffer();
size = outputStreamToRequestAttribute.size();
} else {
outputBuffer = new byte[maxAttributeSize];
size = StreamUtils.fillBuffer(responseBodyStream, outputBuffer, false);
}
String bodyString = new String(outputBuffer, 0, size, getCharsetFromMediaType(responseBody.contentType()));
requestFlowFile = session.putAttribute(requestFlowFile, attributeKey, bodyString);
final long millis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos);
session.getProvenanceReporter().modifyAttributes(requestFlowFile, "The " + attributeKey + " has been added. The value of which is the body of a http call to " + url.toExternalForm() + ". It took " + millis + "millis,");
}
} finally {
if (outputStreamToRequestAttribute != null) {
outputStreamToRequestAttribute.close();
outputStreamToRequestAttribute = null;
}
if (teeInputStream != null) {
teeInputStream.close();
teeInputStream = null;
} else if (responseBodyStream != null) {
responseBodyStream.close();
responseBodyStream = null;
}
}
route(requestFlowFile, responseFlowFile, session, context, statusCode);
} catch (final Exception e) {
// penalize or yield
if (requestFlowFile != null) {
logger.error("Routing to {} due to exception: {}", new Object[] { REL_FAILURE.getName(), e }, e);
requestFlowFile = session.penalize(requestFlowFile);
requestFlowFile = session.putAttribute(requestFlowFile, EXCEPTION_CLASS, e.getClass().getName());
requestFlowFile = session.putAttribute(requestFlowFile, EXCEPTION_MESSAGE, e.getMessage());
// transfer original to failure
session.transfer(requestFlowFile, REL_FAILURE);
} else {
logger.error("Yielding processor due to exception encountered as a source processor: {}", e);
context.yield();
}
// cleanup response flowfile, if applicable
try {
if (responseFlowFile != null) {
session.remove(responseFlowFile);
}
} catch (final Exception e1) {
logger.error("Could not cleanup response flowfile due to exception: {}", new Object[] { e1 }, e1);
}
}
}
use of okhttp3.logging.HttpLoggingInterceptor.Level in project ocreader by schaal.
the class API method login.
public static void login(final Context context, final HttpUrl baseUrl, final String username, final String password, final APICallback<Status, LoginError> loginCallback) {
final HttpManager httpManager = new HttpManager(username, password, baseUrl);
final HttpUrl resolvedBaseUrl = baseUrl.resolve("");
if (resolvedBaseUrl == null) {
loginCallback.onFailure(new LoginError("Couldn't parse URL"));
return;
}
final Moshi moshi = new Moshi.Builder().build();
final JsonAdapter<NewsError> errorJsonAdapter = moshi.adapter(NewsError.class);
final Retrofit retrofit = new Retrofit.Builder().baseUrl(resolvedBaseUrl).client(httpManager.getClient()).addConverterFactory(MoshiConverterFactory.create(moshi)).build();
final CommonAPI commonAPI = retrofit.create(CommonAPI.class);
commonAPI.apiLevels().enqueue(new Callback<APILevels>() {
@Override
public void onResponse(@NonNull Call<APILevels> call, @NonNull Response<APILevels> response) {
if (response.isSuccessful()) {
loginInstance = null;
final APILevels apiLevels = response.body();
final Level apiLevel = apiLevels != null ? apiLevels.highestSupportedApi() : null;
loginInstance = Level.getAPI(context, apiLevel);
if (apiLevel == null) {
loginCallback.onFailure(new LoginError(context.getString(R.string.error_not_compatible)));
} else {
loginInstance.setupApi(httpManager);
loginInstance.metaData(new Callback<Status>() {
@Override
public void onResponse(@NonNull Call<Status> call, @NonNull Response<Status> response) {
if (response.isSuccessful()) {
final Status status = response.body();
final Version version = status != null ? status.getVersion() : null;
if (version != null && MIN_VERSION.lessThanOrEqualTo(version)) {
PreferenceManager.getDefaultSharedPreferences(context).edit().putString(Preferences.USERNAME.getKey(), username).putString(Preferences.PASSWORD.getKey(), password).putString(Preferences.URL.getKey(), resolvedBaseUrl.toString()).putString(Preferences.SYS_DETECTED_API_LEVEL.getKey(), apiLevel.getLevel()).apply();
instance = loginInstance;
loginInstance = null;
loginCallback.onSuccess(status);
} else {
if (version != null) {
Log.d(TAG, String.format("Nextcloud News version is less than minimally supported version: %s < %s", version.toString(), MIN_VERSION.toString()));
loginCallback.onFailure(new LoginError(context.getString(R.string.ncnews_too_old, MIN_VERSION.toString())));
} else {
Log.d(TAG, "Couldn't parse Nextcloud News version");
loginCallback.onFailure(new LoginError(context.getString(R.string.failed_detect_nc_version)));
}
}
} else {
String message = getErrorMessage(errorJsonAdapter, response);
Log.d(TAG, "Metadata call failed with error: " + message);
loginCallback.onFailure(LoginError.getError(context, response.code(), message));
}
}
@Override
public void onFailure(@NonNull Call<Status> call, @NonNull Throwable t) {
Log.e(TAG, "Failed to log in", t);
loginCallback.onFailure(LoginError.getError(context, t));
}
});
}
} else {
Log.d(TAG, "API level call failed with error: " + response.code() + " " + getErrorMessage(errorJsonAdapter, response));
// Either nextcloud news is not installed or version prior 8.8.0
loginCallback.onFailure(LoginError.getError(context, response.code(), context.getString(R.string.ncnews_too_old, MIN_VERSION.toString())));
}
}
@Override
public void onFailure(@NonNull Call<APILevels> call, @NonNull Throwable t) {
Log.e(TAG, "Failed to log in", t);
loginCallback.onFailure(LoginError.getError(context, t));
}
});
}
use of okhttp3.logging.HttpLoggingInterceptor.Level in project MVPFrames by RockyQu.
the class LoggingInterceptor method intercept.
@Override
public Response intercept(Chain chain) throws IOException {
Level level = this.level;
Request request = chain.request();
if (level == Level.NONE) {
return chain.proceed(request);
}
RequestBody requestBody = request.body();
boolean hasRequestBody = requestBody != null;
// 请求地址
Connection connection = chain.connection();
Protocol protocol = connection != null ? connection.protocol() : Protocol.HTTP_1_1;
String requestStartMessage = "--> " + request.method() + ' ' + request.url() + ' ' + protocol;
if (hasRequestBody) {
requestStartMessage += " (" + requestBody.contentLength() + "-byte body)";
}
log(requestStartMessage);
// Content-Type
if (hasRequestBody) {
if (requestBody.contentType() != null) {
log("Content-Type: " + requestBody.contentType());
}
if (requestBody.contentLength() != -1) {
log("Content-Length: " + requestBody.contentLength());
}
}
// 拼装请求参数
Headers headers = request.headers();
for (int i = 0, count = headers.size(); i < count; i++) {
String name = headers.name(i);
if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
log(name + ": " + headers.value(i));
}
}
// Request结束
if (!hasRequestBody) {
log("--> END " + request.method());
} else if (bodyEncoded(request.headers())) {
log("--> END " + request.method() + " (encoded body omitted)");
} else {
Buffer buffer = new Buffer();
requestBody.writeTo(buffer);
Charset charset = UTF8;
MediaType contentType = requestBody.contentType();
if (contentType != null) {
charset = contentType.charset(UTF8);
}
if (isPlaintext(buffer)) {
log(buffer.readString(charset));
log("--> END " + request.method() + " (" + requestBody.contentLength() + "-byte body)");
} else {
log("--> END " + request.method() + " (binary " + requestBody.contentLength() + "-byte body omitted)");
}
}
// Response开始
long startNs = System.nanoTime();
Response response;
try {
response = chain.proceed(request);
} catch (Exception e) {
log("<-- HTTP FAILED: " + e);
throw e;
}
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
ResponseBody responseBody = response.body();
long contentLength = responseBody.contentLength();
String bodySize = contentLength != -1 ? contentLength + "-byte" : "unknown-length";
log("<-- " + response.code() + ' ' + response.message() + ' ' + response.request().url() + " (" + tookMs + "ms" + (", " + bodySize + " body") + ')');
headers = response.headers();
for (int i = 0, count = headers.size(); i < count; i++) {
log(headers.name(i) + ": " + headers.value(i));
}
if (!HttpHeaders.hasBody(response)) {
log("<-- END HTTP");
} else if (bodyEncoded(response.headers())) {
log("<-- END HTTP (encoded body omitted)");
} else {
BufferedSource source = responseBody.source();
// Buffer the entire body.
source.request(Long.MAX_VALUE);
Buffer buffer = source.buffer();
Charset charset = UTF8;
MediaType contentType = responseBody.contentType();
if (contentType != null) {
try {
charset = contentType.charset(UTF8);
} catch (UnsupportedCharsetException e) {
log("Couldn't decode the response body; charset is likely malformed.");
log("<-- END HTTP");
return response;
}
}
if (!isPlaintext(buffer)) {
log("<-- END HTTP (binary " + buffer.size() + "-byte body omitted)");
return response;
}
if (contentLength != 0) {
log(buffer.clone().readString(charset));
}
log("<-- END HTTP (" + buffer.size() + "-byte body)");
}
return response;
}
Aggregations