|
Play Framework/Scala example source code file (FixCertpathDebugLogging.scala)
The FixCertpathDebugLogging.scala Play Framework example source code/* * * * Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com> * */ package play.api.libs.ws.ssl.debug import java.security.AccessController import scala.util.control.NonFatal import sun.security.util.Debug /** * This singleton object turns on "certpath" debug logging (originally based off the "java.security.debug" debug flag), * and swaps out references to internal Sun JSSE classes to ensure that the new debug logging settings are honored, and * that debugging can be turned on dynamically, even after static class block initialization has been completed. It * does this using some {{sun.misc.Unsafe}} black magic. * * Note that currently the only functionality is to turn debug output ON, with the assumption that all output will * go to an appropriately configured logger that can ignore calls to it. There is no "off" method. */ object FixCertpathDebugLogging { val logger = org.slf4j.LoggerFactory.getLogger("play.api.libs.ws.ssl.debug.FixCertpathDebugLogging") class MonkeyPatchSunSecurityUtilDebugAction(val newDebug: Debug, val newOptions: String) extends FixLoggingAction { val logger = org.slf4j.LoggerFactory.getLogger("play.api.libs.ws.ssl.debug.FixCertpathDebugLogging.MonkeyPatchSunSecurityUtilDebugAction") val initialResource = "/sun/security/provider/certpath/Builder.class" val debugType = classOf[Debug] /** * Returns true if this class has an instance of {{Debug.getInstance("certpath")}}, false otherwise. * * @param className the name of the class. * @return true if this class should be returned in the set of findClasses, false otherwise. */ def isValidClass(className: String): Boolean = { if (className.startsWith("java.security.cert")) return true if (className.startsWith("sun.security.provider.certpath")) return true if (className.equals("sun.security.x509.InhibitAnyPolicyExtension")) return true false } /** * Returns true if the new options contains certpath, false otherwise. If it does not contain certpath, * then set the fields to null (which will disable logging). * * @return */ def isUsingDebug: Boolean = (newOptions != null) && newOptions.contains("certpath") def run() { System.setProperty("java.security.debug", newOptions) logger.debug(s"run: debugType = $debugType") val debugValue = if (isUsingDebug) newDebug else null var isPatched = false for ( debugClass <- findClasses; debugField <- debugClass.getDeclaredFields ) { if (isValidField(debugField, debugType)) { logger.debug(s"run: Patching $debugClass with $debugValue") monkeyPatchField(debugField, debugValue) isPatched = true } } // Add an assertion here in case the class location changes, so the tests fail... if (!isPatched) { throw new IllegalStateException("No debug classes found!") } // Switch out the args (for certpath loggers that AREN'T static and final) // This will result in those classes using the base Debug class which will write to System.out, but // I don't know how to switch out the Debug.getInstance method itself without using a java agent. val argsField = debugType.getDeclaredField("args") monkeyPatchField(argsField, newOptions) } } /** * Extends {{sun.security.util.Debug}} to delegate println to a logger. * * @param logger the logger which will receive debug calls. */ class SunSecurityUtilDebugLogger(logger: org.slf4j.Logger) extends sun.security.util.Debug { override def println(message: String) { if (logger.isDebugEnabled) { logger.debug(message) } } override def println() { if (logger.isDebugEnabled) { logger.debug("") } } } def apply(newOptions: String, debugOption: Option[Debug] = None) { logger.trace(s"apply: newOptions = $newOptions, debugOption = $debugOption") try { val newDebug = debugOption match { case Some(d) => d case None => new Debug() } val action = new MonkeyPatchSunSecurityUtilDebugAction(newDebug, newOptions) AccessController.doPrivileged(action) } catch { case NonFatal(e) => throw new IllegalStateException("CertificateDebug configuration error", e) } } } Other Play Framework source code examplesHere is a short list of links related to this Play Framework FixCertpathDebugLogging.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.