/**
* Query
* Copyright 19.05.2016 by Michael Peter Christen, @0rb1t3r
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program in the file lgpl21.txt
* If not, see <http://www.gnu.org/licenses/>.
*/
package org.loklak.server;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Enumeration;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.loklak.LoklakServer;
import org.loklak.data.DAO;
import org.loklak.http.AccessTracker;
import org.loklak.http.RemoteAccess;
import org.loklak.tools.DateParser;
public class Query {
private HttpServletRequest request;
private Map<String, String> qm;
public AccessTracker.Track track;
public Query(final HttpServletRequest request) {
this.qm = new HashMap<>();
this.request = request;
// Add request parameters from servlet request
Enumeration<String> keysEnum = request.getParameterNames();
while (keysEnum.hasMoreElements()) {
String key = keysEnum.nextElement();
qm.put(key, request.getParameter(key));
}
// discover remote host
String clientHost = request.getRemoteHost();
String XRealIP = request.getHeader("X-Real-IP");
if (XRealIP != null && XRealIP.length() > 0) clientHost = XRealIP; // get IP through nginx config "proxy_set_header X-Real-IP $remote_addr;"
// start tracking: get calling thread and start tracking for that
this.track = DAO.access.startTracking(request.getServletPath(), clientHost, request.getHeader("Referer"));
this.track.setTimeSinceLastAccess(this.track.getDate().getTime() - RemoteAccess.latestVisit(request.getServletPath(), clientHost));
this.track.setDoSBlackout(LoklakServer.blacklistedHosts.contains(clientHost) || (!this.track.isLocalhostAccess() && (this.track.getTimeSinceLastAccess() < DAO.getConfig("DoS.blackout", 100))));
this.track.setDoSServicereduction(!this.track.isLocalhostAccess() && (this.track.getTimeSinceLastAccess() < DAO.getConfig("DoS.servicereduction", 1000)));
this.track.setQuery(qm);
}
public void finalize() {
this.track.finalize();
}
public void initGET(final Map<String, String> qm) {
for (String key : qm.keySet())
qm.put(key, qm.get(key));
}
// initPOST is deprecated because the purpose of it has been replaced by the constructor
@Deprecated
public void initPOST(final Map<String, byte[]> map) {
// This method does nothing, removing it is a bad idea because it can break
// other servlets / services
}
public String getClientHost() {
return this.track.getClientHost();
}
public boolean isLocalhostAccess() {
return this.track.isLocalhostAccess();
}
public long getAccessTime() {
return this.track.getDate().getTime();
}
public long getTimeSinceLastAccess() {
return this.track.getTimeSinceLastAccess();
}
public boolean isDoS_blackout() {
return this.track.isDoSBlackout();
}
public boolean isDoS_servicereduction() {
return this.track.isDoSServicereduction();
}
public void recordEvent(String eventName, Object eventValue) {
this.track.put(AccessTracker.EVENT_PREFIX + eventName, eventValue);
}
public String get(String key, String dflt) {
String val = qm == null ? request.getParameter(key) : qm.get(key);
return val == null ? dflt : val;
}
public String[] get(String key, String[] dflt, String delim) {
String val = qm == null ? request.getParameter(key) : qm.get(key);
return val == null || val.length() == 0 ? dflt : val.split(delim);
}
public int get(String key, int dflt) {
String val = qm == null ? request.getParameter(key) : qm.get(key);
return val == null || val.length() == 0 ? dflt : Integer.parseInt(val);
}
public long get(String key, long dflt) {
String val = qm == null ? request.getParameter(key) : qm.get(key);
return val == null || val.length() == 0 ? dflt : Long.parseLong(val);
}
public double get(String key, double dflt) {
String val = qm == null ? request.getParameter(key) : qm.get(key);
return val == null || val.length() == 0 ? dflt : Double.parseDouble(val);
}
public boolean get(String key, boolean dflt) {
String val = qm == null ? request.getParameter(key) : qm.get(key);
return val == null ? dflt : "true".equals(val) || "1".equals(val);
}
public Date get(String key, Date dflt, int timezoneOffset) {
String val = qm == null ? request.getParameter(key) : qm.get(key);
try {
return val == null || val.length() == 0 ? dflt : DateParser.parse(val, timezoneOffset).getTime();
} catch (ParseException e) {
return dflt;
}
}
public Set<String> getKeys() {
return request.getParameterMap().keySet();
}
public void setResponse(final HttpServletResponse response, final String mime) {
long access_time = this.getAccessTime();
response.setDateHeader("Last-Modified", access_time);
response.setDateHeader("Expires", access_time + 2 * DAO.getConfig("DoS.servicereduction", 1000));
response.setContentType(mime);
response.setHeader("X-Robots-Tag", "noindex,noarchive,nofollow,nosnippet");
response.setCharacterEncoding("UTF-8");
response.setStatus(HttpServletResponse.SC_OK);
}
public int hashCode() {
return qm.hashCode();
}
public HttpServletRequest getRequest(){ return this.request; }
}