All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.grizzly.tcp.Request Maven / Gradle / Ivy

There is a newer version: 1.9.65
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 1997-2008 Sun Microsystems, Inc. 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.html
 * or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [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.tcp;

import com.sun.grizzly.util.buf.ByteChunk;
import com.sun.grizzly.util.buf.MessageBytes;
import com.sun.grizzly.util.buf.UDecoder;
import com.sun.grizzly.util.http.ContentType;
import com.sun.grizzly.util.http.Cookies;
import com.sun.grizzly.util.http.MimeHeaders;
import com.sun.grizzly.util.http.Parameters;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;



/**
 * This is a low-level, efficient representation of a server request. Most 
 * fields are GC-free, expensive operations are delayed until the  user code 
 * needs the information.
 *
 * Processing is delegated to modules, using a hook mechanism.
 * 
 * This class is not intended for user code - it is used internally by tomcat
 * for processing the request in the most efficient way. Users ( servlets ) can
 * access the information using a facade, which provides the high-level view
 * of the request.
 *
 * For lazy evaluation, the request uses the getInfo() hook. The following ids
 * are defined:
 * 
    *
  • req.encoding - returns the request encoding *
  • req.attribute - returns a module-specific attribute ( like SSL keys, etc ). *
* * Tomcat defines a number of attributes: *
    *
  • "org.apache.tomcat.request" - allows access to the low-level * request object in trusted applications *
* * @author James Duncan Davidson [[email protected]] * @author James Todd [[email protected]] * @author Jason Hunter [[email protected]] * @author Harish Prabandham * @author Alex Cruikshank [[email protected]] * @author Hans Bergsten [[email protected]] * @author Costin Manolache * @author Remy Maucherat */ public class Request { // ----------------------------------------------------------- Constructors public Request() { parameters.setQuery(queryMB); parameters.setURLDecoder(urlDecoder); parameters.setHeaders(headers); schemeMB.setString("http"); methodMB.setString("GET"); /* SJSWS 6376484 uriMB.setString("/"); */ queryMB.setString(""); protoMB.setString("HTTP/1.0"); } // ----------------------------------------------------- Instance Variables private int serverPort = -1; private MessageBytes serverNameMB = MessageBytes.newInstance(); private String localHost; private int remotePort; private int localPort; private MessageBytes schemeMB = MessageBytes.newInstance(); private MessageBytes methodMB = MessageBytes.newInstance(); private MessageBytes unparsedURIMB = MessageBytes.newInstance(); private MessageBytes uriMB = MessageBytes.newInstance(); private MessageBytes decodedUriMB = MessageBytes.newInstance(); private MessageBytes queryMB = MessageBytes.newInstance(); private MessageBytes protoMB = MessageBytes.newInstance(); // remote address/host private MessageBytes remoteAddrMB = MessageBytes.newInstance(); private MessageBytes localNameMB = MessageBytes.newInstance(); private MessageBytes remoteHostMB = MessageBytes.newInstance(); private MessageBytes localAddrMB = MessageBytes.newInstance(); private MimeHeaders headers = new MimeHeaders(); private MessageBytes instanceId = MessageBytes.newInstance(); /** * Notes. */ private NotesManagerImpl notesManager = new NotesManagerImpl(); /** * Associated input buffer. */ private InputBuffer inputBuffer = null; /** * URL decoder. */ private UDecoder urlDecoder = new UDecoder(); /** * HTTP specific fields. (remove them ?) */ private long contentLength = -1; private MessageBytes contentTypeMB = null; private String charEncoding = null; private boolean charEncodingParsed = false; private Cookies cookies = new Cookies(headers); private Parameters parameters = new Parameters(); private MessageBytes remoteUser = MessageBytes.newInstance(); private MessageBytes authType = MessageBytes.newInstance(); private Map attributes = new ConcurrentHashMap(); private Response response; private ActionHook hook; private int bytesRead=0; // Time of the request - usefull to avoid repeated calls to System.currentTime private long startTime = 0L; private RequestInfo reqProcessorMX=new RequestInfo(this); // ------------------------------------------------------------- Properties /** * Get the instance id (or JVM route). Curently Ajp is sending it with each * request. In future this should be fixed, and sent only once ( or * 'negociated' at config time so both tomcat and apache share the same name. * * @return the instance id */ public MessageBytes instanceId() { return instanceId; } public MimeHeaders getMimeHeaders() { return headers; } public UDecoder getURLDecoder() { return urlDecoder; } // -------------------- Request data -------------------- public MessageBytes scheme() { return schemeMB; } public MessageBytes method() { return methodMB; } public MessageBytes unparsedURI() { return unparsedURIMB; } public MessageBytes requestURI() { return uriMB; } public MessageBytes decodedURI() { return decodedUriMB; } public MessageBytes query() { return queryMB; } public MessageBytes queryString() { return queryMB; } public MessageBytes protocol() { return protoMB; } /** * Return the buffer holding the server name, if * any. Use isNull() to check if there is no value * set. * This is the "virtual host", derived from the * Host: header. */ public MessageBytes serverName() { return serverNameMB; } public int getServerPort() { return serverPort; } public void setServerPort(int serverPort ) { this.serverPort=serverPort; } /** * After #action with ActionCode.ACTION_REQ_HOST_ADDR_ATTRIBUTE is called, * returns remote address of the client that made the request. Otherwise * returns null. * * @return remote address or null */ public MessageBytes remoteAddr() { return remoteAddrMB; } public MessageBytes remoteHost() { return remoteHostMB; } public MessageBytes localName() { return localNameMB; } public MessageBytes localAddr() { return localAddrMB; } public String getLocalHost() { return localHost; } public void setLocalHost(String host) { this.localHost = host; } public int getRemotePort(){ return remotePort; } public void setRemotePort(int port){ this.remotePort = port; } public int getLocalPort(){ return localPort; } public void setLocalPort(int port){ this.localPort = port; } // -------------------- encoding/type -------------------- /** * Get the character encoding used for this request. */ public String getCharacterEncoding() { if (charEncoding != null || charEncodingParsed) { return charEncoding; } charEncoding = ContentType.getCharsetFromContentType(getContentType()); charEncodingParsed = true; return charEncoding; } public void setCharacterEncoding(String enc) { this.charEncoding = enc; } public void setContentLength(int len) { this.contentLength = len; } public int getContentLength() { long length = getContentLengthLong(); if (length < Integer.MAX_VALUE) { return (int) length; } return -1; } public long getContentLengthLong() { if( contentLength > -1 ) return contentLength; MessageBytes clB = headers.getUniqueValue("content-length"); contentLength = (clB == null || clB.isNull()) ? -1 : clB.getLong(); return contentLength; } public String getContentType() { contentType(); if ((contentTypeMB == null) || contentTypeMB.isNull()) return null; return contentTypeMB.toString(); } public void setContentType(String type) { contentTypeMB.setString(type); } public MessageBytes contentType() { if (contentTypeMB == null) contentTypeMB = headers.getValue("content-type"); return contentTypeMB; } public void setContentType(MessageBytes mb) { contentTypeMB=mb; } public String getHeader(String name) { return headers.getHeader(name); } // -------------------- Associated response -------------------- public Response getResponse() { return response; } public void setResponse( Response response ) { this.response=response; response.setRequest( this ); } public void action(ActionCode actionCode, Object param) { if( hook==null && response!=null ) hook=response.getHook(); if (hook != null) { if( param==null ) hook.action(actionCode, this); else hook.action(actionCode, param); } } // -------------------- Cookies -------------------- public Cookies getCookies() { return cookies; } // -------------------- Parameters -------------------- public Parameters getParameters() { return parameters; } // -------------------- Other attributes -------------------- // We can use notes for most - need to discuss what is of general interest public void setAttribute( String name, Object o ) { attributes.put( name, o ); } public Map getAttributes() { return attributes; } public Object getAttribute(String name ) { return attributes.get(name); } public MessageBytes getRemoteUser() { return remoteUser; } public MessageBytes getAuthType() { return authType; } // -------------------- Input Buffer -------------------- public InputBuffer getInputBuffer() { return inputBuffer; } public void setInputBuffer(InputBuffer inputBuffer) { this.inputBuffer = inputBuffer; } /** * Read data from the input buffer and put it into a byte chunk. * * The buffer is owned by the protocol implementation - it will be reused * on the next read. * The Adapter must either process the data in place or copy it to a * separate buffer if it needs to hold it. In most cases this is done * during byte->char conversions or via InputStream. Unlike InputStream, * this interface allows the app to process data in place, without copy. */ public int doRead(ByteChunk chunk) throws IOException { int n = inputBuffer.doRead(chunk, this); if (n > 0) { bytesRead+=n; } return n; } // -------------------- debug -------------------- public String toString() { return "R( " + requestURI().toString() + ")"; } public long getStartTime() { return startTime; } public void setStartTime(long startTime) { this.startTime = startTime; } // -------------------- Per-Request "notes" -------------------- public final void setNote(int pos, Object value) { notesManager.setNote(pos,value); } public final Object getNote(int pos) { return notesManager.getNote(pos); } public NotesManagerImpl getNotesManager() { return notesManager; } public void setNotesManager(NotesManagerImpl notesManager) { this.notesManager = notesManager; } // -------------------- Recycling -------------------- public void recycle() { bytesRead=0; contentLength = -1; contentTypeMB = null; charEncoding = null; charEncodingParsed = false; headers.recycle(); serverNameMB.recycle(); serverPort=-1; localPort = -1; remotePort = -1; cookies.recycle(); parameters.recycle(); unparsedURIMB.recycle(); uriMB.recycle(); decodedUriMB.recycle(); queryMB.recycle(); methodMB.recycle(); protoMB.recycle(); //remoteAddrMB.recycle(); //remoteHostMB.recycle(); // XXX Do we need such defaults ? schemeMB.recycle(); schemeMB.setString("http"); methodMB.setString("GET"); /* SJSWS 6376484 uriMB.setString("/"); */ queryMB.setString(""); protoMB.setString("HTTP/1.0"); //remoteAddrMB.setString("127.0.0.1"); //remoteHostMB.setString("localhost"); instanceId.recycle(); remoteUser.recycle(); authType.recycle(); attributes.clear(); } // -------------------- Info -------------------- public void updateCounters() { reqProcessorMX.updateCounters(); } public RequestInfo getRequestProcessor() { return reqProcessorMX; } public int getBytesRead() { return bytesRead; } public void setBytesRead(int bytesRead) { this.bytesRead = bytesRead; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy