1 //========================================================================
2 //Copyright 2006 Mort Bay Consulting Pty. Ltd.
3 //------------------------------------------------------------------------
4 //Licensed under the Apache License, Version 2.0 (the "License");
5 //you may not use this file except in compliance with the License.
6 //You may obtain a copy of the License at
7 //http://www.apache.org/licenses/LICENSE-2.0
8 //Unless required by applicable law or agreed to in writing, software
9 //distributed under the License is distributed on an "AS IS" BASIS,
10 //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 //See the License for the specific language governing permissions and
12 //limitations under the License.
13 //========================================================================
14 
15 package org.mortbay.jetty.ajp;
16 
17 import java.io.ByteArrayInputStream;
18 import java.io.IOException;
19 import java.security.cert.Certificate;
20 import java.security.cert.CertificateException;
21 import java.security.cert.CertificateFactory;
22 import java.security.cert.X509Certificate;
23 import java.util.Collection;
24 import java.util.Iterator;
25 
26 import javax.servlet.ServletInputStream;
27 import javax.servlet.http.HttpServletResponse;
28 
29 import org.mortbay.io.Buffer;
30 import org.mortbay.io.EndPoint;
31 import org.mortbay.jetty.Connector;
32 import org.mortbay.jetty.HttpConnection;
33 import org.mortbay.jetty.HttpException;
34 import org.mortbay.jetty.Request;
35 import org.mortbay.jetty.Server;
36 
37 /**
38  * Connection implementation of the Ajp13 protocol. <p/> XXX Refactor to remove
39  * duplication of HttpConnection
40  *
41  * @author Markus Kobler markus(at)inquisitive-mind.com
42  * @author Greg Wilkins
43  */
44 public class Ajp13Connection extends HttpConnection
45 {
46     private boolean _sslSecure = false;
47 
Ajp13Connection(Connector connector, EndPoint endPoint, Server server)48     public Ajp13Connection(Connector connector, EndPoint endPoint, Server server)
49     {
50         super(connector, endPoint, server,
51                 new Ajp13Parser(connector, endPoint),
52                 new Ajp13Generator(connector, endPoint, connector.getHeaderBufferSize(), connector.getResponseBufferSize()),
53                 new Ajp13Request()
54                 );
55 
56         ((Ajp13Parser)_parser).setEventHandler(new RequestHandler());
57         ((Ajp13Parser)_parser).setGenerator((Ajp13Generator)_generator);
58         ((Ajp13Request)_request).setConnection(this);
59     }
60 
isConfidential(Request request)61     public boolean isConfidential(Request request)
62     {
63         return _sslSecure;
64     }
65 
isIntegral(Request request)66     public boolean isIntegral(Request request)
67     {
68         return _sslSecure;
69     }
70 
getInputStream()71     public ServletInputStream getInputStream()
72     {
73         if (_in == null)
74             _in = new Ajp13Parser.Input((Ajp13Parser) _parser, _connector.getMaxIdleTime());
75         return _in;
76     }
77 
78     private class RequestHandler implements Ajp13Parser.EventHandler
79     {
80         boolean _delayedHandling = false;
81 
startForwardRequest()82         public void startForwardRequest() throws IOException
83         {
84             _delayedHandling = false;
85             _uri.clear();
86             _sslSecure = false;
87             _request.setTimeStamp(System.currentTimeMillis());
88             _request.setUri(_uri);
89 
90         }
91 
parsedAuthorizationType(Buffer authType)92         public void parsedAuthorizationType(Buffer authType) throws IOException
93         {
94             _request.setAuthType(authType.toString());
95         }
96 
parsedRemoteUser(Buffer remoteUser)97         public void parsedRemoteUser(Buffer remoteUser) throws IOException
98         {
99             ((Ajp13Request)_request).setRemoteUser(remoteUser.toString());
100         }
101 
parsedServletPath(Buffer servletPath)102         public void parsedServletPath(Buffer servletPath) throws IOException
103         {
104             _request.setServletPath(servletPath.toString());
105         }
106 
parsedContextPath(Buffer context)107         public void parsedContextPath(Buffer context) throws IOException
108         {
109             _request.setContextPath(context.toString());
110         }
111 
parsedSslCert(Buffer sslCert)112         public void parsedSslCert(Buffer sslCert) throws IOException
113         {
114             try
115             {
116                 CertificateFactory cf = CertificateFactory.getInstance("X.509");
117                 ByteArrayInputStream bis = new ByteArrayInputStream(sslCert.toString().getBytes());
118 
119                 Collection certCollection = cf.generateCertificates(bis);
120                 X509Certificate[] certificates = new X509Certificate[certCollection.size()];
121 
122                 int i=0;
123                 Iterator iter=certCollection.iterator();
124                 while(iter.hasNext())
125                     certificates[i++] = (X509Certificate)iter.next();
126 
127                 _request.setAttribute("javax.servlet.request.X509Certificate", certificates);
128             }
129             catch (Exception e)
130             {
131                 org.mortbay.log.Log.warn(e.toString());
132                 org.mortbay.log.Log.ignore(e);
133                 if (sslCert!=null)
134                     _request.setAttribute("javax.servlet.request.X509Certificate", sslCert.toString());
135             }
136         }
137 
parsedSslCipher(Buffer sslCipher)138         public void parsedSslCipher(Buffer sslCipher) throws IOException
139         {
140             _request.setAttribute("javax.servlet.request.cipher_suite", sslCipher.toString());
141         }
142 
parsedSslSession(Buffer sslSession)143         public void parsedSslSession(Buffer sslSession) throws IOException
144         {
145             _request.setAttribute("javax.servlet.request.ssl_session", sslSession.toString());
146         }
147 
parsedSslKeySize(int keySize)148         public void parsedSslKeySize(int keySize) throws IOException
149         {
150            _request.setAttribute("javax.servlet.request.key_size", new Integer(keySize));
151         }
152 
parsedMethod(Buffer method)153         public void parsedMethod(Buffer method) throws IOException
154         {
155             if (method == null)
156                 throw new HttpException(HttpServletResponse.SC_BAD_REQUEST);
157             _request.setMethod(method.toString());
158         }
159 
parsedUri(Buffer uri)160         public void parsedUri(Buffer uri) throws IOException
161         {
162             _uri.parse(uri.toString());
163         }
164 
parsedProtocol(Buffer protocol)165         public void parsedProtocol(Buffer protocol) throws IOException
166         {
167             if (protocol != null && protocol.length()>0)
168             {
169                 _request.setProtocol(protocol.toString());
170             }
171         }
172 
parsedRemoteAddr(Buffer addr)173         public void parsedRemoteAddr(Buffer addr) throws IOException
174         {
175             if (addr != null && addr.length()>0)
176             {
177                 ((Ajp13Request) _request).setRemoteAddr(addr.toString());
178             }
179         }
180 
parsedRemoteHost(Buffer name)181         public void parsedRemoteHost(Buffer name) throws IOException
182         {
183             if (name != null && name.length()>0)
184             {
185                 ((Ajp13Request) _request).setRemoteHost(name.toString());
186             }
187         }
188 
parsedServerName(Buffer name)189         public void parsedServerName(Buffer name) throws IOException
190         {
191             if (name != null && name.length()>0)
192             {
193                 _request.setServerName(name.toString());
194             }
195         }
196 
parsedServerPort(int port)197         public void parsedServerPort(int port) throws IOException
198         {
199             ((Ajp13Request) _request).setServerPort(port);
200         }
201 
parsedSslSecure(boolean secure)202         public void parsedSslSecure(boolean secure) throws IOException
203         {
204             _sslSecure = secure;
205         }
206 
parsedQueryString(Buffer value)207         public void parsedQueryString(Buffer value) throws IOException
208         {
209             String u = _uri + "?" + value;
210             _uri.parse(u);
211         }
212 
parsedHeader(Buffer name, Buffer value)213         public void parsedHeader(Buffer name, Buffer value) throws IOException
214         {
215             _requestFields.add(name, value);
216         }
217 
parsedRequestAttribute(String key, Buffer value)218         public void parsedRequestAttribute(String key, Buffer value) throws IOException
219         {
220             _request.setAttribute(key, value.toString());
221         }
222 
parsedRequestAttribute(String key, int value)223         public void parsedRequestAttribute(String key, int value) throws IOException
224         {
225             _request.setAttribute(key, Integer.toString(value));
226         }
227 
headerComplete()228         public void headerComplete() throws IOException
229         {
230             if (((Ajp13Parser) _parser).getContentLength() <= 0)
231             {
232                 handleRequest();
233             }
234             else
235             {
236                 _delayedHandling = true;
237             }
238         }
239 
messageComplete(long contextLength)240         public void messageComplete(long contextLength) throws IOException
241         {
242         }
243 
content(Buffer ref)244         public void content(Buffer ref) throws IOException
245         {
246             if (_delayedHandling)
247             {
248                 _delayedHandling = false;
249                 handleRequest();
250             }
251         }
252 
253     }
254 
255 }
256