Index: admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteAdminCommand.java =================================================================== --- admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteAdminCommand.java (revision 44807) +++ admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteAdminCommand.java (working copy) @@ -665,8 +665,19 @@ logger.log(Level.FINER, "Following redirection to " + redirection); url = followRedirection(url, redirection); shouldTryCommandAgain = true; + /* + * Record that, during the retry of this request, we should + * use https. + */ shouldUseSecure = url.isSecure(); + /* + * Record that, if this is a metadata request, the real + * request should use https also. + */ + secure = true; + + /* * If we have been redirected to https then we can send * the credentials - if we have them - on the next * request we send because the request and therefore the Index: core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java =================================================================== --- core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java (revision 44807) +++ core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java (working copy) @@ -40,6 +40,7 @@ package com.sun.enterprise.v3.server; +import org.glassfish.api.deployment.archive.WritableArchive; import org.glassfish.deployment.versioning.VersioningUtils; import org.glassfish.deployment.versioning.VersioningSyntaxException; import java.io.BufferedInputStream; @@ -47,7 +48,6 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; -import java.util.Calendar; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -62,11 +62,11 @@ import org.jvnet.hk2.config.types.Property; import org.glassfish.api.admin.config.ApplicationName; import com.sun.enterprise.deploy.shared.ArchiveFactory; +import com.sun.enterprise.deploy.shared.FileArchive; import com.sun.enterprise.module.Module; import com.sun.enterprise.module.ModulesRegistry; import com.sun.enterprise.util.LocalStringManagerImpl; import org.glassfish.common.util.admin.ParameterMapExtractor; -import java.util.StringTokenizer; import com.sun.logging.LogDomains; import org.glassfish.api.*; @@ -1604,7 +1604,8 @@ } try { Long start = System.currentTimeMillis(); - archiveHandler.expand(archive, archiveFactory.createArchive(expansionDir), initial); + final WritableArchive expandedArchive = archiveFactory.createArchive(expansionDir); + archiveHandler.expand(archive, expandedArchive, initial); if (logger.isLoggable(Level.FINE)) { logger.fine("Deployment expansion took " + (System.currentTimeMillis() - start)); } @@ -1616,7 +1617,7 @@ logger.log(Level.SEVERE, localStrings.getLocalString("deploy.errorclosingarchive","Error while closing deployable artifact {0}", archive.getURI().getSchemeSpecificPart()),e); throw e; } - archive = archiveFactory.openArchive(expansionDir); + archive = (FileArchive) expandedArchive; initial.setSource(archive); } catch(IOException e) { logger.log(Level.SEVERE, localStrings.getLocalString("deploy.errorexpandingjar","Error while expanding archive file"),e); Index: core/kernel/src/main/java/com/sun/enterprise/v3/admin/AdminAdapter.java =================================================================== --- core/kernel/src/main/java/com/sun/enterprise/v3/admin/AdminAdapter.java (revision 44807) +++ core/kernel/src/main/java/com/sun/enterprise/v3/admin/AdminAdapter.java (working copy) @@ -48,13 +48,15 @@ import com.sun.enterprise.module.ModulesRegistry; import com.sun.enterprise.module.common_impl.LogHelper; import com.sun.enterprise.util.LocalStringManagerImpl; -import com.sun.enterprise.util.net.NetUtils; import com.sun.grizzly.tcp.Request; import com.sun.logging.LogDomains; import java.security.Principal; +import java.util.Iterator; +import java.util.zip.ZipEntry; import org.glassfish.admin.payload.PayloadImpl; import org.glassfish.api.ActionReport; import org.glassfish.api.admin.*; +import org.glassfish.api.admin.Payload.Part; import org.glassfish.api.event.Events; import org.glassfish.api.event.EventListener; import org.glassfish.api.container.Adapter; @@ -85,6 +87,7 @@ import java.util.List; import java.util.Properties; import java.util.concurrent.CountDownLatch; +import java.util.zip.ZipOutputStream; import org.glassfish.api.event.EventTypes; import org.glassfish.api.event.RestrictTo; @@ -208,6 +211,7 @@ } Payload.Outbound outboundPayload = PayloadImpl.Outbound.newInstance(); + PayloadBuffer payloadBuffer = null; try { if (!latch.await(20L, TimeUnit.SECONDS)) { @@ -215,9 +219,11 @@ report.setActionExitCode(ActionReport.ExitCode.FAILURE); report.setMessage("V3 cannot process this command at this time, please wait"); } else { + payloadBuffer = PayloadBuffer.newInstance(req.getContentType(), + req.getInputStream()); if (!authenticate(req, report, res)) return; - report = doCommand(requestURI, req, report, outboundPayload); + report = doCommand(requestURI, req, report, outboundPayload, payloadBuffer.bufferedPayload()); } } catch(InterruptedException e) { report.setActionExitCode(ActionReport.ExitCode.FAILURE); @@ -225,6 +231,11 @@ } catch (Exception e) { report.setActionExitCode(ActionReport.ExitCode.FAILURE); report.setMessage("Exception while processing command: " + e); + } finally { + if (payloadBuffer != null) { + payloadBuffer.close(); + payloadBuffer = null; + } } try { @@ -255,6 +266,76 @@ } } + private static class PayloadBuffer { + + private File tempFile = null; + private Payload.Inbound bufferedPayload = null; + private InputStream payloadInputStream = null; + + private static PayloadBuffer newInstance(final String payloadContentType, + final InputStream requestInputStream) throws IOException { + return new PayloadBuffer(payloadContentType, + PayloadImpl.Inbound.newInstance(payloadContentType, requestInputStream)); + } + + private PayloadBuffer(final String payloadContentType, final Payload.Inbound originalPayload) throws IOException { + if (originalPayload == null) { + return; + } + /* + * Empty out the incoming payload to a temp file to work around a Grizzly + * issue. Otherwise when we try to get the user principal (to use SSL + * cert authentication) we get into trouble with large payloads. + */ + tempFile = File.createTempFile("payload", ".tmp"); + tempFile.deleteOnExit(); + + final ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(tempFile))); + + for (Iterator it = originalPayload.parts(); it.hasNext();) { + final Part p = it.next(); + final ZipEntry entry = new ZipEntry(p.getName()); + entry.setExtra(extra(p.getProperties())); + zos.putNextEntry(entry); + p.copy(zos); + zos.closeEntry(); + } + zos.close(); + + /* + * Now create the inbound payload - based on the temp file - that we + * will reveal to the rest of the admin adapter. + */ + payloadInputStream = new BufferedInputStream(new FileInputStream(tempFile)); + bufferedPayload = PayloadImpl.Inbound.newInstance(payloadContentType, payloadInputStream); + } + + private Payload.Inbound bufferedPayload() { + return bufferedPayload; + } + + private byte[] extra(final Properties props) throws IOException { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + props.store(baos, null); + return baos.toByteArray(); + } + + private void close() { + if (payloadInputStream != null) { + try { + payloadInputStream.close(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + payloadInputStream = null; + } + if (tempFile != null) { + tempFile.delete(); + tempFile = null; + } + } + } + public AdminAccessController.Access authenticate(GrizzlyRequest req) throws Exception { final Request r = req.getRequest(); @@ -409,7 +490,8 @@ protected abstract boolean validatePrivacy(AdminCommand command); private ActionReport doCommand(String requestURI, GrizzlyRequest req, ActionReport report, - Payload.Outbound outboundPayload) { + Payload.Outbound outboundPayload, + Payload.Inbound inboundPayload) { if (!requestURI.startsWith(getContextRoot())) { String msg = adminStrings.getLocalString("adapter.panic", @@ -427,8 +509,6 @@ final ParameterMap parameters = extractParameters(req.getQueryString()); try { - Payload.Inbound inboundPayload = PayloadImpl.Inbound.newInstance( - req.getContentType(), req.getInputStream()); if (logger.isLoggable(Level.FINE)) { logger.fine("***** AdminAdapter "+req.getMethod()+" *****"); } Index: core/kernel/src/main/java/com/sun/enterprise/v3/admin/CommandRunnerImpl.java =================================================================== --- core/kernel/src/main/java/com/sun/enterprise/v3/admin/CommandRunnerImpl.java (revision 44807) +++ core/kernel/src/main/java/com/sun/enterprise/v3/admin/CommandRunnerImpl.java (working copy) @@ -1127,7 +1127,7 @@ } } catch (Exception ex) { - logger.severe(ex.getMessage()); + logger.log(Level.SEVERE, "", ex); report.setActionExitCode(ActionReport.ExitCode.FAILURE); report.setMessage(ex.getMessage()); report.setFailureCause(ex); Index: common/common-util/src/main/java/org/glassfish/admin/payload/PayloadFilesManager.java =================================================================== --- common/common-util/src/main/java/org/glassfish/admin/payload/PayloadFilesManager.java (revision 44807) +++ common/common-util/src/main/java/org/glassfish/admin/payload/PayloadFilesManager.java (working copy) @@ -562,7 +562,7 @@ } catch (Exception e) { reportExtractionFailure(part.getName(), e); - IOException ioe = new IOException(); + IOException ioe = new IOException(e.getMessage()); ioe.initCause(e); throw ioe; } finally { Index: common/common-util/src/main/java/org/glassfish/admin/payload/ZipPayloadImpl.java =================================================================== --- common/common-util/src/main/java/org/glassfish/admin/payload/ZipPayloadImpl.java (revision 44807) +++ common/common-util/src/main/java/org/glassfish/admin/payload/ZipPayloadImpl.java (working copy) @@ -285,6 +285,7 @@ extra.getContentType(), extra.getProperties(), Inbound.this); + isNextEntryPrefetched = false; return part; }