1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */

17
18 package org.apache.coyote;
19
20 import javax.management.ObjectName;
21
22
23 /**
24  * Structure holding the Request and Response objects. It also holds statistical
25  * informations about request processing and provide management informations
26  * about the requests being processed.
27  *
28  * Each thread uses a Request/Response pair that is recycled on each request.
29  * This object provides a place to collect global low-level statistics - without
30  * having to deal with synchronization ( since each thread will have it's own
31  * RequestProcessorMX ).
32  *
33  * @author Costin Manolache
34  */

35 public class RequestInfo  {
36     private RequestGroupInfo global=null;
37
38     // ----------------------------------------------------------- Constructors
39
40     public RequestInfo( Request req) {
41         this.req=req;
42     }
43
44     public RequestGroupInfo getGlobalProcessor() {
45         return global;
46     }
47
48     public void setGlobalProcessor(RequestGroupInfo global) {
49         if( global != null) {
50             this.global=global;
51             global.addRequestProcessor( this );
52         } else {
53             if (this.global != null) {
54                 this.global.removeRequestProcessor( this );
55                 this.global = null;
56             }
57         }
58     }
59
60
61     // ----------------------------------------------------- Instance Variables
62     private final Request req;
63     private int stage = Constants.STAGE_NEW;
64     private String workerThreadName;
65     private ObjectName rpName;
66
67     // -------------------- Information about the current request  -----------
68     // This is useful for long-running requests only
69
70     public String getMethod() {
71         return req.method().toString();
72     }
73
74     public String getCurrentUri() {
75         return req.requestURI().toString();
76     }
77
78     public String getCurrentQueryString() {
79         return req.queryString().toString();
80     }
81
82     public String getProtocol() {
83         return req.protocol().toString();
84     }
85
86     public String getVirtualHost() {
87         return req.serverName().toString();
88     }
89
90     public int getServerPort() {
91         return req.getServerPort();
92     }
93
94     public String getRemoteAddr() {
95         req.action(ActionCode.REQ_HOST_ADDR_ATTRIBUTE, null);
96         return req.remoteAddr().toString();
97     }
98
99     /**
100      * Obtain the remote address for this connection as reported by an
101      * intermediate proxy (if any).
102      *
103      * @return The remote address for the this connection
104      */

105     public String getRemoteAddrForwarded() {
106         String remoteAddrProxy = (String) req.getAttribute(Constants.REMOTE_ADDR_ATTRIBUTE);
107         if (remoteAddrProxy == null) {
108             return getRemoteAddr();
109         }
110         return remoteAddrProxy;
111     }
112
113     public int getContentLength() {
114         return req.getContentLength();
115     }
116
117     public long getRequestBytesReceived() {
118         return req.getBytesRead();
119     }
120
121     public long getRequestBytesSent() {
122         return req.getResponse().getContentWritten();
123     }
124
125     public long getRequestProcessingTime() {
126         // Not perfect, but good enough to avoid returning strange values due to
127         // concurrent updates.
128         long startTime = req.getStartTime();
129         if (getStage() == org.apache.coyote.Constants.STAGE_ENDED || startTime < 0) {
130             return 0;
131         } else {
132             return System.currentTimeMillis() - startTime;
133         }
134     }
135
136     // -------------------- Statistical data  --------------------
137     // Collected at the end of each request.
138     private long bytesSent;
139     private long bytesReceived;
140
141     // Total time = divide by requestCount to get average.
142     private long processingTime;
143     // The longest response time for a request
144     private long maxTime;
145     // URI of the request that took maxTime
146     private String maxRequestUri;
147
148     private int requestCount;
149     // number of response codes >= 400
150     private int errorCount;
151
152     //the time of the last request
153     private long lastRequestProcessingTime = 0;
154
155
156     /** Called by the processor before recycling the request. It'll collect
157      * statistic information.
158      */

159     void updateCounters() {
160         bytesReceived+=req.getBytesRead();
161         bytesSent+=req.getResponse().getContentWritten();
162
163         requestCount++;
164         if( req.getResponse().getStatus() >=400 )
165             errorCount++;
166         long t0=req.getStartTime();
167         long t1=System.currentTimeMillis();
168         long time=t1-t0;
169         this.lastRequestProcessingTime = time;
170         processingTime+=time;
171         if( maxTime < time ) {
172             maxTime=time;
173             maxRequestUri=req.requestURI().toString();
174         }
175     }
176
177     public int getStage() {
178         return stage;
179     }
180
181     public void setStage(int stage) {
182         this.stage = stage;
183     }
184
185     public long getBytesSent() {
186         return bytesSent;
187     }
188
189     public void setBytesSent(long bytesSent) {
190         this.bytesSent = bytesSent;
191     }
192
193     public long getBytesReceived() {
194         return bytesReceived;
195     }
196
197     public void setBytesReceived(long bytesReceived) {
198         this.bytesReceived = bytesReceived;
199     }
200
201     public long getProcessingTime() {
202         return processingTime;
203     }
204
205     public void setProcessingTime(long processingTime) {
206         this.processingTime = processingTime;
207     }
208
209     public long getMaxTime() {
210         return maxTime;
211     }
212
213     public void setMaxTime(long maxTime) {
214         this.maxTime = maxTime;
215     }
216
217     public String getMaxRequestUri() {
218         return maxRequestUri;
219     }
220
221     public void setMaxRequestUri(String maxRequestUri) {
222         this.maxRequestUri = maxRequestUri;
223     }
224
225     public int getRequestCount() {
226         return requestCount;
227     }
228
229     public void setRequestCount(int requestCount) {
230         this.requestCount = requestCount;
231     }
232
233     public int getErrorCount() {
234         return errorCount;
235     }
236
237     public void setErrorCount(int errorCount) {
238         this.errorCount = errorCount;
239     }
240
241     public String getWorkerThreadName() {
242         return workerThreadName;
243     }
244
245     public ObjectName getRpName() {
246         return rpName;
247     }
248
249     public long getLastRequestProcessingTime() {
250         return lastRequestProcessingTime;
251     }
252
253     public void setWorkerThreadName(String workerThreadName) {
254         this.workerThreadName = workerThreadName;
255     }
256
257     public void setRpName(ObjectName rpName) {
258         this.rpName = rpName;
259     }
260
261     public void setLastRequestProcessingTime(long lastRequestProcessingTime) {
262         this.lastRequestProcessingTime = lastRequestProcessingTime;
263     }
264 }
265