1 /*
2  * Copyright 2008-2019 by Emeric Vernat
3  *
4  *     This file is part of Java Melody.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package net.bull.javamelody.internal.web;
19
20 import java.text.DateFormat;
21 import java.text.SimpleDateFormat;
22 import java.util.Locale;
23
24 import javax.servlet.http.Cookie;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27
28 import net.bull.javamelody.internal.common.HttpParameter;
29 import net.bull.javamelody.internal.common.I18N;
30 import net.bull.javamelody.internal.model.Period;
31 import net.bull.javamelody.internal.model.Range;
32
33 /**
34  * Gestionnaire de cookie http persistent.
35  * @author Emeric Vernat
36  */

37 public class HttpCookieManager {
38     private static final String PERIOD_COOKIE_NAME = "javamelody.period";
39
40     // période par défaut : jour
41     private static Range defaultRange = Period.JOUR.getRange();
42
43     public Range getRange(HttpServletRequest req, HttpServletResponse resp) {
44         final DateFormat dateFormat;
45         final String pattern = HttpParameter.PATTERN.getParameterFrom(req);
46         if (pattern == null || pattern.isEmpty()) {
47             dateFormat = I18N.createDateFormat();
48         } else {
49             dateFormat = new SimpleDateFormat(pattern, Locale.US);
50         }
51         final Range range;
52         if (HttpParameter.PERIOD.getParameterFrom(req) == null) {
53             // pas de paramètre period dans la requête, on cherche le cookie
54             final Cookie cookie = getCookieByName(req, PERIOD_COOKIE_NAME);
55             if (cookie == null) {
56                 // pas de cookie, période par défaut
57                 range = defaultRange;
58             } else {
59                 range = Range.parse(cookie.getValue(), dateFormat);
60             }
61         } else {
62             range = Range.parse(HttpParameter.PERIOD.getParameterFrom(req), dateFormat);
63             // un paramètre period est présent dans la requête :
64             // l'utilisateur a choisi une période, donc on fixe le cookie
65             addCookie(req, resp, PERIOD_COOKIE_NAME, range.getValue());
66         }
67         return range;
68     }
69
70     Cookie getCookieByName(HttpServletRequest req, String cookieName) {
71         final Cookie[] cookies = req.getCookies();
72         if (cookies != null) {
73             for (final Cookie cookie : cookies) {
74                 if (cookieName.equals(cookie.getName())) {
75                     return cookie;
76                 }
77             }
78         }
79         return null;
80     }
81
82     void addCookie(HttpServletRequest req, HttpServletResponse resp, String cookieName,
83             String cookieValue) {
84         if (!"added".equals(req.getAttribute(cookieName))) {
85             final Cookie cookie = new Cookie(cookieName, cookieValue);
86             // cookie persistant, valide pendant 30 jours
87             cookie.setMaxAge(30 * 24 * 60 * 60);
88             // inutile d'envoyer ce cookie aux autres URLs que le monitoring
89             cookie.setPath(req.getRequestURI());
90             resp.addCookie(cookie);
91             req.setAttribute(cookieName, "added");
92         }
93     }
94
95     String getCookiesAsString(HttpServletRequest req) {
96         final Cookie[] cookies = req.getCookies();
97         if (cookies != null) {
98             final StringBuilder sb = new StringBuilder();
99             for (int i = 0; i < cookies.length; i++) {
100                 final Cookie cookie = cookies[i];
101                 sb.append(cookie.getName()).append('=').append(cookie.getValue());
102                 if (i < cookies.length - 1) {
103                     sb.append("; ");
104                 }
105             }
106             return sb.toString();
107         }
108         return null;
109     }
110
111     public static void setDefaultRange(Range range) {
112         defaultRange = range;
113     }
114 }
115