private String readLine(ServletInputStream in) throws IOException { StringBuilder sbuf = new StringBuilder(); int result; do { result = in.readLine(buf, 0, buf.length); // does += if (result != -1) { sbuf.append(new String(buf, 0, result, encoding)); } } while (result == buf.length); // loop only if the buffer was filled if (sbuf.length() == 0) { return null; // nothing read, must be at the end of stream } // Cut off the trailing \n or \r\n // It should always be \r\n but IE5 sometimes does just \n // Thanks to Luke Blaikie for helping make this work with \n int len = sbuf.length(); if (len >= 2 && sbuf.charAt(len - 2) == '\r') { sbuf.setLength(len - 2); // cut \r\n } else if (len >= 1 && sbuf.charAt(len - 1) == '\n') { sbuf.setLength(len - 1); // cut \n } return sbuf.toString(); }
/* * protected method to get a job in JsonBean representation */ @Override protected JsonBean getJob(HttpServletRequest request, HttpServletResponse response) throws XServletException, IOException, BaseEngineException { ServletInputStream is = request.getInputStream(); byte[] b = new byte[101]; while (is.readLine(b, 0, 100) != -1) { XLog.getLog(getClass()).warn("Printing :" + new String(b)); } JsonBean jobBean = null; String jobId = getResourceName(request); if (jobId.endsWith("-B")) { jobBean = getBundleJob(request, response); } else { if (jobId.endsWith("-W")) { jobBean = getWorkflowJob(request, response); } else { if (jobId.contains("-W@")) { jobBean = getWorkflowAction(request, response); } else { if (jobId.contains("-C@")) { jobBean = getCoordinatorAction(request, response); } else { jobBean = getCoordinatorJob(request, response); } } } } return jobBean; }
private Document getDocument(ServletInputStream inputStream, int contentLength) { int charCount = 0; byte[] byteBuffer = new byte[contentLength]; while (true) { try { int readLength = inputStream.readLine(byteBuffer, charCount, 1024); // LogEvent.logFatal("IndicatorAggregationReportingServlet", String.valueOf(readLength), new // String(byteBuffer).trim()); if (readLength == -1) { return DocumentHelper.parseText(new String(byteBuffer).trim()); } else { charCount += readLength; } } catch (IOException e) { e.printStackTrace(); return null; } catch (DocumentException de) { de.printStackTrace(); return null; } } }
/** * The method reads the next line from the servlet input stream into a byte array and returns a * String form of the array.Returns null if it reaches the end of the stream * * @return String The next line in the stream * @throws IOException - If there was a problem reading the stream or */ private String readLine() throws IOException { int len = 0; String line = null; len = in.readLine(buff, 0, buff.length); if (len < 0) return null; line = new String(buff, 0, len, "ISO-8859-1"); return line; }
/** Convenience method to read HTTP header lines */ private synchronized String getLine(ServletInputStream sis) throws IOException { byte b[] = new byte[1024]; int read = sis.readLine(b, 0, b.length), index; String line = null; if (read != -1) { line = new String(b, 0, read); if ((index = line.indexOf('\n')) >= 0) line = line.substring(0, index - 1); } return line; }
/** * Reads the file content from the stream and writes it to the local file system * * @throws IOException - If there was a problem reading the stream */ private void writeToFile() throws IOException { // Open an o/p stream File tmpFile = File.createTempFile(prefix, "upload", new File(dir)); tmpFile.deleteOnExit(); log.debug("Setting: " + uploadFileArg + " to: " + tmpFile.getPath()); map.put(uploadFileArg, tmpFile.getPath()); // FileOutputStream out = new FileOutputStream (dir+File.separator+fileName); FileOutputStream out = new FileOutputStream(tmpFile); // this flag checks if \r\n needs to be written to the file // the servlet output stream appends these characters at the end of the // last line of the content, which should be skipped // so in the loop, all \r\n but for the last line are written to the file boolean writeCR = false; int len = 0; String line = null; map.put(paramName, fileName); // for each line while ((len = in.readLine(buff, 0, buff.length)) > -1) { line = new String(buff, 0, len); // if end of content, break if (line.startsWith(boundary)) break; if (writeCR) { writeCR = false; out.write('\r'); out.write('\n'); } if (len > 2 && buff[len - 2] == '\r' && buff[len - 1] == '\n') { writeCR = true; out.write(buff, 0, len - 2); } else { out.write(buff, 0, len); } } out.close(); }
/** * Obtain the byte array for this part of the request. * * <p>It may be necessary to modify this code to handle additional encoding types such as Base64. * * @param input Object from which data is read * @param thisPage Object containing information for this request * @param encoding type of character encoding to be used * @return Byte array for this part of request * @throws IOException if io errors */ protected byte[] readPart(ServletInputStream input, ThisPage thisPage, String encoding) throws IOException { HttpServletRequest req = thisPage.getRequest(); String boundary = extractBoundary(req); byte buffer[] = new byte[4096]; int bytesRead = -1; ByteArrayOutputStream working = null; boolean pendingRN = false; working = new ByteArrayOutputStream(); /* * Read body of part */ while (true) { bytesRead = input.readLine(buffer, 0, buffer.length); if (bytesRead < 0) { thisPage.addMessage("readPart method - Section of form not properly ended"); thisPage.errorMessage(); return null; } else if (bytesRead == 0) { thisPage.addMessage("readPart method - Read yielded 0 characters"); thisPage.errorMessage(); return null; } else if (bytesRead == 1 && buffer[0] == '\n') { if (pendingRN) { working.write('\r'); working.write('\n'); pendingRN = false; } working.write(buffer[0]); } else if (new String(buffer, 0, bytesRead).equals("--" + boundary + "\r\n")) { if (!pendingRN) { thisPage.addMessage("readPart method - Boundary reached without preceding end of line"); thisPage.errorMessage(); return null; } if (working.size() == 0) { return null; } return working.toByteArray(); } else if (new String(buffer, 0, bytesRead).equals("--" + boundary + "--\r\n")) { thisPage.setEndOfPacket(true); if (!pendingRN) { thisPage.addMessage( "readPart method - Final boundary reached with preceding end of line"); thisPage.errorMessage(); return null; } if (working.size() == 0) { return null; } return working.toByteArray(); } else if (buffer[bytesRead - 2] == '\r' && buffer[bytesRead - 1] == '\n') { if (pendingRN) { working.write('\r'); working.write('\n'); } if (bytesRead > 2) { working.write(buffer, 0, bytesRead - 2); } pendingRN = true; } else if (buffer[bytesRead - 1] == '\r') { if (pendingRN) { working.write('\r'); working.write('\n'); pendingRN = false; } if (bytesRead > 1) { working.write(buffer, 0, bytesRead - 1); } int nextChar = input.read(); if (nextChar == '\n') { pendingRN = true; } else { working.write('\r'); working.write(nextChar); } } else { if (pendingRN) { working.write('\r'); working.write('\n'); pendingRN = false; } working.write(buffer, 0, bytesRead); } } }
/** * Process the call to the servlet. * * <p>With regard to reading data from the request, a {@link javax.servlet.ServletInputStream} * object for binary data can be obtained by {@link HttpServletRequest#getInputStream()} or a * {@link java.io.BufferedReader} can be obtained for character data by using {@link * HttpServletRequest#getReader}. * * <p>With regard to writing data to the response a {@link javax.servlet.ServletOutputStream} * object for binary data can be obtained using {@link HttpServletResponse#getOutputStream()} * while a {@link java.io.PrintWriter} object can be obtained using {@link * HttpServletResponse#getWriter()}. * * <p>The {@link java.io.ByteArrayOutputStream} class can be used as a means of collecting the * bytes contained in the attached file. * * <p>It would be desirable to have tests for enctype and method. * * @param req Request object * @param res Response object * @throws IOException if io problems */ public void service(HttpServletRequest req, HttpServletResponse res) throws IOException { ThisPage thisPage = new ThisPage(req, res, config); GenericPrinter output = thisPage.getPrinter(); if (!req.getMethod().equalsIgnoreCase("post")) { output.println("<html><head>"); output.println("<title>Must use POST method</title>"); output.println("</head><body>"); output.println("<h1>Must use POST method</h1>"); output.println("<p>Request used " + req.getMethod() + " method</p>"); output.println("<p>Must use POST method</p>"); output.println("</body></html>"); thisPage.sendContents(); return; } else if (req.getHeader("content-type") == null) { output.println("<html><head>"); output.println("<title>Missing content-type header</title>"); output.println("</head><body>"); output.println("<h1>Missing content-type header</h1>"); output.println( "<p>Must use content-type header " + "to specify multipart/form-data encoding</p>"); output.println("</body></html>"); thisPage.sendContents(); return; } else if (!req.getHeader("content-type").toLowerCase().startsWith("multipart/form-data")) { output.println("<html><head>"); output.println("<title>Must use multipart/form-data encoding</title>"); output.println("</head><body>"); output.println("<h1>Must use multipart/form-data encoding</h1>"); output.println("<p>content-type is " + req.getHeader("content-type") + " </p>"); output.println("<p>Must use multipart/form-data encoding</p>"); output.println("</body></html>"); thisPage.sendContents(); return; } String boundary = extractBoundary(req); if (boundary == null) { thisPage.addMessage("Unable to extract boundary value"); thisPage.addMessage(req.getHeader("content-type")); thisPage.errorMessage(); return; } int counter = 0; byte buffer[] = new byte[4096]; byte extract[]; int bytesRead = -1; ServletInputStream input = req.getInputStream(); bytesRead = input.readLine(buffer, 0, buffer.length); if (!new String(buffer, 0, bytesRead, "ISO8859_1").startsWith("--" + boundary)) { thisPage.addMessage( "Should be separator " + "--" + boundary + " : " + " found " + new String(buffer, 0, bytesRead)); thisPage.errorMessage(); return; } while (true) { counter++; Contents part = new Contents(); thisPage.addMessage("Starting part " + Integer.toString(counter) + " of form"); while (true) { bytesRead = input.readLine(buffer, 0, buffer.length); if (bytesRead < 0) { thisPage.addMessage("Unexpected end of packet"); thisPage.errorMessage(); return; } else { String value = new String(buffer, 0, bytesRead, "ISO8859_1"); if (value.endsWith("\r\n")) { value = stripEOL(value); } if (value.length() == 0) { extract = readPart(input, thisPage, part.getTransferEncoding()); if (thisPage.getTerminateRequest()) { return; } part.setContents(extract); thisPage.addElement(part); break; } else { thisPage.addMessage("service method - Parsing line: " + value); part.parseLine(value); } } } if (thisPage.getEndOfPacket()) { break; } } if (thisPage.getTerminateRequest()) { return; } starter(thisPage); if (thisPage.getTerminateRequest()) { return; } processor(thisPage); if (thisPage.getTerminateRequest()) { return; } ender(thisPage); if (thisPage.getTerminateRequest()) { return; } if (thisPage.getRedirectAddress() != null) { thisPage .getResponse() .sendRedirect(thisPage.getResponse().encodeRedirectURL(thisPage.getRedirectAddress())); } }
public Hashtable processData( ServletInputStream is, String boundary, String saveInDir, int clength) throws IllegalArgumentException, IOException { if (is == null) throw new IllegalArgumentException("InputStream"); if (boundary == null || boundary.trim().length() < 1) throw new IllegalArgumentException("\"" + boundary + "\" is an illegal boundary indicator"); boundary = "--" + boundary; StringTokenizer stLine = null, stFields = null; FileInfo fileInfo = null; Hashtable dataTable = new Hashtable(5); String line = null, field = null, paramName = null; boolean saveFiles = (saveInDir != null && saveInDir.trim().length() > 0); boolean isFile = false; if (saveFiles) { // Create the required directory (including parent dirs) File f = new File(saveInDir); f.mkdirs(); } line = getLine(is); if (line == null || !line.startsWith(boundary)) throw new IOException("Boundary not found; boundary = " + boundary + ", line = " + line); while (line != null) { if (line == null || !line.startsWith(boundary)) return dataTable; line = getLine(is); if (line == null) return dataTable; stLine = new StringTokenizer(line, ";\r\n"); if (stLine.countTokens() < 2) throw new IllegalArgumentException("Bad data in second line"); line = stLine.nextToken().toLowerCase(); if (line.indexOf("form-data") < 0) throw new IllegalArgumentException("Bad data in second line"); stFields = new StringTokenizer(stLine.nextToken(), "=\""); if (stFields.countTokens() < 2) throw new IllegalArgumentException("Bad data in second line"); fileInfo = new FileInfo(); stFields.nextToken(); paramName = stFields.nextToken(); isFile = false; if (stLine.hasMoreTokens()) { field = stLine.nextToken(); stFields = new StringTokenizer(field, "=\""); if (stFields.countTokens() > 1) { if (stFields.nextToken().trim().equalsIgnoreCase("filename")) { fileInfo.name = paramName; String value = stFields.nextToken(); if (value != null && value.trim().length() > 0) { fileInfo.clientFileName = value; isFile = true; } else { line = getLine(is); // Skip "Content-Type:" line line = getLine(is); // Skip blank line line = getLine(is); // Skip blank line line = getLine(is); // Position to boundary line continue; } } } else if (field.toLowerCase().indexOf("filename") >= 0) { line = getLine(is); // Skip "Content-Type:" line line = getLine(is); // Skip blank line line = getLine(is); // Skip blank line line = getLine(is); // Position to boundary line continue; } } boolean skipBlankLine = true; if (isFile) { line = getLine(is); if (line == null) return dataTable; if (line.trim().length() < 1) skipBlankLine = false; else { stLine = new StringTokenizer(line, ": "); if (stLine.countTokens() < 2) throw new IllegalArgumentException("Bad data in third line"); stLine.nextToken(); // Content-Type fileInfo.fileContentType = stLine.nextToken(); } } if (skipBlankLine) { line = getLine(is); if (line == null) return dataTable; } if (!isFile) { line = getLine(is); if (line == null) return dataTable; dataTable.put(paramName, line); // If parameter is dir, change saveInDir to dir if (paramName.equals("dir")) saveInDir = line; line = getLine(is); continue; } try { UplInfo uplInfo = new UplInfo(clength); UploadMonitor.set(fileInfo.clientFileName, uplInfo); OutputStream os = null; String path = null; if (saveFiles) os = new FileOutputStream(path = getFileName(saveInDir, fileInfo.clientFileName)); else os = new ByteArrayOutputStream(ONE_MB); boolean readingContent = true; byte previousLine[] = new byte[2 * ONE_MB]; byte temp[] = null; byte currentLine[] = new byte[2 * ONE_MB]; int read, read3; if ((read = is.readLine(previousLine, 0, previousLine.length)) == -1) { line = null; break; } while (readingContent) { if ((read3 = is.readLine(currentLine, 0, currentLine.length)) == -1) { line = null; uplInfo.aborted = true; break; } if (compareBoundary(boundary, currentLine)) { os.write(previousLine, 0, read - 2); line = new String(currentLine, 0, read3); break; } else { os.write(previousLine, 0, read); uplInfo.currSize += read; temp = currentLine; currentLine = previousLine; previousLine = temp; read = read3; } // end else } // end while os.flush(); os.close(); if (!saveFiles) { ByteArrayOutputStream baos = (ByteArrayOutputStream) os; fileInfo.setFileContents(baos.toByteArray()); } else fileInfo.file = new File(path); dataTable.put(paramName, fileInfo); uplInfo.currSize = uplInfo.totalSize; } // end try catch (IOException e) { throw e; } } return dataTable; }
long readPart(String encoding, String boundary, ServletInputStream sis, ServletAccessDescr sad) throws IOException { long currentPos = 0; byte[] buff = new byte[BUFF_SIZE * 1024]; int boundaryLen = boundary.length(); if (boundaryLen >= (buff.length - 2)) throw new IOException( "Boundary length exceeds allowed:" + boundaryLen + "/" + (buff.length - 2)); String hl; int ss; // parse part headers do { int len = sis.readLine(buff, 0, buff.length); if (len < 0) throw new IOException("Trying reading parts after EOS"); currentPos += len; if (buff[len - 1] != '\n') throw new IOException("Part header is over " + buff.length); hl = new String(buff, 0, len - 2, "US-ASCII"); // System.err.println("h:" + hl); if (hl.length() == 0) break; ss = hl.indexOf(boundary); if (ss >= 0) { if (hl.indexOf("--", boundaryLen + ss) == boundaryLen + ss) return -currentPos; // continue; // 1st part starts with it } hl = new String(buff, 0, len - 2, encoding); ss = hl.indexOf(':'); if (ss < 0) throw new IOException("Illegal multipart header, no value separator ':' in " + hl); String header = hl.substring(0, ss).toLowerCase(); String value = hl.substring(ss + 1).trim(); headers.put(header, value); if (header.equals("Content-Disposition".toLowerCase())) { // TODO add real parser as for cookies if (name != null) throw new IOException("Multiple header 'Content-Disposition' for the same part: " + hl); int ni = value.toLowerCase().indexOf("name=\""); if (ni < 0) throw new IOException("Part name is missed in 'Content-Disposition'" + hl); int eq = value.indexOf('"', ni + "name=\"".length()); // TODO name can be encoded so right approach is decoding it here name = value.substring(ni + "name=\"".length(), eq); ni = value.toLowerCase().indexOf("filename=\""); if (ni >= 0) { eq = value.indexOf('"', ni + "filename=\"".length()); filename = value.substring(ni + "filename=\"".length(), eq); } } // TODO Analyze content-type multipart/mixed defining new boundary, so they need to be // stacked } while (true); // TODO for content type multipart/mixed need another loop for another boundary // read part content fileSize = 0; boolean writingInMem = sad.multipartThreshold > 0; OutputStream wos = cos; int state = no_rn; try { read_part: do { int len = sis.readLine(buff, 0, buff.length); if (len < 0) throw new IOException("Unexpected end of multipart data at " + currentPos); // System.err.println("" + len + "==" + new String(buff, 0, len)); switch (state) { case no_rn: if (buff[len - 1] == '\n') { if (len > 1) if (buff[len - 2] == '\r') { wos.write(buff, 0, len - 2); fileSize += len - 2; state = last_rn; break; } } else if (buff[len - 1] == '\r') { wos.write(buff, 0, len - 1); fileSize += len - 1; state = last_r; break; } wos.write(buff, 0, len); fileSize += len; break; case last_r: if (buff[len - 1] == '\n') { if (len == 1) { state = last_rn; break; } if (buff[len - 2] == '\r') { wos.write('\r'); fileSize++; wos.write(buff, 0, len - 2); fileSize += len - 2; state = last_rn; break; } } else if (buff[len - 1] == '\r') { wos.write('\r'); fileSize++; wos.write(buff, 0, len - 1); fileSize += len - 1; state = last_r; break; } wos.write('\r'); fileSize++; wos.write(buff, 0, len); fileSize += len; state = no_rn; break; case last_rn: if (buff[len - 1] == '\n') { if (len > 1) if (buff[len - 2] == '\r') { hl = new String(buff, 0, len - 2, "US-ASCII"); ss = hl.indexOf(boundary); if (ss >= 0) { if (hl.indexOf("--", ss + boundaryLen) == (ss + boundaryLen)) return -currentPos - fileSize; else break read_part; } else { wos.write('\r'); fileSize++; wos.write('\n'); fileSize++; wos.write(buff, 0, len - 2); fileSize += len - 2; break; } } } else if (buff[len - 1] == '\r') { // can't be boundary limiter since buffer is bigger than boundary } wos.write('\r'); fileSize++; wos.write('\n'); fileSize++; wos.write(buff, 0, len); fileSize += len; state = no_rn; break; default: throw new IllegalStateException(); } if (sad.multipartMaxFile > 0 && sad.multipartMaxFile <= fileSize) throw new IOException("File size exceeds limit of " + sad.multipartMaxFile); if (writingInMem && sad.multipartThreshold < fileSize) { if (sad.multipartLocation == null || sad.multipartLocation.getName().length() == 0) partFile = File.createTempFile(name, "multipart"); else partFile = File.createTempFile(name, "multipart", sad.multipartLocation); partFile.deleteOnExit(); wos = new FileOutputStream(partFile); wos.write(cos.toByteArray()); cos.close(); cos = null; writingInMem = false; } } while (true); // TODO add condition } finally { if (wos != null) { // can b e null ? try { wos.close(); } catch (Exception e) { } } } return currentPos + fileSize; }