Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2009-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.grizzly.http.jk.common;
import com.sun.grizzly.http.jk.core.Msg;
import com.sun.grizzly.http.jk.core.MsgContext;
import java.io.IOException;
import com.sun.grizzly.tcp.OutputBuffer;
import com.sun.grizzly.tcp.InputBuffer;
import com.sun.grizzly.tcp.Request;
import com.sun.grizzly.tcp.Response;
import com.sun.grizzly.util.LoggerUtils;
import com.sun.grizzly.util.buf.ByteChunk;
import com.sun.grizzly.util.buf.MessageBytes;
import com.sun.grizzly.util.buf.C2BConverter;
import com.sun.grizzly.util.http.HttpMessages;
import com.sun.grizzly.util.http.MimeHeaders;
import java.util.logging.Level;
/** Generic input stream impl on top of ajp
*/
public class JkInputStream implements InputBuffer, OutputBuffer {
private Msg bodyMsg;
private Msg outputMsg;
private MsgContext mc;
// Holds incoming chunks of request body data
private MessageBytes bodyBuff = MessageBytes.newInstance();
private MessageBytes tempMB = MessageBytes.newInstance();
private boolean end_of_stream = false;
private boolean isEmpty = true;
private boolean isFirst = true;
private boolean isReplay = false;
private boolean isReadRequired = false;
static {
// Make certain HttpMessages is loaded for SecurityManager
try {
Class.forName("com.sun.grizzly.util.http.HttpMessages");
} catch (Exception ex) {
// ignore
}
}
public JkInputStream(MsgContext context, int bsize) {
mc = context;
bodyMsg = new MsgAjp(bsize);
outputMsg = new MsgAjp(bsize);
}
/**
* @deprecated
*/
public JkInputStream(MsgContext context) {
this(context, 8 * 1024);
}
// -------------------- Jk specific methods --------------------
/**
* Set the flag saying that the server is sending a body
*/
public void setIsReadRequired(boolean irr) {
isReadRequired = irr;
}
/**
* Return the flag saying that the server is sending a body
*/
public boolean isReadRequired() {
return isReadRequired;
}
/** Must be called before or after each request
*/
public void recycle() {
if (isReadRequired && isFirst) {
// The Servlet never read the request body, so we need to junk it
try {
receive();
} catch (IOException iex) {
LoggerUtils.getLogger().log(Level.FINEST, "Error consuming request body", iex);
}
}
end_of_stream = false;
isEmpty = true;
isFirst = true;
isReplay = false;
isReadRequired = false;
bodyBuff.recycle();
tempMB.recycle();
}
public void endMessage() throws IOException {
outputMsg.reset();
outputMsg.appendByte(AjpConstants.JK_AJP13_END_RESPONSE);
outputMsg.appendByte(1);
mc.getSource().send(outputMsg, mc);
mc.getSource().flush(outputMsg, mc);
}
// -------------------- OutputBuffer implementation --------------------
public int doWrite(ByteChunk chunk, Response res)
throws IOException {
if (!res.isCommitted()) {
// Send the connector a request for commit. The connector should
// then validate the headers, send them (using sendHeader) and
// set the filters accordingly.
res.sendHeaders();
}
int len = chunk.getLength();
byte buf[] = outputMsg.getBuffer();
// 4 - hardcoded, byte[] marshalling overhead
int chunkSize = buf.length - outputMsg.getHeaderLength() - 4;
int off = 0;
while (len > 0) {
int thisTime = len;
if (thisTime > chunkSize) {
thisTime = chunkSize;
}
len -= thisTime;
outputMsg.reset();
outputMsg.appendByte(AjpConstants.JK_AJP13_SEND_BODY_CHUNK);
outputMsg.appendBytes(chunk.getBytes(), chunk.getOffset() + off, thisTime);
off += thisTime;
mc.getSource().send(outputMsg, mc);
}
return 0;
}
public int doRead(ByteChunk responseChunk, Request req)
throws IOException {
if (LoggerUtils.getLogger().isLoggable(Level.FINEST)) {
LoggerUtils.getLogger().log(Level.FINEST, "doRead " + end_of_stream +
" " + responseChunk.getOffset() + " " + responseChunk.getLength());
}
if (end_of_stream) {
return -1;
}
if (isFirst && isReadRequired) {
// Handle special first-body-chunk, but only if httpd expects it.
if (!receive()) {
return 0;
}
} else if (isEmpty) {
if (!refillReadBuffer()) {
return -1;
}
}
ByteChunk bc = bodyBuff.getByteChunk();
responseChunk.setBytes(bc.getBuffer(), bc.getStart(), bc.getLength());
isEmpty = true;
return responseChunk.getLength();
}
/** Receive a chunk of data. Called to implement the
* 'special' packet in ajp13 and to receive the data
* after we send a GET_BODY packet
*/
public boolean receive() throws IOException {
isFirst = false;
bodyMsg.reset();
int err = mc.getSource().receive(bodyMsg, mc);
if (LoggerUtils.getLogger().isLoggable(Level.FINEST)) {
LoggerUtils.getLogger().info("Receiving: getting request body chunk " + err + " " + bodyMsg.getLen());
}
if (err < 0) {
throw new IOException();
}
// No data received.
if (bodyMsg.getLen() == 0) { // just the header
// Don't mark 'end of stream' for the first chunk.
// end_of_stream = true;
return false;
}
int blen = bodyMsg.peekInt();
if (blen == 0) {
return false;
}
bodyMsg.getBytes(bodyBuff);
isEmpty = false;
return true;
}
/**
* Get more request body data from the web server and store it in the
* internal buffer.
*
* @return true if there is more data, false if not.
*/
private boolean refillReadBuffer() throws IOException {
// If the server returns an empty packet, assume that that end of
// the stream has been reached (yuck -- fix protocol??).
if (isReplay) {
end_of_stream = true; // we've read everything there is
}
if (end_of_stream) {
if (LoggerUtils.getLogger().isLoggable(Level.FINEST)) {
LoggerUtils.getLogger().log(Level.FINEST, "refillReadBuffer: end of stream ");
}
return false;
}
// Why not use outBuf??
bodyMsg.reset();
bodyMsg.appendByte(AjpConstants.JK_AJP13_GET_BODY_CHUNK);
bodyMsg.appendInt(AjpConstants.MAX_READ_SIZE);
if (LoggerUtils.getLogger().isLoggable(Level.FINEST)) {
LoggerUtils.getLogger().log(Level.FINEST, "refillReadBuffer " + Thread.currentThread());
}
mc.getSource().send(bodyMsg, mc);
mc.getSource().flush(bodyMsg, mc); // Server needs to get it
// In JNI mode, response will be in bodyMsg. In TCP mode, response need to be
// read
boolean moreData = receive();
if (!moreData) {
end_of_stream = true;
}
return moreData;
}
public void appendHead(Response res) throws IOException {
if (LoggerUtils.getLogger().isLoggable(Level.FINEST)) {
LoggerUtils.getLogger().log(Level.FINEST, "COMMIT sending headers " + res + " " + res.getMimeHeaders());
}
C2BConverter c2b = mc.getConverter();
outputMsg.reset();
outputMsg.appendByte(AjpConstants.JK_AJP13_SEND_HEADERS);
outputMsg.appendInt(res.getStatus());
String message = null;
// if (com.sun.grizzly.tcp.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER) {
message = res.getMessage();
// }
if (message == null) {
message = HttpMessages.getMessage(res.getStatus());
} else {
message = message.replace('\n', ' ').replace('\r', ' ');
}
tempMB.setString(message);
c2b.convert(tempMB);
outputMsg.appendBytes(tempMB);
// XXX add headers
MimeHeaders headers = res.getMimeHeaders();
String contentType = res.getContentType();
if (contentType != null) {
headers.setValue("Content-Type").setString(contentType);
}
String contentLanguage = res.getContentLanguage();
if (contentLanguage != null) {
headers.setValue("Content-Language").setString(contentLanguage);
}
long contentLength = res.getContentLengthLong();
if (contentLength >= 0) {
headers.setValue("Content-Length").setLong(contentLength);
}
int numHeaders = headers.size();
outputMsg.appendInt(numHeaders);
for (int i = 0; i < numHeaders; i++) {
MessageBytes hN = headers.getName(i);
// no header to sc conversion - there's little benefit
// on this direction
c2b.convert(hN);
outputMsg.appendBytes(hN);
MessageBytes hV = headers.getValue(i);
c2b.convert(hV);
outputMsg.appendBytes(hV);
}
mc.getSource().send(outputMsg, mc);
}
/**
* Set the replay buffer for Form auth
*/
public void setReplay(ByteChunk replay) {
isFirst = false;
isEmpty = false;
isReplay = true;
bodyBuff.setBytes(replay.getBytes(), replay.getStart(), replay.getLength());
}
}