Example usage for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED

List of usage examples for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED

Introduction

In this page you can find the example usage for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED.

Prototype

int SC_NOT_MODIFIED

To view the source code for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED.

Click Source Link

Document

Status code (304) indicating that a conditional GET operation found that the resource was available and not modified.

Usage

From source file:org.openlaszlo.servlets.responders.ResponderCompile.java

/**
 * @return File name for temporary LZX file that is the
 *         result of this http pre-processing; null for a bad request
 * @param req request// w w w  .  j a v a  2s . co  m
 * @param fileName file name associated with request
 */
private String doPreProcessing(HttpServletRequest req, String fileName) throws IOException {
    // Do an http request for this and see what we get back.
    //
    StringBuffer s = req.getRequestURL();
    int len = s.length();
    // Remove the .lzx from the end of the URL
    if (len <= 4) {
        return null;
    }
    s.delete(len - 4, len);

    // FIXME [2002-12-15 bloch] does any/all of this need to be synchronized on session?

    // First get the temporary file name for this session
    HttpSession session = req.getSession();
    String sid = session.getId();
    String tempFileName = getTempFileName(fileName, sid);
    File tempFile = new File(tempFileName);

    tempFile.deleteOnExit();

    // Now pre-process the request and copy the data to
    // the temporary file that is unique to this session

    // FIXME: query string processing

    String surl = s.toString();

    URL url = new URL(surl);
    mLogger.debug(
            /* (non-Javadoc)
             * @i18n.test
             * @org-mes="Preprocessing request at " + p[0]
             */
            org.openlaszlo.i18n.LaszloMessages.getMessage(ResponderCompile.class.getName(), "051018-263",
                    new Object[] { surl }));
    GetMethod getRequest = new LZGetMethod();
    getRequest.setPath(url.getPath());
    //getRequest.setQueryString(url.getQuery());
    getRequest.setQueryString(req.getQueryString());

    // Copy headers to request
    LZHttpUtils.proxyRequestHeaders(req, getRequest);
    // Mention the last modified time, if the file exists
    if (tempFile.exists()) {
        long lastModified = tempFile.lastModified();
        getRequest.addRequestHeader("If-Modified-Since", LZHttpUtils.getDateString(lastModified));
    } else {
        // Otherwise, create a listener that will clean up the tempfile
        // Note: web server administrators must make sure that their servers are killed
        // gracefully or temporary files will not be handled by the LZBindingListener.
        // Add a binding listener for this session that
        // will remove our temporary files
        LZBindingListener listener = (LZBindingListener) session.getAttribute("tmpl");
        if (listener == null) {
            listener = new LZBindingListener(tempFileName);
            session.setAttribute("tmpl", listener);
        } else {
            listener.addTempFile(tempFileName);
        }
    }

    HostConfiguration hostConfig = new HostConfiguration();
    hostConfig.setHost(url.getHost(), url.getPort(), url.getProtocol());

    HttpClient htc = new HttpClient();
    htc.setHostConfiguration(hostConfig);

    int rc = htc.executeMethod(getRequest);
    mLogger.debug("Response Status: " + rc);
    if (rc >= 400) {
        // respondWithError(req, res, "HTTP Status code: " + rc + " for url " + surl, rc);
        return null;
    }
    if (rc != HttpServletResponse.SC_NOT_MODIFIED) {
        FileOutputStream output = new FileOutputStream(tempFile);
        try {
            // FIXME:[2002-12-17 bloch] verify that the response body is XML
            FileUtils.sendToStream(getRequest.getResponseBodyAsStream(), output);
            // TODO: [2002-12-15 bloch] What to do with response headers?
        } catch (FileUtils.StreamWritingException e) {
            mLogger.warn(
                    /* (non-Javadoc)
                     * @i18n.test
                     * @org-mes="StreamWritingException while sending error: " + p[0]
                     */
                    org.openlaszlo.i18n.LaszloMessages.getMessage(ResponderCompile.class.getName(),
                            "051018-313", new Object[] { e.getMessage() }));
        } finally {
            FileUtils.close(output);
        }
    }

    return tempFileName;
}

From source file:org.alfresco.module.vti.handler.alfresco.AlfrescoMethodHandler.java

/**
 * @see org.alfresco.module.vti.handler.MethodHandler#existResource(HttpServletRequest, HttpServletResponse)
 *///from w w w.  j a  v a  2  s  .c  o m
public boolean existResource(HttpServletRequest request, HttpServletResponse response) {
    String decodedUrl = URLDecoder.decode(request.getRequestURI());
    if (decodedUrl.length() > getPathHelper().getAlfrescoContext().length()) {
        decodedUrl = decodedUrl.substring(getPathHelper().getAlfrescoContext().length() + 1);
    }

    FileInfo resourceFileInfo = getPathHelper().resolvePathFileInfo(decodedUrl);

    // ALF-17662, hidden documents are the same as nonexistent
    if (resourceFileInfo == null || getFileFolderService().isHidden(resourceFileInfo.getNodeRef())) {
        try {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            response.getOutputStream().write("NOT FOUND".getBytes());
            response.getOutputStream().close();
        } catch (Exception e) {
            if (logger.isDebugEnabled()) {
                logger.debug("An exception occurred while writing the response.", e);
            }
        }
    } else {
        if (!resourceFileInfo.isFolder()) {
            NodeRef resourceNodeRef = resourceFileInfo.getNodeRef();
            String guid = resourceNodeRef.getId().toUpperCase();

            NodeRef workingCopyNodeRef = getCheckOutCheckInService().getWorkingCopy(resourceNodeRef);

            // original node props
            Map<QName, Serializable> props = getNodeService().getProperties(resourceNodeRef);
            // original node reader
            ContentReader contentReader = getFileFolderService().getReader(resourceNodeRef);

            if (workingCopyNodeRef != null) {
                String workingCopyOwner = getNodeService()
                        .getProperty(workingCopyNodeRef, ContentModel.PROP_WORKING_COPY_OWNER).toString();
                if (workingCopyOwner.equals(getUserName())) {
                    // allow to see changes in document after it was checked out (only for checked out owner)
                    contentReader = getFileFolderService().getReader(workingCopyNodeRef);

                    // working copy props
                    props = getNodeService().getProperties(workingCopyNodeRef);
                }
            }

            Date lastModified = (Date) props.get(ContentModel.PROP_MODIFIED);

            // Office 2008/2011 for Mac requires following headers
            response.setHeader("Last-Modified", VtiUtils.formatBrowserDate(lastModified));
            String etag = VtiUtils.constructETag(guid, lastModified);
            response.setHeader("ETag", etag);
            response.setHeader("ResourceTag", VtiUtils.constructResourceTag(guid, lastModified));

            boolean writeContent = true;

            if ("HEAD".equals(request.getMethod())) {
                writeContent = false;
            }

            String ifNonMatch = request.getHeader("If-None-Match");

            if (ifNonMatch != null && ifNonMatch.equals(etag)) {
                writeContent = false;
                response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            }

            if (writeContent) {
                ContentData content = (ContentData) props.get(ContentModel.PROP_CONTENT);

                response.setContentType(content.getMimetype());

                try {
                    FileCopyUtils.copy(contentReader.getContentInputStream(), response.getOutputStream());
                } catch (Exception e) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Exception while copying content stream to response ", e);
                    }
                }
            }
        }
    }
    return resourceFileInfo != null;
}

From source file:org.apache.ranger.biz.AssetMgr.java

public String getLatestRepoPolicy(VXAsset xAsset, List<VXResource> xResourceList, Long updatedTime,
        X509Certificate[] certchain, boolean httpEnabled, String epoch, String ipAddress, boolean isSecure,
        String count, String agentId) {
    if (xAsset == null) {
        logger.error("Requested repository not found");
        throw restErrorUtil.createRESTException("No Data Found.", MessageEnums.DATA_NOT_FOUND);
    }//from w  w w  . ja  v  a 2 s . c om
    if (xResourceList == null) {
        logger.error("ResourceList is found");
        throw restErrorUtil.createRESTException("No Data Found.", MessageEnums.DATA_NOT_FOUND);
    }
    if (xAsset.getActiveStatus() == RangerCommonEnums.ACT_STATUS_DISABLED) {
        logger.error("Requested repository is disabled");
        throw restErrorUtil.createRESTException("Unauthorized access.", MessageEnums.OPER_NO_EXPORT);
    }

    HashMap<String, Object> updatedRepo = new HashMap<String, Object>();
    updatedRepo.put("repository_name", xAsset.getName());

    XXPolicyExportAudit policyExportAudit = new XXPolicyExportAudit();
    policyExportAudit.setRepositoryName(xAsset.getName());

    if (agentId != null && !agentId.isEmpty()) {
        policyExportAudit.setAgentId(agentId);
    }

    policyExportAudit.setClientIP(ipAddress);

    if (epoch != null && !epoch.trim().isEmpty() && !epoch.equalsIgnoreCase("null")) {
        policyExportAudit.setRequestedEpoch(Long.parseLong(epoch));
    } else {
        policyExportAudit.setRequestedEpoch(0L);
    }

    if (!httpEnabled) {
        if (!isSecure) {
            policyExportAudit.setHttpRetCode(HttpServletResponse.SC_BAD_REQUEST);
            createPolicyAudit(policyExportAudit);

            throw restErrorUtil.createRESTException("Unauthorized access -" + " only https allowed",
                    MessageEnums.OPER_NOT_ALLOWED_FOR_ENTITY);
        }

        if (certchain == null || certchain.length == 0) {

            policyExportAudit.setHttpRetCode(HttpServletResponse.SC_BAD_REQUEST);
            createPolicyAudit(policyExportAudit);

            throw restErrorUtil.createRESTException(
                    "Unauthorized access -" + " unable to get client certificate",
                    MessageEnums.OPER_NOT_ALLOWED_FOR_ENTITY);
        }
    }

    Long policyCount = restErrorUtil.parseLong(count, "Invalid value for " + "policyCount",
            MessageEnums.INVALID_INPUT_DATA, null, "policyCount");

    String commonName = null;

    if (certchain != null) {
        X509Certificate clientCert = certchain[0];
        String dn = clientCert.getSubjectX500Principal().getName();

        try {
            LdapName ln = new LdapName(dn);
            for (Rdn rdn : ln.getRdns()) {
                if (rdn.getType().equalsIgnoreCase("CN")) {
                    commonName = rdn.getValue() + "";
                    break;
                }
            }
            if (commonName == null) {
                policyExportAudit.setHttpRetCode(HttpServletResponse.SC_BAD_REQUEST);
                createPolicyAudit(policyExportAudit);

                throw restErrorUtil.createRESTException(
                        "Unauthorized access - Unable to find Common Name from [" + dn + "]",
                        MessageEnums.OPER_NOT_ALLOWED_FOR_ENTITY);
            }
        } catch (InvalidNameException e) {
            policyExportAudit.setHttpRetCode(HttpServletResponse.SC_BAD_REQUEST);
            createPolicyAudit(policyExportAudit);

            logger.error("Invalid Common Name.", e);
            throw restErrorUtil.createRESTException("Unauthorized access - Invalid Common Name",
                    MessageEnums.OPER_NOT_ALLOWED_FOR_ENTITY);
        }
    }

    if (policyCount == null) {
        policyCount = 0L;
    }

    if (commonName != null) {
        String config = xAsset.getConfig();
        Map<String, String> configMap = jsonUtil.jsonToMap(config);
        String cnFromConfig = configMap.get("commonNameForCertificate");

        if (cnFromConfig == null || !commonName.equalsIgnoreCase(cnFromConfig)) {
            policyExportAudit.setHttpRetCode(HttpServletResponse.SC_BAD_REQUEST);
            createPolicyAudit(policyExportAudit);

            throw restErrorUtil.createRESTException(
                    "Unauthorized access. expected [" + cnFromConfig + "], found [" + commonName + "]",
                    MessageEnums.OPER_NOT_ALLOWED_FOR_ENTITY);
        }
    }

    long epochTime = epoch != null ? Long.parseLong(epoch) : 0;

    if (epochTime == updatedTime) {
        int resourceListSz = xResourceList.size();

        if (policyCount == resourceListSz) {
            policyExportAudit.setHttpRetCode(HttpServletResponse.SC_NOT_MODIFIED);
            createPolicyAudit(policyExportAudit);

            throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_MODIFIED,
                    "No change since last update", false);
        }
    }

    List<HashMap<String, Object>> resourceList = new ArrayList<HashMap<String, Object>>();

    // HDFS Repository
    if (xAsset.getAssetType() == AppConstants.ASSET_HDFS) {
        for (VXResource xResource : xResourceList) {
            HashMap<String, Object> resourceMap = new HashMap<String, Object>();
            resourceMap.put("id", xResource.getId());
            resourceMap.put("resource", xResource.getName());
            resourceMap.put("isRecursive", getBooleanValue(xResource.getIsRecursive()));
            resourceMap.put("policyStatus",
                    RangerCommonEnums.getLabelFor_ActiveStatus(xResource.getResourceStatus()));
            // resourceMap.put("isEncrypt",
            // AKAConstants.getLabelFor_BooleanValue(xResource.getIsEncrypt()));
            populatePermMap(xResource, resourceMap, AppConstants.ASSET_HDFS);
            List<VXAuditMap> xAuditMaps = xResource.getAuditList();
            if (xAuditMaps.size() != 0) {
                resourceMap.put("audit", 1);
            } else {
                resourceMap.put("audit", 0);
            }

            resourceList.add(resourceMap);
        }
    } else if (xAsset.getAssetType() == AppConstants.ASSET_HIVE) {
        for (VXResource xResource : xResourceList) {
            HashMap<String, Object> resourceMap = new HashMap<String, Object>();
            resourceMap.put("id", xResource.getId());
            resourceMap.put("database_name", xResource.getDatabases());
            resourceMap.put("policyStatus",
                    RangerCommonEnums.getLabelFor_ActiveStatus(xResource.getResourceStatus()));
            resourceMap.put("tablePolicyType", AppConstants.getLabelFor_PolicyType(xResource.getTableType()));
            resourceMap.put("columnPolicyType", AppConstants.getLabelFor_PolicyType(xResource.getColumnType()));
            int resourceType = xResource.getResourceType();
            if (resourceType == AppConstants.RESOURCE_UDF) {
                resourceMap.put("udf_name", xResource.getUdfs());
            } else if (resourceType == AppConstants.RESOURCE_COLUMN) {
                resourceMap.put("table_name", xResource.getTables());
                resourceMap.put("column_name", xResource.getColumns());
            } else if (resourceType == AppConstants.RESOURCE_TABLE) {
                resourceMap.put("table_name", xResource.getTables());
            }

            populatePermMap(xResource, resourceMap, AppConstants.ASSET_HIVE);

            List<VXAuditMap> xAuditMaps = xResource.getAuditList();
            if (xAuditMaps.size() != 0) {
                resourceMap.put("audit", 1);
            } else {
                resourceMap.put("audit", 0);
            }
            resourceList.add(resourceMap);
        }
    }

    else if (xAsset.getAssetType() == AppConstants.ASSET_HBASE) {
        for (VXResource xResource : xResourceList) {
            HashMap<String, Object> resourceMap = new HashMap<String, Object>();

            resourceMap.put("id", xResource.getId());
            resourceMap.put("table_name", xResource.getTables());
            resourceMap.put("column_name", xResource.getColumns());
            resourceMap.put("column_families", xResource.getColumnFamilies());
            resourceMap.put("policyStatus",
                    RangerCommonEnums.getLabelFor_ActiveStatus(xResource.getResourceStatus()));
            if (xResource.getIsEncrypt() == 1) {
                resourceMap.put("encrypt", 1);
            } else {
                resourceMap.put("encrypt", 0);
            }
            // resourceMap.put("isEncrypt",
            // AKAConstants.getLabelFor_BooleanValue(xResource.getIsEncrypt()));
            populatePermMap(xResource, resourceMap, AppConstants.ASSET_HBASE);
            List<VXAuditMap> xAuditMaps = xResource.getAuditList();
            if (xAuditMaps.size() != 0) {
                resourceMap.put("audit", 1);
            } else {
                resourceMap.put("audit", 0);
            }
            resourceList.add(resourceMap);
        }
    } else if (xAsset.getAssetType() == AppConstants.ASSET_KNOX) {
        for (VXResource xResource : xResourceList) {
            HashMap<String, Object> resourceMap = new HashMap<String, Object>();

            resourceMap.put("id", xResource.getId());
            resourceMap.put("topology_name", xResource.getTopologies());
            resourceMap.put("service_name", xResource.getServices());
            resourceMap.put("policyStatus",
                    RangerCommonEnums.getLabelFor_ActiveStatus(xResource.getResourceStatus()));
            if (xResource.getIsEncrypt() == 1) {
                resourceMap.put("encrypt", 1);
            } else {
                resourceMap.put("encrypt", 0);
            }
            // resourceMap.put("isEncrypt",
            // AKAConstants.getLabelFor_BooleanValue(xResource.getIsEncrypt()));
            populatePermMap(xResource, resourceMap, AppConstants.ASSET_KNOX);
            List<VXAuditMap> xAuditMaps = xResource.getAuditList();
            if (xAuditMaps.size() != 0) {
                resourceMap.put("audit", 1);
            } else {
                resourceMap.put("audit", 0);
            }
            resourceList.add(resourceMap);
        }

    } else if (xAsset.getAssetType() == AppConstants.ASSET_STORM) {
        for (VXResource xResource : xResourceList) {
            HashMap<String, Object> resourceMap = new HashMap<String, Object>();

            resourceMap.put("id", xResource.getId());
            resourceMap.put("topology_name", xResource.getTopologies());
            resourceMap.put("policyStatus",
                    RangerCommonEnums.getLabelFor_ActiveStatus(xResource.getResourceStatus()));
            if (xResource.getIsEncrypt() == 1) {
                resourceMap.put("encrypt", 1);
            } else {
                resourceMap.put("encrypt", 0);
            }
            populatePermMap(xResource, resourceMap, AppConstants.ASSET_STORM);
            List<VXAuditMap> xAuditMaps = xResource.getAuditList();
            if (xAuditMaps.size() != 0) {
                resourceMap.put("audit", 1);
            } else {
                resourceMap.put("audit", 0);
            }
            resourceList.add(resourceMap);
        }
    } else {
        policyExportAudit.setHttpRetCode(HttpServletResponse.SC_BAD_REQUEST);
        createPolicyAudit(policyExportAudit);
        throw restErrorUtil.createRESTException("The operation isn't yet supported for the repository",
                MessageEnums.OPER_NOT_ALLOWED_FOR_ENTITY);
    }

    policyCount = Long.valueOf(resourceList.size());
    updatedRepo.put("last_updated", updatedTime);
    updatedRepo.put("policyCount", policyCount);
    updatedRepo.put("acl", resourceList);

    String updatedPolicyStr = jsonUtil.readMapToString(updatedRepo);

    //      File file = null;
    //      try {
    //         file = jsonUtil.writeMapToFile(updatedRepo, repository);
    //      } catch (JsonGenerationException e) {
    //         logger.error("Error exporting policies for repository : "
    //               + repository, e);
    //      } catch (JsonMappingException e) {
    //         logger.error("Error exporting policies for repository : "
    //               + repository, e);
    //      } catch (IOException e) {
    //         logger.error("Error exporting policies for repository : "
    //               + repository, e);
    //      }

    policyExportAudit.setHttpRetCode(HttpServletResponse.SC_OK);
    createPolicyAudit(policyExportAudit);

    return updatedPolicyStr;
}

From source file:com.fuseim.webapp.ProxyServlet.java

@Override
protected void service(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
        throws ServletException, IOException {
    //initialize request attributes from caches if unset by a subclass by this point
    if (servletRequest.getAttribute(ATTR_TARGET_URI) == null) {
        servletRequest.setAttribute(ATTR_TARGET_URI, targetUri);
    }//from   ww w  . j  a  va  2  s . com
    if (servletRequest.getAttribute(ATTR_TARGET_HOST) == null) {
        servletRequest.setAttribute(ATTR_TARGET_HOST, targetHost);
    }

    // Make the Request
    //note: we won't transfer the protocol version because I'm not sure it would truly be compatible
    String method = servletRequest.getMethod();
    String proxyRequestUri = rewriteUrlFromRequest(servletRequest);
    HttpRequest proxyRequest;
    proxyRequest = initProxyRequest(servletRequest, method, proxyRequestUri);
    copyRequestHeaders(servletRequest, proxyRequest);

    setXForwardedForHeader(servletRequest, proxyRequest);

    HttpResponse proxyResponse = null;
    try {
        // Execute the request
        if (doLog) {
            log("proxy " + method + " uri: " + servletRequest.getRequestURI() + " -- "
                    + proxyRequest.getRequestLine().getUri());
        }

        proxyResponse = proxyClient.execute(getTargetHost(servletRequest), proxyRequest);

        // Process the response:

        // Pass the response code. This method with the "reason phrase" is deprecated but it's the
        //   only way to pass the reason along too.
        int statusCode = proxyResponse.getStatusLine().getStatusCode();
        //noinspection deprecation
        servletResponse.setStatus(statusCode, proxyResponse.getStatusLine().getReasonPhrase());

        // Copying response headers to make sure SESSIONID or other Cookie which comes from the remote
        // server will be saved in client when the proxied url was redirected to another one.
        // See issue [#51](https://github.com/mitre/HTTP-Proxy-Servlet/issues/51)
        copyResponseHeaders(proxyResponse, servletRequest, servletResponse);

        if (statusCode == HttpServletResponse.SC_NOT_MODIFIED) {
            // 304 needs special handling.  See:
            // http://www.ics.uci.edu/pub/ietf/http/rfc1945.html#Code304
            // Don't send body entity/content!
            servletResponse.setIntHeader(HttpHeaders.CONTENT_LENGTH, 0);
        } else {
            // Send the content to the client
            copyResponseEntity(proxyResponse, servletResponse, proxyRequest, servletRequest);
        }

    } catch (Exception e) {
        //abort request, according to best practice with HttpClient
        if (proxyRequest instanceof AbortableHttpRequest) {
            AbortableHttpRequest abortableHttpRequest = (AbortableHttpRequest) proxyRequest;
            abortableHttpRequest.abort();
        }
        if (e instanceof RuntimeException)
            throw (RuntimeException) e;
        if (e instanceof ServletException)
            throw (ServletException) e;
        //noinspection ConstantConditions
        if (e instanceof IOException)
            throw (IOException) e;
        throw new RuntimeException(e);

    } finally {
        // make sure the entire entity was consumed, so the connection is released
        if (proxyResponse != null)
            consumeQuietly(proxyResponse.getEntity());
        //Note: Don't need to close servlet outputStream:
        // http://stackoverflow.com/questions/1159168/should-one-call-close-on-httpservletresponse-getoutputstream-getwriter
    }
}

From source file:cn.tiup.httpproxy.ProxyServlet.java

@Override
protected void service(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
        throws ServletException, IOException {
    //initialize request attributes from caches if unset by a subclass by this point
    if (servletRequest.getAttribute(ATTR_TARGET_URI) == null) {
        servletRequest.setAttribute(ATTR_TARGET_URI, targetUri);
    }/*from  w  w w.j a v  a2s .  com*/
    if (servletRequest.getAttribute(ATTR_TARGET_HOST) == null) {
        servletRequest.setAttribute(ATTR_TARGET_HOST, targetHost);
    }

    // Make the Request
    //note: we won't transfer the protocol version because I'm not sure it would truly be compatible
    String method = servletRequest.getMethod();
    String proxyRequestUri = rewriteUrlFromRequest(servletRequest);
    HttpRequest proxyRequest;
    //spec: RFC 2616, sec 4.3: either of these two headers signal that there is a message body.
    if (servletRequest.getHeader(HttpHeaders.CONTENT_LENGTH) != null
            || servletRequest.getHeader(HttpHeaders.TRANSFER_ENCODING) != null) {
        proxyRequest = newProxyRequestWithEntity(method, proxyRequestUri, servletRequest);
    } else {
        proxyRequest = new BasicHttpRequest(method, proxyRequestUri);
    }

    copyRequestHeaders(servletRequest, proxyRequest);

    setXForwardedForHeader(servletRequest, proxyRequest);
    setXForwardedHostHeader(servletRequest, proxyRequest);
    setXForwardedProtoHeader(servletRequest, proxyRequest);

    HttpResponse proxyResponse = null;
    try {
        // Execute the request
        if (doLog) {
            log("proxy " + method + " uri: " + servletRequest.getRequestURI() + " -- "
                    + proxyRequest.getRequestLine().getUri());
        }
        proxyResponse = proxyClient.execute(getTargetHost(servletRequest), proxyRequest);

        // Process the response:

        // Pass the response code. This method with the "reason phrase" is deprecated but it's the
        //   only way to pass the reason along too.
        int statusCode = proxyResponse.getStatusLine().getStatusCode();
        //noinspection deprecation
        servletResponse.setStatus(statusCode, proxyResponse.getStatusLine().getReasonPhrase());

        // Copying response headers to make sure SESSIONID or other Cookie which comes from the remote
        // server will be saved in client when the proxied url was redirected to another one.
        // See issue [#51](https://github.com/mitre/HTTP-Proxy-Servlet/issues/51)
        copyResponseHeaders(proxyResponse, servletRequest, servletResponse);

        if (statusCode == HttpServletResponse.SC_NOT_MODIFIED) {
            // 304 needs special handling.  See:
            // http://www.ics.uci.edu/pub/ietf/http/rfc1945.html#Code304
            // Don't send body entity/content!
            servletResponse.setIntHeader(HttpHeaders.CONTENT_LENGTH, 0);
        } else {
            // Send the content to the client
            copyResponseEntity(proxyResponse, servletResponse, proxyRequest, servletRequest);
        }

    } catch (Exception e) {
        //abort request, according to best practice with HttpClient
        if (proxyRequest instanceof AbortableHttpRequest) {
            AbortableHttpRequest abortableHttpRequest = (AbortableHttpRequest) proxyRequest;
            abortableHttpRequest.abort();
        }
        if (e instanceof RuntimeException)
            throw (RuntimeException) e;
        if (e instanceof ServletException)
            throw (ServletException) e;
        //noinspection ConstantConditions
        if (e instanceof IOException)
            throw (IOException) e;
        throw new RuntimeException(e);

    } finally {
        // make sure the entire entity was consumed, so the connection is released
        if (proxyResponse != null)
            consumeQuietly(proxyResponse.getEntity());
        //Note: Don't need to close servlet outputStream:
        // http://stackoverflow.com/questions/1159168/should-one-call-close-on-httpservletresponse-getoutputstream-getwriter
    }
}

From source file:helma.servlet.AbstractServletClient.java

protected void writeResponse(HttpServletRequest req, HttpServletResponse res, RequestTrans hopreq,
        ResponseTrans hopres) throws IOException {
    if (hopres.getForward() != null) {
        sendForward(res, req, hopres);/*from w  w w .  j  a  v  a2s.  c om*/
        return;
    }

    if (hopres.getETag() != null) {
        res.setHeader("ETag", hopres.getETag());
    }

    if (hopres.getRedirect() != null) {
        sendRedirect(req, res, hopres.getRedirect(), hopres.getStatus());
    } else if (hopres.getNotModified()) {
        res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
    } else {
        if (!hopres.isCacheable() || !caching) {
            // Disable caching of response.
            if (isOneDotOne(req.getProtocol())) {
                // for HTTP 1.1
                res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate, max-age=0");
            } else {
                // for HTTP 1.0
                res.setDateHeader("Expires", System.currentTimeMillis() - 10000);
                res.setHeader("Pragma", "no-cache");
            }
        }

        if (hopres.getRealm() != null) {
            res.setHeader("WWW-Authenticate", "Basic realm=\"" + hopres.getRealm() + "\"");
        }

        if (hopres.getStatus() > 0) {
            res.setStatus(hopres.getStatus());
        }

        // set last-modified header to now
        long modified = hopres.getLastModified();
        if (modified > -1) {
            res.setDateHeader("Last-Modified", modified);
        }

        res.setContentLength(hopres.getContentLength());
        res.setContentType(hopres.getContentType());

        if (!"HEAD".equalsIgnoreCase(req.getMethod())) {
            byte[] content = hopres.getContent();
            if (content != null) {
                try {
                    OutputStream out = res.getOutputStream();
                    out.write(content);
                    out.flush();
                } catch (Exception iox) {
                    log("Exception in writeResponse: " + iox);
                }
            }
        }
    }
}

From source file:jenkins.metrics.api.MetricsRootAction.java

/**
 * Binds the health checks to the CORS aware URL {@code /metrics/healthcheck} where the metrics access key is
 * provided in the form field {@code key} or an {@code Authorization: Jenkins-Metrics-Key {key}} header
 *
 * @param req the request//from ww w  .j  av a  2  s.  c  o  m
 * @param key the key from the form field.
 * @return the {@link HttpResponse}
 * @throws IllegalAccessException if the access attempt is invalid.
 */
@SuppressWarnings("unused") // stapler binding
@Restricted(NoExternalUse.class) // stapler binding
public HttpResponse doHealthcheck(StaplerRequest req, @QueryParameter("key") String key)
        throws IllegalAccessException {
    requireCorrectMethod(req);
    if (StringUtils.isBlank(key)) {
        key = getKeyFromAuthorizationHeader(req);
    }
    Metrics.checkAccessKeyHealthCheck(key);
    long ifModifiedSince = req.getDateHeader("If-Modified-Since");
    long maxAge = getCacheControlMaxAge(req);
    Metrics.HealthCheckData data = Metrics.getHealthCheckData();
    if (data == null || (maxAge != -1 && data.getLastModified() + maxAge < System.currentTimeMillis())) {
        data = new Metrics.HealthCheckData(Metrics.healthCheckRegistry().runHealthChecks());
    } else if (ifModifiedSince != -1 && data.getLastModified() < ifModifiedSince) {
        return Metrics.cors(key, HttpResponses.status(HttpServletResponse.SC_NOT_MODIFIED));
    }
    return Metrics.cors(key, new HealthCheckResponse(data));
}

From source file:com.zimbra.cs.service.FeedManager.java

private static RemoteDataInfo retrieveRemoteData(String url, Folder.SyncData fsd)
        throws ServiceException, HttpException, IOException {
    assert !Strings.isNullOrEmpty(url);

    HttpClient client = ZimbraHttpConnectionManager.getExternalHttpConnMgr().newHttpClient();
    HttpProxyUtil.configureProxy(client);

    // cannot set connection timeout because it'll affect all HttpClients associated with the conn mgr.
    // see comments in ZimbraHttpConnectionManager
    // client.setConnectionTimeout(10000);

    HttpMethodParams params = new HttpMethodParams();
    params.setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, MimeConstants.P_CHARSET_UTF8);
    params.setSoTimeout(60000);//www. j  a v  a 2s.  c  om

    GetMethod get = null;
    BufferedInputStream content = null;
    long lastModified = 0;
    String expectedCharset = MimeConstants.P_CHARSET_UTF8;
    int redirects = 0;
    int statusCode = HttpServletResponse.SC_NOT_FOUND;
    try {
        do {
            String lcurl = url.toLowerCase();
            if (lcurl.startsWith("webcal:")) {
                url = "http:" + url.substring(7);
            } else if (lcurl.startsWith("feed:")) {
                url = "http:" + url.substring(5);
            } else if (!lcurl.startsWith("http:") && !lcurl.startsWith("https:")) {
                throw ServiceException.INVALID_REQUEST("url must begin with http: or https:", null);
            }

            // username and password are encoded in the URL as http://user:pass@host/...
            if (url.indexOf('@') != -1) {
                HttpURL httpurl = lcurl.startsWith("https:") ? new HttpsURL(url) : new HttpURL(url);
                if (httpurl.getUser() != null) {
                    String user = httpurl.getUser();
                    if (user.indexOf('%') != -1) {
                        try {
                            user = URLDecoder.decode(user, "UTF-8");
                        } catch (OutOfMemoryError e) {
                            Zimbra.halt("out of memory", e);
                        } catch (Throwable t) {
                        }
                    }
                    UsernamePasswordCredentials creds = new UsernamePasswordCredentials(user,
                            httpurl.getPassword());
                    client.getParams().setAuthenticationPreemptive(true);
                    client.getState().setCredentials(AuthScope.ANY, creds);
                }
            }

            try {
                get = new GetMethod(url);
            } catch (OutOfMemoryError e) {
                Zimbra.halt("out of memory", e);
                return null;
            } catch (Throwable t) {
                throw ServiceException.INVALID_REQUEST("invalid url for feed: " + url, t);
            }
            get.setParams(params);
            get.setFollowRedirects(true);
            get.setDoAuthentication(true);
            get.addRequestHeader("User-Agent", HTTP_USER_AGENT);
            get.addRequestHeader("Accept", HTTP_ACCEPT);
            if (fsd != null && fsd.getLastSyncDate() > 0) {
                String lastSyncAt = org.apache.commons.httpclient.util.DateUtil
                        .formatDate(new Date(fsd.getLastSyncDate()));
                get.addRequestHeader("If-Modified-Since", lastSyncAt);
            }
            HttpClientUtil.executeMethod(client, get);

            Header locationHeader = get.getResponseHeader("location");
            if (locationHeader != null) {
                // update our target URL and loop again to do another HTTP GET
                url = locationHeader.getValue();
                get.releaseConnection();
            } else {
                statusCode = get.getStatusCode();
                if (statusCode == HttpServletResponse.SC_OK) {
                    Header contentEncoding = get.getResponseHeader("Content-Encoding");
                    InputStream respInputStream = get.getResponseBodyAsStream();
                    if (contentEncoding != null) {
                        if (contentEncoding.getValue().indexOf("gzip") != -1) {
                            respInputStream = new GZIPInputStream(respInputStream);
                        }
                    }
                    content = new BufferedInputStream(respInputStream);
                    expectedCharset = get.getResponseCharSet();

                    Header lastModHdr = get.getResponseHeader("Last-Modified");
                    if (lastModHdr == null) {
                        lastModHdr = get.getResponseHeader("Date");
                    }
                    if (lastModHdr != null) {
                        try {
                            Date d = org.apache.commons.httpclient.util.DateUtil
                                    .parseDate(lastModHdr.getValue());
                            lastModified = d.getTime();
                        } catch (DateParseException e) {
                            ZimbraLog.misc.warn(
                                    "unable to parse Last-Modified/Date header: " + lastModHdr.getValue(), e);
                            lastModified = System.currentTimeMillis();
                        }
                    } else {
                        lastModified = System.currentTimeMillis();
                    }
                } else if (statusCode == HttpServletResponse.SC_NOT_MODIFIED) {
                    ZimbraLog.misc.debug("Remote data at " + url + " not modified since last sync");
                    return new RemoteDataInfo(statusCode, redirects, null, expectedCharset, lastModified);
                } else {
                    throw ServiceException.RESOURCE_UNREACHABLE(get.getStatusLine().toString(), null);
                }
                break;
            }
        } while (++redirects <= MAX_REDIRECTS);
    } catch (ServiceException ex) {
        if (get != null) {
            get.releaseConnection();
        }
        throw ex;
    } catch (HttpException ex) {
        if (get != null) {
            get.releaseConnection();
        }
        throw ex;
    } catch (IOException ex) {
        if (get != null) {
            get.releaseConnection();
        }
        throw ex;
    }
    RemoteDataInfo rdi = new RemoteDataInfo(statusCode, redirects, content, expectedCharset, lastModified);
    rdi.setGetMethod(get);
    return rdi;
}

From source file:ch.rasc.extclassgenerator.ModelGenerator.java

public static void writeModel(HttpServletRequest request, HttpServletResponse response, ModelBean model,
        OutputConfig outputConfig) throws IOException {

    byte[] data = generateJavascript(model, outputConfig).getBytes(UTF8_CHARSET);
    String ifNoneMatch = request.getHeader("If-None-Match");
    String etag = "\"0" + DigestUtils.md5DigestAsHex(data) + "\"";

    if (etag.equals(ifNoneMatch)) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        return;//from  w  ww.j a va  2 s.c o  m
    }

    response.setContentType("application/javascript");
    response.setCharacterEncoding(UTF8_CHARSET.name());
    response.setContentLength(data.length);

    response.setHeader("ETag", etag);

    @SuppressWarnings("resource")
    ServletOutputStream out = response.getOutputStream();
    out.write(data);
    out.flush();

}

From source file:hu.api.SivaPlayerVideoServlet.java

private void doAction(HttpServletRequest request, HttpServletResponse response, String requestType)
        throws ServletException, IOException {

    // Check if it's an AJAX request
    this.isAJAXRequest = (request.getParameter("ajax") != null && request.getParameter("ajax").equals("true"));

    // Allow Cross-Origin-Requests
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS");
    response.setHeader("Access-Control-Max-Age", "1000");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");

    // URL pattern: /videoId
    // Get request parameter from URL and check if it has been set.
    // Show 400 if less or more parameters than allowed.
    String requestedVideo = request.getPathInfo();
    if (requestedVideo == null || requestedVideo.split("/").length < 2
            || requestedVideo.split("/")[1].equals("")) {
        this.sendError(response, HttpServletResponse.SC_BAD_REQUEST,
                "The video folder has to be specified for using this web service.");
        return;/* w w  w. ja v a  2 s .  co  m*/
    }

    this.persistenceProvider = (IPersistenceProvider) getServletContext().getAttribute("PersistenceProvider");
    this.mailService = (MailService) getServletContext().getAttribute("mailService");
    this.brandingConfiguration = (BrandingConfiguration) getServletContext()
            .getAttribute("brandingConfiguration");

    // Check if it's a watching request
    if (request.getPathInfo().endsWith("/watch.html")) {
        this.providePlayer(request, response);
        return;
    }

    // Check if it's a log request and perform logging if so
    if (request.getPathInfo().endsWith("/log") && requestType.equals("POST")) {
        this.doLogging(request, response);
        return;
    }

    // Check if it's a checkSession request and provide session status if so
    if (requestedVideo.endsWith("/getStats.js")) {
        this.getStats(request, response);
        return;
    }

    // Check if user requests user secret and perform login
    if (request.getPathInfo().endsWith("/getSecret.js") && requestType.equals("POST")) {
        this.provideUserSecret(request, response, requestType);
        return;
    }

    // Check if current session exists and if it is allowed to access this
    // video, stop further execution, if so.
    boolean result = handleAccess(request, response, requestType);
    if (!result) {
        return;
    }

    // Check if it's collaboration request and provide data
    if (request.getPathInfo().endsWith("/getCollaboration.js")) {
        this.provideCollaboration(request, response);
        return;
    }

    // Check if it's a thread creation request
    if (request.getPathInfo().endsWith("/createCollaborationThread.js")) {
        this.createCollaborationThread(request, response);
        return;
    }

    // Check if it's a post creation request
    if (request.getPathInfo().endsWith("/createCollaborationPost.js")) {
        this.createCollaborationPost(request, response);
        return;
    }

    // Check if it's a post activation request
    if (request.getPathInfo().endsWith("/activateCollaborationPost.js")) {
        this.activateCollaborationPost(request, response);
        return;
    }

    // Check if it's a post creation request
    if (request.getPathInfo().endsWith("/deleteCollaborationThread.js")) {
        this.deleteCollaborationThread(request, response);
        return;
    }

    // Check if it's a post creation request
    if (request.getPathInfo().endsWith("/deleteCollaborationPost.js")) {
        this.deleteCollaborationPost(request, response);
        return;
    }

    // Check if it's a checkSession request and provide session status if so
    if (requestedVideo.endsWith("/checkSession.js")) {
        this.provideSessionStatus(request, response);
        return;
    }

    // Decode the file name from the URL and check if file actually exists
    // in
    // file system, send 404 if not
    File file = new File(videoPath, URLDecoder.decode(requestedVideo, "UTF-8"));
    if (!file.exists()) {
        this.sendError(response, HttpServletResponse.SC_NOT_FOUND, "File not found");
        return;
    }

    // Create log entry for file request
    this.logFileRequest(requestedVideo);

    // Check if configuration is requested and do needed preparing and
    // stop standard file preparation
    if (file.getName().equals("export.js")) {
        this.provideConfigFile(request, response, file);
        return;
    }

    // Prepare some variables. The ETag is an unique identifier of the file.
    String fileName = file.getName();
    long length = file.length();
    long lastModified = file.lastModified();
    String eTag = fileName + "_" + length + "_" + lastModified;
    long expires = System.currentTimeMillis() + DEFAULT_EXPIRE_TIME;

    // Validate request headers for caching
    // ---------------------------------------------------

    // If-None-Match header should contain "*" or ETag. If so, then return
    // 304.
    String ifNoneMatch = request.getHeader("If-None-Match");
    if (ifNoneMatch != null && matches(ifNoneMatch, eTag)) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        response.setHeader("ETag", eTag); // Required in 304.
        response.setDateHeader("Expires", expires); // Postpone cache with 1
        // week.
        return;
    }

    // If-Modified-Since header should be greater than LastModified. If so,
    // then return 304.
    // This header is ignored if any If-None-Match header is specified.
    long ifModifiedSince = request.getDateHeader("If-Modified-Since");
    if (ifNoneMatch == null && ifModifiedSince != -1 && ifModifiedSince + 1000 > lastModified) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        response.setHeader("ETag", eTag); // Required in 304.
        response.setDateHeader("Expires", expires); // Postpone cache with 1
        // week.
        return;
    }

    // Validate request headers for resume
    // ----------------------------------------------------

    // If-Match header should contain "*" or ETag. If not, then return 412.
    String ifMatch = request.getHeader("If-Match");
    if (ifMatch != null && !matches(ifMatch, eTag)) {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }

    // If-Unmodified-Since header should be greater than LastModified. If
    // not, then return 412.
    long ifUnmodifiedSince = request.getDateHeader("If-Unmodified-Since");
    if (ifUnmodifiedSince != -1 && ifUnmodifiedSince + 1000 <= lastModified) {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }

    // Validate and process range
    // -------------------------------------------------------------

    // Prepare some variables. The full Range represents the complete file.
    Range full = new Range(0, length - 1, length);
    List<Range> ranges = new ArrayList<Range>();

    // Validate and process Range and If-Range headers.
    String range = request.getHeader("Range");
    if (range != null) {

        // Range header should match format "bytes=n-n,n-n,n-n...". If not,
        // then return 416.
        if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) {
            response.setHeader("Content-Range", "bytes */" + length); // Required
            // in
            // 416.
            response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
            return;
        }

        // If-Range header should either match ETag or be greater then
        // LastModified. If not,
        // then return full file.
        String ifRange = request.getHeader("If-Range");
        if (ifRange != null && !ifRange.equals(eTag)) {
            try {
                long ifRangeTime = request.getDateHeader("If-Range"); // Throws
                // IAE
                // if
                // invalid.
                if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) {
                    ranges.add(full);
                }
            } catch (IllegalArgumentException ignore) {
                ranges.add(full);
            }
        }

        // If any valid If-Range header, then process each part of byte
        // range.
        if (ranges.isEmpty()) {
            for (String part : range.substring(6).split(",")) {
                // Assuming a file with length of 100, the following
                // examples returns bytes at:
                // 50-80 (50 to 80), 40- (40 to length=100), -20
                // (length-20=80 to length=100).
                long start = sublong(part, 0, part.indexOf("-"));
                long end = sublong(part, part.indexOf("-") + 1, part.length());

                if (start == -1) {
                    start = length - end;
                    end = length - 1;
                } else if (end == -1 || end > length - 1) {
                    end = length - 1;
                }

                // Check if Range is syntactically valid. If not, then
                // return 416.
                if (start > end) {
                    response.setHeader("Content-Range", "bytes */" + length); // Required
                    // in
                    // 416.
                    response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
                    return;
                }

                // Add range.
                ranges.add(new Range(start, end, length));
            }
        }
    }

    // Prepare and initialize response
    // --------------------------------------------------------

    // Get content type by file name and set default GZIP support and
    // content disposition.
    String contentType = getServletContext().getMimeType(fileName);
    boolean acceptsGzip = false;
    String disposition = "inline";

    // If content type is unknown, then set the default value.
    // For all content types, see:
    // http://www.w3schools.com/media/media_mimeref.asp
    // To add new content types, add new mime-mapping entry in web.xml.
    if (contentType == null) {
        contentType = "application/octet-stream";
    }

    // If content type is text, then determine whether GZIP content encoding
    // is supported by
    // the browser and expand content type with the one and right character
    // encoding.
    if (contentType.startsWith("text")) {
        String acceptEncoding = request.getHeader("Accept-Encoding");
        acceptsGzip = acceptEncoding != null && accepts(acceptEncoding, "gzip");
        contentType += ";charset=UTF-8";
    }

    // Else, expect for images, determine content disposition. If content
    // type is supported by
    // the browser, then set to inline, else attachment which will pop a
    // 'save as' dialogue.
    else if (!contentType.startsWith("image")) {
        String accept = request.getHeader("Accept");
        disposition = accept != null && accepts(accept, contentType) ? "inline" : "attachment";
    }

    // Initialize response.
    response.reset();
    response.setBufferSize(DEFAULT_BUFFER_SIZE);
    response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileName + "\"");
    response.setHeader("Accept-Ranges", "bytes");
    response.setHeader("ETag", eTag);
    response.setDateHeader("Last-Modified", lastModified);
    response.setDateHeader("Expires", expires);

    // Send requested file (part(s)) to client
    // ------------------------------------------------

    // Prepare streams.
    RandomAccessFile input = null;
    OutputStream output = null;

    try {
        // Open streams.
        input = new RandomAccessFile(file, "r");
        output = response.getOutputStream();

        if (ranges.isEmpty() || ranges.get(0) == full) {

            // Return full file.
            Range r = full;
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);

            if (requestType.equals("GET")) {
                if (acceptsGzip) {
                    // The browser accepts GZIP, so GZIP the content.
                    response.setHeader("Content-Encoding", "gzip");
                    output = new GZIPOutputStream(output, DEFAULT_BUFFER_SIZE);
                } else {
                    // Content length is not directly predictable in case of
                    // GZIP.
                    // So only add it if there is no means of GZIP, else
                    // browser will hang.
                    response.setHeader("Content-Length", String.valueOf(r.length));
                }

                // Copy full range.
                copy(input, output, r.start, r.length);
            }

        } else if (ranges.size() == 1) {

            // Return single part of file.
            Range r = ranges.get(0);
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);
            response.setHeader("Content-Length", String.valueOf(r.length));
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

            if (requestType.equals("GET")) {
                // Copy single part range.
                copy(input, output, r.start, r.length);
            }

        } else {

            // Return multiple parts of file.
            response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY);
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

            if (requestType.equals("GET")) {
                // Cast back to ServletOutputStream to get the easy println
                // methods.
                ServletOutputStream sos = (ServletOutputStream) output;

                // Copy multi part range.
                for (Range r : ranges) {
                    // Add multipart boundary and header fields for every
                    // range.
                    sos.println();
                    sos.println("--" + MULTIPART_BOUNDARY);
                    sos.println("Content-Type: " + contentType);
                    sos.println("Content-Range: bytes " + r.start + "-" + r.end + "/" + r.total);

                    // Copy single part range of multi part range.
                    copy(input, output, r.start, r.length);
                }

                // End with multipart boundary.
                sos.println();
                sos.println("--" + MULTIPART_BOUNDARY + "--");
            }
        }
    } finally {
        // Gently close streams.
        close(output);
        close(input);
    }
}