📄 ajp13generator.java
字号:
//========================================================================//Copyright 2006 Mort Bay Consulting Pty. Ltd.//------------------------------------------------------------------------//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 org.mortbay.jetty.ajp;import java.io.IOException;import java.util.HashMap;import java.util.Iterator;import org.mortbay.io.Buffer;import org.mortbay.io.Buffers;import org.mortbay.io.ByteArrayBuffer;import org.mortbay.io.EndPoint;import org.mortbay.jetty.*;import org.mortbay.jetty.HttpFields.Field;import org.mortbay.log.Log;import org.mortbay.util.TypeUtil;/** * @author lagdeppa (at) exist.com * @author Greg Wilkins */ public class Ajp13Generator extends AbstractGenerator{ private static HashMap __headerHash = new HashMap(); static { byte[] xA001 = { (byte) 0xA0, (byte) 0x01 }; byte[] xA002 = { (byte) 0xA0, (byte) 0x02 }; byte[] xA003 = { (byte) 0xA0, (byte) 0x03 }; byte[] xA004 = { (byte) 0xA0, (byte) 0x04 }; byte[] xA005 = { (byte) 0xA0, (byte) 0x05 }; byte[] xA006 = { (byte) 0xA0, (byte) 0x06 }; byte[] xA007 = { (byte) 0xA0, (byte) 0x07 }; byte[] xA008 = { (byte) 0xA0, (byte) 0x08 }; byte[] xA009 = { (byte) 0xA0, (byte) 0x09 }; byte[] xA00A = { (byte) 0xA0, (byte) 0x0A }; byte[] xA00B = { (byte) 0xA0, (byte) 0x0B }; __headerHash.put("Content-Type", xA001); __headerHash.put("Content-Language", xA002); __headerHash.put("Content-Length", xA003); __headerHash.put("Date", xA004); __headerHash.put("Last-Modified", xA005); __headerHash.put("Location", xA006); __headerHash.put("Set-Cookie", xA007); __headerHash.put("Set-Cookie2", xA008); __headerHash.put("Servlet-Engine", xA009); __headerHash.put("Status", xA00A); __headerHash.put("WWW-Authenticate", xA00B); } // A, B ajp response header // 0, 1 ajp int 1 packet length // 9 CPONG response Code private static final byte[] AJP13_CPONG_RESPONSE = { 'A', 'B', 0, 1, 9}; private static final byte[] AJP13_END_RESPONSE = { 'A', 'B', 0, 2, 5, 1 }; // AB ajp respose // 0, 3 int = 3 packets in length // 6, send signal to get more data // 31, -7 byte values for int 8185 = (8 * 1024) - 7 MAX_DATA private static final byte[] AJP13_MORE_CONTENT = { 'A', 'B', 0, 3, 6, 31, -7 }; private static String SERVER = "Server: Jetty(6.0.x)"; public static void setServerVersion(String version) { SERVER = "Jetty(" + version + ")"; } /* ------------------------------------------------------------ */ private boolean _expectMore = false; private boolean _needMore = false; private boolean _needEOC = false; private boolean _bufferPrepared = false; /* ------------------------------------------------------------ */ public Ajp13Generator(Buffers buffers, EndPoint io, int headerBufferSize, int contentBufferSize) { super(buffers, io, headerBufferSize, contentBufferSize); } /* ------------------------------------------------------------ */ public void reset(boolean returnBuffers) { super.reset(returnBuffers); _needEOC = false; _needMore = false; _expectMore = false; _bufferPrepared = false; _last=false; _state = STATE_HEADER; _status = 0; _version = HttpVersions.HTTP_1_1_ORDINAL; _reason = null; _method = null; _uri = null; _contentWritten = 0; _contentLength = HttpTokens.UNKNOWN_CONTENT; _last = false; _head = false; _noContent = false; _close = false; _header = null; // Buffer for HTTP header (and maybe small _content) _buffer = null; // Buffer for copy of passed _content _content = null; // Buffer passed to addContent } /* ------------------------------------------------------------ */ /** * Add content. * * @param content * @param last * @throws IllegalArgumentException * if <code>content</code> is * {@link Buffer#isImmutable immutable}. * @throws IllegalStateException * If the request is not expecting any more content, or if the * buffers are full and cannot be flushed. * @throws IOException * if there is a problem flushing the buffers. */ public void addContent(Buffer content, boolean last) throws IOException { if (_noContent) { content.clear(); return; } if (content.isImmutable()) throw new IllegalArgumentException("immutable"); if (_last || _state == STATE_END) { Log.debug("Ignoring extra content {}", content); content.clear(); return; } _last = last; if(!_endp.isOpen()) { _state = STATE_END; return; } // Handle any unfinished business? if (_content != null && _content.length() > 0) { flush(); if (_content != null && _content.length() > 0) throw new IllegalStateException("FULL"); } _content = content; _contentWritten += content.length(); // Handle the _content if (_head) { content.clear(); _content = null; } else { // Yes - so we better check we have a buffer initContent(); // Copy _content to buffer; int len = 0; len = _buffer.put(_content); // make sure there is space for a trailing null if (len > 0 && _buffer.space() == 0) { len--; _buffer.setPutIndex(_buffer.putIndex() - 1); } _content.skip(len); if (_content.length() == 0) _content = null; } } /* ------------------------------------------------------------ */ /** * Add content. * * @param b * byte * @return true if the buffers are full * @throws IOException */ public boolean addContent(byte b) throws IOException { if (_noContent) return false; if (_last || _state == STATE_END) throw new IllegalStateException("Closed"); if(!_endp.isOpen()) { _state = STATE_END; return false; } // Handle any unfinished business? if (_content != null && _content.length() > 0) { flush(); if (_content != null && _content.length() > 0) throw new IllegalStateException("FULL"); } _contentWritten++; // Handle the _content if (_head) return false; // we better check we have a buffer initContent(); // Copy _content to buffer; _buffer.put(b); return _buffer.space() <= 1; } /* ------------------------------------------------------------ */ /** * Prepare buffer for unchecked writes. Prepare the generator buffer to * receive unchecked writes * * @return the available space in the buffer. * @throws IOException */ protected int prepareUncheckedAddContent() throws IOException { if (_noContent) return -1; if (_last || _state == STATE_END) throw new IllegalStateException("Closed"); if(!_endp.isOpen()) { _state = STATE_END; return -1; } // Handle any unfinished business? Buffer content = _content; if (content != null && content.length() > 0) { flush(); if (content != null && content.length() > 0) throw new IllegalStateException("FULL"); } // we better check we have a buffer initContent(); _contentWritten -= _buffer.length(); // Handle the _content if (_head) return Integer.MAX_VALUE; return _buffer.space() - 1; } /* ------------------------------------------------------------ */ public void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException { if (_state != STATE_HEADER) return; if (_last && !allContentAdded) throw new IllegalStateException("last?"); _last = _last | allContentAdded; boolean has_server = false; if (_version == HttpVersions.HTTP_1_0_ORDINAL) _close = true; // get a header buffer if (_header == null) _header = _buffers.getBuffer(_headerBufferSize); Buffer tmpbuf = _buffer; _buffer = _header; try { // start the header _buffer.put((byte) 'A'); _buffer.put((byte) 'B'); addInt(0); _buffer.put((byte) 0x4); addInt(_status); if (_reason == null) _reason = getReasonBuffer(_status); if (_reason == null) _reason = new ByteArrayBuffer(TypeUtil.toString(_status)); addBuffer(_reason); if (_status == 100 || _status == 204 || _status == 304) { _noContent = true; _content = null; } // allocate 2 bytes for number of headers int field_index = _buffer.putIndex(); addInt(0); int num_fields = 0; if (fields != null) { // Add headers Iterator i = fields.getFields(); while (i.hasNext()) { num_fields++; Field f = (Field) i.next(); byte[] codes = (byte[]) __headerHash.get(f.getName()); if (codes != null) { _buffer.put(codes); } else { addString(f.getName()); } addString(f.getValue()); } } if (!has_server && _status > 100 && getSendServerVersion()) { num_fields++; addString("Server");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -