/** * Test for {@code write(int)}. */ @Test public void testWriteChar() throws Exception { String phrase = "Apache Tomcat " + "\u0410\u043f\u0430\u0447\u0435 \u0422\u043e\u043c\u043a\u0430\u0442 "; byte[] data = phrase.getBytes("UTF-8"); ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(); OutputStream output = new FlushableGZIPOutputStream(byteOutStream); output.write(data); for (int i=0; i<data.length; i++) { output.write(data[i]); } output.flush(); for (int i=0; i<data.length; i++) { output.write(data[i]); } output.write(data); output.close(); ByteArrayInputStream byteInStream = new ByteArrayInputStream(byteOutStream.toByteArray()); GZIPInputStream inflaterStream = new GZIPInputStream(byteInStream); ByteArrayOutputStream sink = new ByteArrayOutputStream(); try { IOTools.flow(inflaterStream, sink); } finally { sink.close(); } byte[] decompressedBytes = sink.toByteArray(); assertEquals(data.length * 4, decompressedBytes.length); for (int i = 0; i < 4; i++) { assertArrayEquals(data, Arrays.copyOfRange(decompressedBytes, data.length * i, data.length * (i + 1))); } }
/** * Loads file into memory. */ private byte[] loadFile(File file) throws IOException { ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(); FileInputStream input = new FileInputStream(file); try { IOTools.flow(input, byteOutStream); } finally { input.close(); } return byteOutStream.toByteArray(); }
/** * Writes data to the stream and returns the size of the file. */ private void flowBytes(byte[] bytes, OutputStream output) throws IOException { // Could use output.write(), but IOTools writes in small portions, and // that is more natural ByteArrayInputStream byteInStream = new ByteArrayInputStream(bytes); try { IOTools.flow(byteInStream, output); } finally { byteInStream.close(); } }
@Test public void testBug52121() throws Exception { ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(); OutputStream output = new FlushableGZIPOutputStream(byteOutStream); File sourcesDir = new File("test/org/apache/coyote/http11/filters/"); List<byte[]> parts = new ArrayList<byte[]>(); byte[] part; part = loadFile(new File(sourcesDir, "bug52121-part1")); parts.add(part); flowBytes(part, output); output.flush(); part = loadFile(new File(sourcesDir, "bug52121-part2")); parts.add(part); flowBytes(part, output); output.flush(); part = "data2".getBytes("ASCII"); parts.add(part); output.write(part); output.flush(); output.close(); ByteArrayInputStream byteInStream = new ByteArrayInputStream(byteOutStream.toByteArray()); GZIPInputStream inflaterStream = new GZIPInputStream(byteInStream); ByteArrayOutputStream sink = new ByteArrayOutputStream(); try { IOTools.flow(inflaterStream, sink); } finally { sink.close(); } byte[] decompressedBytes = sink.toByteArray(); int originalLength = 0; for (byte[] bytes : parts) { assertArrayEquals(bytes, Arrays.copyOfRange(decompressedBytes, originalLength, originalLength + bytes.length)); originalLength += bytes.length; } assertEquals(originalLength, decompressedBytes.length); }
/** * Extracts requested resource from web app archive to context work * directory to enable script to be executed. */ protected void expandScript() { StringBuffer srcPath = new StringBuffer(); StringBuffer dstPath = new StringBuffer(); InputStream is = null; // paths depend on mapping if (scriptPathPrefix == null) { srcPath.append(pathInfo); is = context.getResourceAsStream(srcPath.toString()); dstPath.append(tempDir); dstPath.append(pathInfo); } else { // essentially same search algorithm as findScript() srcPath.append(scriptPathPrefix); StringTokenizer dirWalker = new StringTokenizer(pathInfo, "/"); // start with first element while (dirWalker.hasMoreElements() && (is == null)) { srcPath.append("/"); srcPath.append(dirWalker.nextElement()); is = context.getResourceAsStream(srcPath.toString()); } dstPath.append(tempDir); dstPath.append("/"); dstPath.append(srcPath); } if (is == null) { // didn't find anything, give up now return; } File f = new File(dstPath.toString()); if (f.exists()) { // Don't need to expand if it already exists return; } // create directories String dirPath = new String(dstPath.toString().substring( 0, dstPath.toString().lastIndexOf("/"))); File dir = new File(dirPath); dir.mkdirs(); try { synchronized (expandFileLock) { // make sure file doesn't exist if (f.exists()) { return; } // create file if (!f.createNewFile()) { return; } FileOutputStream fos = new FileOutputStream(f); // copy data IOTools.flow(is, fos); is.close(); fos.close(); } } catch (IOException ioe) { // delete in case file is corrupted if (f.exists()) { f.delete(); } } }
/** * Process a file with server-side commands, reading from reader and writing the processed * version to writer. * * NOTE: We really should be doing this in a streaming way rather than converting it to an array first. * * @param reader the reader to read the file containing SSIs from * @param writer the writer to write the file with the SSIs processed. * @throws IOException when things go horribly awry. Should be unlikely since * the SSICommand usually catches 'normal' IOExceptions. */ public void process( Reader reader, Date lastModifiedDate, PrintWriter writer ) throws IOException { SSIMediator ssiMediator = new SSIMediator( ssiExternalResolver, lastModifiedDate, debug ); StringWriter stringWriter = new StringWriter(); IOTools.flow( reader, stringWriter ); String fileContents = stringWriter.toString(); stringWriter = null; int index = 0; boolean inside = false; StringBuffer command = new StringBuffer(); try { while (index < fileContents.length()) { char c = fileContents.charAt( index ); if ( !inside ) { if ( c == COMMAND_START.charAt( 0 ) && charCmp( fileContents, index, COMMAND_START ) ) { inside = true; index += COMMAND_START.length(); command.setLength( 0 ); //clear the command string } else { writer.write( c ); index++; } } else { if ( c == COMMAND_END.charAt( 0 ) && charCmp( fileContents, index, COMMAND_END ) ) { inside = false; index += COMMAND_END.length(); String strCmd = parseCmd(command); if ( debug > 0 ) { ssiExternalResolver.log( "SSIProcessor.process -- processing command: " + strCmd, null ); } String[] paramNames = parseParamNames(command, strCmd.length()); String[] paramValues = parseParamValues(command, strCmd.length()); //We need to fetch this value each time, since it may change during the loop String configErrMsg = ssiMediator.getConfigErrMsg(); SSICommand ssiCommand = (SSICommand) commands.get(strCmd.toLowerCase()); if ( ssiCommand != null ) { if ( paramNames.length==paramValues.length ) { ssiCommand.process( ssiMediator, paramNames, paramValues, writer ); } else { ssiExternalResolver.log( "Parameter names count does not match parameter values count on command: " + strCmd, null ); writer.write( configErrMsg ); } } else { ssiExternalResolver.log( "Unknown command: " + strCmd, null); writer.write( configErrMsg ); } } else { command.append( c ); index++; } } } } catch ( SSIStopProcessingException e ) { //If we are here, then we have already stopped processing, so all is good } }