/** * {@inheritDoc} * * @throws IOException * @see * org.sakaiproject.nakamura.api.proxy.ProxyPostProcessor#process(org.apache.sling.api.SlingHttpServletResponse, * org.sakaiproject.nakamura.api.proxy.ProxyResponse) */ public void process( Map<String, Object> templateParams, SlingHttpServletResponse response, ProxyResponse proxyResponse) throws IOException { for (Entry<String, String[]> h : proxyResponse.getResponseHeaders().entrySet()) { for (String v : h.getValue()) { response.setHeader(h.getKey(), v); } } int code = proxyResponse.getResultCode(); response.setStatus(code); IOUtils.stream(proxyResponse.getResponseBodyAsInputStream(), response.getOutputStream()); }
protected void dispatch( SlingHttpServletRequest request, SlingHttpServletResponse response, boolean userInputStream) throws ServletException, IOException { try { Resource resource = request.getResource(); if (!resource.getPath().startsWith(PROXY_PATH_PREFIX)) { response.sendError( HttpServletResponse.SC_FORBIDDEN, "Proxying templates may only be stored in " + PROXY_PATH_PREFIX); return; } Node node = resource.adaptTo(Node.class); if (!userInputStream) { Value[] v = JcrUtils.getValues(node, SAKAI_REQUEST_STREAM_BODY); if (v != null && v.length > 0) { userInputStream = Boolean.parseBoolean(v[0].getString()); } } Map<String, String> headers = new ConcurrentHashMap<String, String>(); for (Enumeration<?> enames = request.getHeaderNames(); enames.hasMoreElements(); ) { String name = (String) enames.nextElement(); if (!headerBacklist.contains(name)) { headers.put(name, request.getHeader(name)); } } // search for special headers. if (headers.containsKey(BASIC_USER)) { String user = headers.get(BASIC_USER); String password = headers.get(BASIC_PASSWORD); Base64 base64 = new Base64(); String passwordDigest = new String(base64.encode((user + ":" + password).getBytes("UTF-8"))); String digest = BASIC + passwordDigest.trim(); headers.put(AUTHORIZATION, digest); } for (Entry<String, String> e : headers.entrySet()) { if (e.getKey().startsWith(":")) { headers.remove(e.getKey()); } } // collect the parameters and store into a mutable map. RequestParameterMap parameterMap = request.getRequestParameterMap(); Map<String, Object> templateParams = new ConcurrentHashMap<String, Object>(parameterMap); // search for special parameters. if (parameterMap.containsKey(BASIC_USER)) { String user = parameterMap.getValue(BASIC_USER).getString(); String password = parameterMap.getValue(BASIC_PASSWORD).getString(); Base64 base64 = new Base64(); String passwordDigest = new String(base64.encode((user + ":" + password).getBytes("UTF-8"))); String digest = BASIC + passwordDigest.trim(); headers.put(AUTHORIZATION, digest); } // we might want to pre-process the headers if (node.hasProperty(ProxyPreProcessor.SAKAI_PREPROCESSOR)) { String preprocessorName = node.getProperty(ProxyPreProcessor.SAKAI_PREPROCESSOR).getString(); ProxyPreProcessor preprocessor = preProcessors.get(preprocessorName); if (preprocessor != null) { preprocessor.preProcessRequest(request, headers, templateParams); } else { LOGGER.warn( "Unable to find pre processor of name {} for node {} ", preprocessorName, node.getPath()); } } ProxyPostProcessor postProcessor = defaultPostProcessor; // we might want to post-process the headers if (node.hasProperty(ProxyPostProcessor.SAKAI_POSTPROCESSOR)) { String postProcessorName = node.getProperty(ProxyPostProcessor.SAKAI_POSTPROCESSOR).getString(); if (postProcessors.containsKey(postProcessorName)) { postProcessor = postProcessors.get(postProcessorName); } if (postProcessor == null) { LOGGER.warn( "Unable to find post processor of name {} for node {} ", postProcessorName, node.getPath()); postProcessor = defaultPostProcessor; } } ProxyResponse proxyResponse = proxyClientService.executeCall(node, headers, templateParams, null, -1, null); try { postProcessor.process(templateParams, response, proxyResponse); } finally { proxyResponse.close(); } } catch (IOException e) { throw e; } catch (ProxyClientException e) { response.sendError(500, e.getMessage()); } catch (RepositoryException e) { response.sendError(500, e.getMessage()); } }
public void process(SlingHttpServletResponse response, ProxyResponse proxyResponse) throws IOException { Map<String, String[]> headers = proxyResponse.getResponseHeaders(); // Check if the content-length is smaller than the maximum (if any). String[] contentLengthHeader = headers.get("Content-Length"); if (contentLengthHeader != null) { int length = Integer.parseInt(contentLengthHeader[0]); if (length > MAX_RSS_LENGTH) { response.sendError( HttpServletResponse.SC_FORBIDDEN, "This RSS feed is too big. The maximum for a feed is: " + MAX_RSS_LENGTH); return; } } // Check if the Content-Type we get is valid (if any). String[] contentTypeHeader = headers.get("Content-Type"); if (contentTypeHeader != null) { String contentType = contentTypeHeader[0]; if (contentType.contains(";")) { contentType = contentType.substring(0, contentType.indexOf(';')); } if (!contentTypes.contains(contentType)) { response.sendError( HttpServletResponse.SC_FORBIDDEN, "This URL doesn't send a proper Content-Type back"); return; } } boolean isValid = false; InputStream in = proxyResponse.getResponseBodyAsInputStream(); InputStreamReader reader = new InputStreamReader(in); // XMLStreamWriter writer = null; XMLEventWriter writer = null; ByteArrayOutputStream out = null; int i = 0; try { XMLEventReader eventReader = xmlInputFactory.createXMLEventReader(reader); // Create a temporary outputstream where we can write to. out = new ByteArrayOutputStream(); Map<String, Boolean> checkedElements = new HashMap<String, Boolean>(); checkedElements.put("rss", false); checkedElements.put("channel", false); checkedElements.put("title", false); checkedElements.put("link", false); checkedElements.put("item", false); checkedElements.put("title", false); checkedElements.put("link", false); XMLOutputFactory outputFactory = new WstxOutputFactory(); writer = outputFactory.createXMLEventWriter(out); while (eventReader.hasNext()) { XMLEvent e = eventReader.nextEvent(); // Stream it to an output stream. writer.add(e); if (!isValid) { if (e.getEventType() == XMLEvent.START_ELEMENT) { StartElement el = e.asStartElement(); String name = el.getName().toString().toLowerCase(); if (checkedElements.containsKey(name)) { checkedElements.put(name, true); } boolean all = true; for (Entry<String, Boolean> es : checkedElements.entrySet()) { if (!checkedElements.get(es.getKey())) { all = false; break; } } if (all) isValid = true; } if (i > 100) { response.sendError( HttpServletResponse.SC_FORBIDDEN, "This file does not match an RSS formatted XML file.."); break; } i++; } } if (!isValid) { response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid RSS file."); return; } // Check if we are not streaming a gigantic file.. if (out.size() > MAX_RSS_LENGTH) { response.sendError(HttpServletResponse.SC_FORBIDDEN, "This file is to big."); return; } for (Entry<String, String[]> h : proxyResponse.getResponseHeaders().entrySet()) { for (String v : h.getValue()) { response.setHeader(h.getKey(), v); } } // We always return 200 when we get to this point. response.setStatus(200); response.setHeader("Content-Length", "" + out.size()); // Write the cached stream to the output. out.writeTo(response.getOutputStream()); } catch (XMLStreamException e) { response.sendError(HttpServletResponse.SC_FORBIDDEN, "This is not a valid XML file."); } catch (Exception e) { logger.warn("Exception reading RSS feed."); response.sendError(HttpServletResponse.SC_FORBIDDEN, "General exception caught."); } finally { out.close(); reader.close(); try { writer.close(); } catch (XMLStreamException e) { // Not much we can do? e.printStackTrace(); } } }