/** * Read bytes. * * @return If the filter does request length control, this value is significant; it should be the * number of bytes consumed from the buffer, up until the end of the current request body, or * the buffer length, whichever is greater. If the filter does not do request body length * control, the returned value should be -1. */ public int doRead(ByteChunk chunk, Request req) throws IOException { if (endChunk) return -1; if (needCRLFParse) { needCRLFParse = false; parseCRLF(); } if (remaining <= 0) { if (!parseChunkHeader()) { throw new IOException("Invalid chunk header"); } if (endChunk) { parseEndChunk(); return -1; } } int result = 0; if (pos >= lastValid) { readBytes(); } if (remaining > (lastValid - pos)) { result = lastValid - pos; remaining = remaining - result; chunk.setBytes(buf, pos, result); pos = lastValid; } else { result = remaining; chunk.setBytes(buf, pos, remaining); pos = pos + remaining; remaining = 0; // we need a CRLF if ((pos + 1) >= lastValid) { // if we call parseCRLF we overrun the buffer here // so we defer it to the next call BZ 11117 needCRLFParse = true; } else { parseCRLF(); // parse the CRLF immediately } } return result; }
/** * Customize the error pahe * * @param req The {@link Request} object * @param res The {@link Response} object * @throws Exception */ protected void customizedErrorPage(Request req, Response res) throws Exception { /** With Grizzly, we just return a 404 with a simple error message. */ res.setMessage("Not Found"); res.setStatus(404); ByteBuffer bb = HtmlHelper.getErrorPage("Not Found", "HTTP/1.1 404 Not Found\r\n", "Grizzly"); res.setContentLength(bb.limit()); res.setContentType("text/html"); res.flushHeaders(); if (res.getChannel() != null) { res.getChannel().write(bb); req.setNote(14, "SkipAfterService"); } else { byte b[] = new byte[bb.limit()]; bb.get(b); ByteChunk chunk = new ByteChunk(); chunk.setBytes(b, 0, b.length); res.doWrite(chunk); } }
/** * Lookup a resource based on the request URI, and send it using send file. * * @param uri The request URI * @param req the {@link Request} * @param res the {@link Response} * @throws Exception */ protected void service(String uri, Request req, final Response res) throws Exception { FileInputStream fis = null; try { initWebDir(); boolean found = false; File resource = null; for (File webDir : fileFolders) { // local file resource = cache.get(uri); if (resource == null) { resource = new File(webDir, uri); if (resource.exists() && resource.isDirectory()) { final File f = new File(resource, "/index.html"); if (f.exists()) { resource = f; found = true; break; } } } if (resource.isDirectory() || !resource.exists()) { found = false; } else { found = true; break; } } cache.put(uri, resource); if (!found) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "File not found " + resource); } res.setStatus(404); if (commitErrorResponse) { customizedErrorPage(req, res); } return; } res.setStatus(200); String substr; int dot = uri.lastIndexOf("."); if (dot < 0) { substr = resource.toString(); dot = substr.lastIndexOf("."); } else { substr = uri; } if (dot > 0) { String ext = substr.substring(dot + 1); String ct = MimeType.get(ext, defaultContentType); if (ct != null) { res.setContentType(ct); } } else { res.setContentType(defaultContentType); } long length = resource.length(); res.setContentLengthLong(length); // Send the header, and flush the bytes as we will now move to use // send file. res.sendHeaders(); if (req.method().toString().equalsIgnoreCase("HEAD")) { return; } fis = new FileInputStream(resource); OutputBuffer outputBuffer = res.getOutputBuffer(); if (useSendFile && (outputBuffer instanceof FileOutputBuffer) && ((FileOutputBuffer) outputBuffer).isSupportFileSend()) { res.flush(); long nWrite = 0; while (nWrite < length) { nWrite += ((FileOutputBuffer) outputBuffer).sendFile(fis.getChannel(), nWrite, length - nWrite); } } else { byte b[] = new byte[8192]; ByteChunk chunk = new ByteChunk(); int rd; while ((rd = fis.read(b)) > 0) { chunk.setBytes(b, 0, rd); res.doWrite(chunk); } } } finally { if (fis != null) { try { fis.close(); } catch (IOException ignored) { } } } }
static { ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME.length()); }