/*
* This file is part of the Wayback archival access software
* (http://archive-access.sourceforge.net/projects/wayback/).
*
* Licensed to the Internet Archive (IA) by one or more individual
* contributors.
*
* The IA licenses this file to You 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 org.archive.wayback.core;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.archive.wayback.requestparser.OpenSearchRequestParser;
import org.archive.wayback.resourceindex.filters.ExclusionFilter;
import org.archive.wayback.util.ObjectFilter;
import org.archive.wayback.util.ObjectFilterChain;
import org.archive.wayback.util.StringFormatter;
import org.archive.wayback.util.Timestamp;
import org.archive.wayback.util.url.UrlOperations;
import org.archive.wayback.webapp.AccessPoint;
/**
* Abstraction of all the data associated with a users request to the Wayback
* Machine.
*
* @author Brad Tofel
* @version $Date$, $Revision$
*/
public class WaybackRequest {
/**
* indicates the number of requests per page, only makes sense for
* Capture/Url queries.
*/
private int resultsPerPage = 10;
/**
* indicates the specific page of results to show, for paginated requests,
* only makes sense for Capture/Url queries.
*/
private int pageNum = 1;
/**
* absolute URL prefix to the AccessPoint which received this request
*/
private String contextPrefix = null;
/**
* absolute URL prefix to the Server(webapp) which received this request
*/
private String serverPrefix = null;
/**
* reference to the AccessPoint which received this request.
*/
private AccessPoint accessPoint = null;
/**
* custom CaptureSearchResult Filter to use for this specific request. Can
* be null, and is sometimes useful to allow an AccessPoint to have specific
* and possibly variable filters. These filters relate specifically to
* exclusion of results from the ResourceIndex. Compared to the
* resultFilters, if these filters redact all results, then an
* AccessControlException will be thrown.
*/
private ExclusionFilter exclusionFilter = null;
/**
* custom CaptureSearchResult Filter to use for this specific request. Can
* be null, and is sometimes useful to allow an AccessPoint to have specific
* and possibly variable filters.
*/
private ObjectFilterChain<CaptureSearchResult> resultFilters = null;
/**
* StringFormatter object set up with the users specific Locale, and the
* Wayback UI ResourceBundle prepared for use, simplifying UI generation
* somewhat.
*/
private StringFormatter formatter = null;
/**
* generic String-to-String map of various request filters and type
* information. See constants below for keys & values.
*/
private HashMap<String,String> filters = new HashMap<String,String>();
/*
* **********************
* REQUEST TYPE CONSTANTS
* **********************
*/
/**
* specifies the TYPE of the this particular request. One of:
* *) REQUEST_REPLAY_QUERY
* *) REQUEST_CAPTURE_QUERY
* *) REQUEST_URL_QUERY
*/
public static final String REQUEST_TYPE = "type";
/**
* REQUEST_TYPE option indicating a request for Replay of the Resource
* matching REQUEST_URL closest in time to REQUEST_DATE
*/
public static final String REQUEST_REPLAY_QUERY = "replay";
/**
* REQUEST_TYPE option indicating a query against the ResourceIndex for
* captures of URLs matching the REQUEST_URL
*/
public static final String REQUEST_CAPTURE_QUERY = "urlquery";
/**
* REQUEST_TYPE option indicating a query against the ResourceIndex for
* summaries of URLs prefixed with the REQUEST_URL
*/
public static final String REQUEST_URL_QUERY = "prefixquery";
/*
* **********************
* /REQUEST TYPE CONSTANTS
* **********************
*/
/*
* ******************
* URL/DATE CONSTANTS
* ******************
*/
/**
* GUARANTEED PRESENT: Original(RAW) URL or URL prefix requested, before any
* cleanup/fixing
*/
public static final String REQUEST_URL = "url";
/**
* Cleaned up version of original requested URL or URL prefix, as performed
* by UURIFactory.
*/
// public static final String REQUEST_URL_CLEANED = "cleanedurl";
/**
* GUARANTEED PRESENT: omit results after this 14-digit String timestamp.
* Possibly created from:
* 1) specified directly in request
* 2) a partial REQUEST_DATE (latest possible given a prefix)
* 3) RequestParser default
* 4) 14-digit representation of the moment the request was recieved.
*/
public static final String REQUEST_END_DATE = "enddate";
/**
* GUARANTEED PRESENT: omit results before this 14-digit String timestamp.
* Possibly created from:
* 1) specified directly in request
* 2) a partial REQUEST_DATE (earliest possible given a prefix)
* 3) RequestParser default
* 4) 14-digit representation of midnight Jan 1, 1996.
*/
public static final String REQUEST_START_DATE = "startdate";
/**
* GUARANTEED PRESENT for Replay requests only. If present for Query
* requests, then it will be interpreted as a partial timestamp for missing
* REQUEST_START_DATE and REQUEST_END_DATE fields.
* Original (RAW/possibly partial) 14-digit timestamp of date requested for
* Replay
*/
public static final String REQUEST_DATE = "date";
/**
* GUARANTEED PRESENT for Replay requests only, no meaning for Query
* requests.
* Cleaned up version of original REQUEST_DATE, padded to 14 digits assuming
* the
*/
public static final String REQUEST_EXACT_DATE = "exactdate";
/**
* Indicates user only wants results that exactly match the hostname within
* REQUEST_URL -- no canonicalization.
*/
public static final String REQUEST_EXACT_HOST_ONLY = "requestexacthost";
/**
* Indicates user only wants results that were captured using the same
* scheme as that specified in REQUEST_URL.
*/
public static final String REQUEST_EXACT_SCHEME_ONLY = "requestexactscheme";
/**
* Indicates user requested content from proxied from the live web.
*/
public static final String REQUEST_IS_LIVE_WEB = "requestliveweb";
/**
* indicates positive value for any request boolean flag.
*/
public static final String REQUEST_YES = "yes";
/**
* Replay-Only: indicates the date to tend towards when computing closest
* matches within time. Used to prevent "time drift" while surfing from a
* particular date.
*/
public final static String REQUEST_ANCHOR_DATE = "request.anchordate";
/**
* Replay-Only: String representation of number of seconds. Used only in
* conjunction with REQUEST_ANCHOR_DATE, and indicates that documents more
* than this many seconds should not be shown in a replay session. Useful
* for QA purposes, to ensure that all content within a replay session was
* crawled near a particular point, the REQUEST_ANCHOR_DATE.
*/
public final static String REQUEST_ANCHOR_WINDOW = "request.anchorwindow";
/*
* ******************
* /URL/DATE CONSTANTS
* ******************
*/
/*
* *******************************
* OUTPUT TYPE CONSTANTS
* *******************************
*/
/**
* Request: replay actual document or metadata for document: "yes" means
* replay metadata only, not the actual document: (TimeLine mode)
*/
public static final String REQUEST_META_MODE = "metamode";
/**
* Request: xml data requested
*/
public static final String REQUEST_XML_DATA = "xmldata";
/**
* Request: CSS context requested
*/
public static final String REQUEST_CSS_CONTEXT = "csscontext";
/**
* Request: JS context requested
*/
public static final String REQUEST_JS_CONTEXT = "jscontext";
/**
* Request: IMG context requested
*/
public static final String REQUEST_IMAGE_CONTEXT = "imagecontext";
/**
* Request: Identity context requested (totally transparent)
*/
public static final String REQUEST_IDENTITY_CONTEXT = "identitycontext";
/**
* Request: Content should be wrapped in a frame
*/
public static final String REQUEST_FRAME_WRAPPER_CONTEXT =
"framewrappercontext";
/**
* Request: Display context for embedded metadata in an IFrame
*/
public static final String REQUEST_IFRAME_WRAPPER_CONTEXT =
"iframewrappercontext";
/**
* Request: Charset detection mode
*/
public static final String REQUEST_CHARSET_MODE = "charsetmode";
/*
* *******************************
* /OUTPUT TYPE CONSTANTS
* *******************************
*/
/*
* *******************************
* CONTEXT & ACCESSPOINT CONSTANTS
* *******************************
*/
/**
* the string (webapp) context that received this request
*/
public static final String REQUEST_WAYBACK_CONTEXT = "waybackcontext";
/**
* the port the remote user connected to for this request
*/
public static final String REQUEST_WAYBACK_PORT = "waybackport";
/*
* *******************************
* /CONTEXT & ACCESSPOINT CONSTANTS
* *******************************
*/
/*
* *****************************
* HTTP HEADER/REQUEST CONSTANTS
* *****************************
*/
/**
* incoming requests HTTP "Host:" header, or null
*/
public static final String REQUEST_WAYBACK_HOSTNAME = "waybackhostname";
/**
* incoming requests HTTP "Referer:" header, or null
*/
public static final String REQUEST_REFERER_URL = "refererurl";
/**
* Remote Address that connected to this webapp to create the request
* string IP address: "127.0.0.1"
*/
public static final String REQUEST_REMOTE_ADDRESS = "remoteaddress";
/**
* Remote User or null if the request did not contain auth info.
* see HttpServletRequest.getRemoteUser()
*/
public static final String REQUEST_REMOTE_USER = "requestremoteuser";
/**
* Exact value from HTTP request for header "Authorization"
*/
public static final String REQUEST_AUTHORIZATION = "Authorization";
/**
* User Locale name: Best Guess at users requested locale.
* see ServletRequest.getLocale().getDisplayLanguage()
*/
public static final String REQUEST_LOCALE_LANG = "requestlocalelang";
/**
* Authorization Type: "BASIC", "SSL", or null if none.
* see HttpServletRequest.getAuthType()
*/
public static final String REQUEST_AUTH_TYPE = "requestauthtype";
/*
* ***********************
* /HTTP HEADER/REQUEST CONSTANTS
* ***********************
*/
/*
* ***********************
* TIMELINE MODE CONSTANTS
* ***********************
*/
/**
* resolution of results to be displayed: (TimeLine mode)
*/
public static final String REQUEST_RESOLUTION = "resolution";
/**
* auto resolution (TimeLine mode)
*/
public static final String REQUEST_RESOLUTION_AUTO = "auto";
/**
* year resolution (TimeLine mode)
*/
public static final String REQUEST_RESOLUTION_YEARS = "years";
/**
* two-month resolution (TimeLine mode)
*/
public static final String REQUEST_RESOLUTION_TWO_MONTHS = "twomonths";
/**
* month resolution (TimeLine mode)
*/
public static final String REQUEST_RESOLUTION_MONTHS = "months";
/**
* day resolution (TimeLine mode)
*/
public static final String REQUEST_RESOLUTION_DAYS = "days";
/**
* hour resolution (TimeLine mode)
*/
public static final String REQUEST_RESOLUTION_HOURS = "hours";
/*
* ***********************
* /TIMELINE MODE CONSTANTS
* ***********************
*/
private static String UI_RESOURCE_BUNDLE_NAME = "WaybackUI";
private static String STD_LOGGED_IN_VER = "logged-in-ver";
private static String STD_LOGGED_IN_NAME = "logged-in-name";
private static String STD_LOGGED_IN_USER = "logged-in-user";
private static String STD_PHP_SESSION_ID = "PHPSESSID";
private static String STD_J_SESSION_ID = "JSESSIONID";
/**
* set of filter keys that are not forwarded to subsequent paginated
* requests.
*/
private final static String standardHeaders[] = {
REQUEST_REFERER_URL,
REQUEST_REMOTE_ADDRESS,
REQUEST_WAYBACK_HOSTNAME,
REQUEST_WAYBACK_PORT,
REQUEST_WAYBACK_CONTEXT,
REQUEST_AUTH_TYPE,
REQUEST_REMOTE_USER,
REQUEST_LOCALE_LANG,
STD_LOGGED_IN_USER,
STD_LOGGED_IN_VER,
STD_LOGGED_IN_NAME,
STD_PHP_SESSION_ID,
STD_J_SESSION_ID };
/**
* @return Returns the resultsPerPage.
*/
public int getResultsPerPage() {
return resultsPerPage;
}
/**
* @param resultsPerPage
* The resultsPerPage to set.
*/
public void setResultsPerPage(int resultsPerPage) {
this.resultsPerPage = resultsPerPage;
}
/**
* @return Returns the pageNum.
*/
public int getPageNum() {
return pageNum;
}
/**
* @param pageNum
* The pageNum to set.
*/
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
/**
* @param prefix
* @deprecated use getAccessPoint.getStaticPrefix() or
* getAccessPoint.getReplayPrefix()
*/
public void setContextPrefix(String prefix) {
contextPrefix = prefix;
}
/**
* Construct an absolute URL that points to the root of the context that
* received the request, including a trailing "/".
*
* @return String absolute URL pointing to the Context root where the
* request was received.
* @deprecated use AccessPoint.setReplayPrefix or setQueryPrefix
*/
public String getContextPrefix() {
if(accessPoint == null) {
return "";
}
return accessPoint.getQueryPrefix();
}
/**
* @param prefix
* @deprecated use AccessPoint.set*Prefix
*/
public void setServerPrefix(String prefix) {
serverPrefix = prefix;
}
/**
* @param prefix
* @return an absolute String URL that will point to the root of the
* server that is handling the request.
* @deprecated use AccessPoint.get*Prefix
*/
public String getServerPrefix() {
if(accessPoint == null) {
return "";
}
return accessPoint.getQueryPrefix();
}
/**
* @return the accessPoint
*/
public AccessPoint getAccessPoint() {
return accessPoint;
}
/**
* @param accessPoint the accessPoint to set
*/
public void setAccessPoint(AccessPoint accessPoint) {
this.accessPoint = accessPoint;
}
public ExclusionFilter getExclusionFilter() {
return exclusionFilter;
}
public void setExclusionFilter(ExclusionFilter exclusionFilter) {
this.exclusionFilter = exclusionFilter;
}
public void setResultFilters(ObjectFilterChain<CaptureSearchResult> resultFilters) {
this.resultFilters = resultFilters;
}
public void addResultFilter(ObjectFilter<CaptureSearchResult> resultFilter) {
if(resultFilters == null) {
resultFilters = new ObjectFilterChain<CaptureSearchResult>();
}
resultFilters.addFilter(resultFilter);
}
/**
* @return StringFormatter based on user request info
*/
public StringFormatter getFormatter() {
if(formatter == null) {
setLocale(Locale.getAvailableLocales()[0]);
}
return formatter;
}
/**
* @param key
* @return String value for key 'key', or null if no value exists
*/
public String get(String key) {
return filters.get(key);
}
/**
* @param key
* @param value
*/
public void put(String key, String value) {
filters.put(key, value);
}
public void remove(String key) {
filters.remove(key);
}
private void setBoolean(String key, boolean value) {
if(value) {
put(key,REQUEST_YES);
} else {
remove(key);
}
}
private int getInt(String key) {
String value = get(key);
if(value == null) {
return -1;
}
return Integer.parseInt(value);
}
private void setInt(String key, int value) {
put(key,String.valueOf(value));
}
private boolean getBoolean(String key) {
String value = get(key);
return(value != null && value.equals(REQUEST_YES));
}
/**
* @param key
* @return boolean, true if the request contains key 'key'
* @deprecated
*/
public boolean containsKey(String key) {
return filters.containsKey(key);
}
private void putUnlessNull(String key, String val) {
if (val != null) {
put(key,val);
}
}
private boolean isRequestType(String requestType) {
String type = get(REQUEST_TYPE);
if(type != null && type.equals(requestType)) {
return true;
}
return false;
}
/**
* @return true if this is a Replay request
*/
public boolean isReplayRequest() {
return isRequestType(REQUEST_REPLAY_QUERY);
}
/**
* marks this request as a Replay request
*/
public void setReplayRequest() {
put(REQUEST_TYPE,REQUEST_REPLAY_QUERY);
}
/**
* @return true if this is a Capture Query request
*/
public boolean isCaptureQueryRequest() {
return isRequestType(REQUEST_CAPTURE_QUERY);
}
/**
* marks this request as a Capture Query request
*/
public void setCaptureQueryRequest() {
put(REQUEST_TYPE,REQUEST_CAPTURE_QUERY);
}
/**
* @return true if this is an Url Query request
*/
public boolean isUrlQueryRequest() {
return isRequestType(REQUEST_URL_QUERY);
}
/**
* marks this request as an Url Query request
*/
public void setUrlQueryRequest() {
put(REQUEST_TYPE,REQUEST_URL_QUERY);
}
public String getRequestUrl() {
return get(REQUEST_URL);
}
/**
* Set the request URL.
* @param urlStr Request URL.
*/
public void setRequestUrl(String urlStr) {
// This looks a little confusing: We're trying to fixup an incoming
// request URL that starts with:
// "http:/www.archive.org"
// so it becomes:
// "http://www.archive.org"
// (note the missing second "/" in the first)
//
// if that is not the case, then see if the incoming scheme
// is known, adding an implied "http://" scheme if there doesn't appear
// to be a scheme..
// TODO: make the default "http://" configurable.
if (!urlStr.startsWith(UrlOperations.HTTP_SCHEME)) {
if(urlStr.startsWith("http:/")) {
urlStr = UrlOperations.HTTP_SCHEME + urlStr.substring(6);
} else {
if(UrlOperations.urlToScheme(urlStr) == null) {
urlStr = UrlOperations.HTTP_SCHEME + urlStr;
}
}
}
put(REQUEST_URL, urlStr);
}
public String getEndTimestamp() {
return get(REQUEST_END_DATE);
}
public Date getEndDate() {
return Timestamp.parseAfter(get(REQUEST_END_DATE)).getDate();
}
public void setEndDate(Date date) {
put(REQUEST_END_DATE,new Timestamp(date).getDateStr());
}
public void setEndTimestamp(String timestamp) {
put(REQUEST_END_DATE,timestamp);
}
public String getStartTimestamp() {
return get(REQUEST_START_DATE);
}
public Date getStartDate() {
return Timestamp.parseBefore(get(REQUEST_START_DATE)).getDate();
}
public void setStartDate(Date date) {
put(REQUEST_START_DATE,new Timestamp(date).getDateStr());
}
public void setStartTimestamp(String timestamp) {
put(REQUEST_START_DATE,timestamp);
}
public String getReplayTimestamp() {
return get(REQUEST_DATE);
}
public Date getReplayDate() {
return Timestamp.parseAfter(get(REQUEST_DATE)).getDate();
}
public void setReplayDate(Date date) {
put(REQUEST_DATE,new Timestamp(date).getDateStr());
}
public void setReplayTimestamp(String timestamp) {
put(REQUEST_DATE,timestamp);
}
public void setExactHost(boolean isExactHost) {
setBoolean(REQUEST_EXACT_HOST_ONLY,isExactHost);
}
public boolean isExactHost() {
return getBoolean(REQUEST_EXACT_HOST_ONLY);
}
public void setExactScheme(boolean isExactScheme) {
setBoolean(REQUEST_EXACT_SCHEME_ONLY,isExactScheme);
}
public boolean isExactScheme() {
return getBoolean(REQUEST_EXACT_SCHEME_ONLY);
}
public void setLiveWebRequest(boolean isLiveWebRequest) {
setBoolean(REQUEST_IS_LIVE_WEB,isLiveWebRequest);
}
public boolean isLiveWebRequest() {
return getBoolean(REQUEST_IS_LIVE_WEB);
}
public String getAnchorTimestamp() {
return get(REQUEST_ANCHOR_DATE);
}
public Date getAnchorDate() {
return Timestamp.parseAfter(get(REQUEST_ANCHOR_DATE)).getDate();
}
public void setAnchorDate(Date date) {
put(REQUEST_ANCHOR_DATE,new Timestamp(date).getDateStr());
}
public void setAnchorTimestamp(String timestamp) {
put(REQUEST_ANCHOR_DATE,timestamp);
}
public long getAnchorWindow() {
String seconds = get(REQUEST_ANCHOR_WINDOW);
if(seconds == null) {
return 0;
}
return Long.parseLong(seconds);
}
public void setAnchorWindow(long seconds) {
put(REQUEST_ANCHOR_WINDOW,String.valueOf(seconds));;
}
public void setMetaMode(boolean isMetaMode) {
setBoolean(REQUEST_META_MODE,isMetaMode);
}
public boolean isMetaMode() {
return getBoolean(REQUEST_META_MODE);
}
public void setXMLMode(boolean isXMLMode) {
setBoolean(REQUEST_XML_DATA,isXMLMode);
}
public boolean isXMLMode() {
return getBoolean(REQUEST_XML_DATA);
}
public void setJSContext(boolean isJSContext) {
setBoolean(REQUEST_JS_CONTEXT,isJSContext);
}
public boolean isJSContext() {
return getBoolean(REQUEST_JS_CONTEXT);
}
public void setCSSContext(boolean isCSSContext) {
setBoolean(REQUEST_CSS_CONTEXT,isCSSContext);
}
public boolean isCSSContext() {
return getBoolean(REQUEST_CSS_CONTEXT);
}
public void setIMGContext(boolean isIMGContext) {
setBoolean(REQUEST_IMAGE_CONTEXT,isIMGContext);
}
public boolean isIMGContext() {
return getBoolean(REQUEST_IMAGE_CONTEXT);
}
public void setIdentityContext(boolean isIdentityContext) {
setBoolean(REQUEST_IDENTITY_CONTEXT,isIdentityContext);
}
public boolean isIdentityContext() {
return getBoolean(REQUEST_IDENTITY_CONTEXT);
}
public void setFrameWrapperContext(boolean isFrameWrapperContext) {
setBoolean(REQUEST_FRAME_WRAPPER_CONTEXT,isFrameWrapperContext);
}
public boolean isFrameWrapperContext() {
return getBoolean(REQUEST_FRAME_WRAPPER_CONTEXT);
}
public void setIFrameWrapperContext(boolean isIFrameWrapperContext) {
setBoolean(REQUEST_IFRAME_WRAPPER_CONTEXT,isIFrameWrapperContext);
}
public boolean isIFrameWrapperContext() {
return getBoolean(REQUEST_IFRAME_WRAPPER_CONTEXT);
}
public void setCharsetMode(int mode) {
setInt(REQUEST_CHARSET_MODE,mode);
}
public int getCharsetMode() {
int mode = getInt(REQUEST_CHARSET_MODE);
return (mode == -1) ? 0 : mode;
}
public String getWaybackContext() {
return get(REQUEST_WAYBACK_CONTEXT);
}
public int getWaybackPort() {
String port = get(REQUEST_WAYBACK_PORT);
if(port == null) {
return 0;
}
return Integer.parseInt(port);
}
public String getWaybackHostname() {
return get(REQUEST_WAYBACK_HOSTNAME);
}
public String getRefererUrl() {
return get(REQUEST_REFERER_URL);
}
public String getRemoteIPAddress() {
return get(REQUEST_REMOTE_ADDRESS);
}
public String getRemoteUser() {
return get(REQUEST_REMOTE_USER);
}
public String getLocaleLanguage() {
return get(REQUEST_LOCALE_LANG);
}
public String getAuthType() {
return get(REQUEST_AUTH_TYPE);
}
public String getTimelineResolution() {
return get(REQUEST_RESOLUTION);
}
public void setTimelineAutoResolution() {
put(REQUEST_RESOLUTION,REQUEST_RESOLUTION_AUTO);
}
public void setTimelineYearResolution() {
put(REQUEST_RESOLUTION,REQUEST_RESOLUTION_YEARS);
}
public void setTimelineTwoMonthResolution() {
put(REQUEST_RESOLUTION,REQUEST_RESOLUTION_TWO_MONTHS);
}
public void setTimelineMonthResolution() {
put(REQUEST_RESOLUTION,REQUEST_RESOLUTION_MONTHS);
}
public void setTimelineDayResolution() {
put(REQUEST_RESOLUTION,REQUEST_RESOLUTION_DAYS);
}
public void setTimelineHourResolution() {
put(REQUEST_RESOLUTION,REQUEST_RESOLUTION_HOURS);
}
/**
* Set the Locale for the request, which impacts UI Strings
* @param l
*/
public void setLocale(Locale l) {
ResourceBundle b = ResourceBundle.getBundle(UI_RESOURCE_BUNDLE_NAME,l);
formatter = new StringFormatter(b,l);
}
/**
* extract REFERER, remote IP and authorization information from the
* HttpServletRequest
*
* @param httpRequest
*/
private void extractHttpRequestInfo(HttpServletRequest httpRequest) {
putUnlessNull(REQUEST_REFERER_URL, httpRequest.getHeader("REFERER"));
putUnlessNull(REQUEST_REMOTE_ADDRESS, httpRequest.getRemoteAddr());
putUnlessNull(REQUEST_WAYBACK_HOSTNAME, httpRequest.getLocalName());
putUnlessNull(REQUEST_AUTH_TYPE, httpRequest.getAuthType());
putUnlessNull(REQUEST_REMOTE_USER, httpRequest.getRemoteUser());
putUnlessNull(REQUEST_AUTHORIZATION,
httpRequest.getHeader(REQUEST_AUTHORIZATION));
putUnlessNull(REQUEST_WAYBACK_PORT,
String.valueOf(httpRequest.getLocalPort()));
putUnlessNull(REQUEST_WAYBACK_CONTEXT, httpRequest.getContextPath());
Locale l = null;
if(accessPoint != null) {
l = accessPoint.getLocale();
}
if(l == null) {
l = httpRequest.getLocale();
}
setLocale(l);
putUnlessNull(REQUEST_LOCALE_LANG,l.getDisplayLanguage());
Cookie[] cookies = httpRequest.getCookies();
if(cookies != null) {
for(Cookie cookie : cookies) {
String name = cookie.getName();
String value = cookie.getValue();
String oldVal = get(name);
if(oldVal == null || oldVal.length() == 0) {
put(name,value);
}
}
}
}
/**
* attempt to fixup this WaybackRequest, mostly with respect to dates: if
* only "date" was specified, infer start and end dates from it. Also grab
* useful info from the HttpServletRequest, cookies, remote address, etc.
*
* @param httpRequest
*/
public void fixup(HttpServletRequest httpRequest) {
extractHttpRequestInfo(httpRequest);
// String startDate = get(REQUEST_START_DATE);
// String endDate = get(REQUEST_END_DATE);
// String exactDate = get(REQUEST_EXACT_DATE);
// String partialDate = get(REQUEST_DATE);
// if (partialDate == null) {
// partialDate = "";
// }
// if (startDate == null || startDate.length() == 0) {
// put(REQUEST_START_DATE, Timestamp
// .padStartDateStr(partialDate));
// } else if (startDate.length() < 14) {
// put(REQUEST_START_DATE, Timestamp
// .padStartDateStr(startDate));
// }
// if (endDate == null || endDate.length() == 0) {
// put(REQUEST_END_DATE, Timestamp
// .padEndDateStr(partialDate));
// } else if (endDate.length() < 14) {
// put(REQUEST_END_DATE, Timestamp
// .padEndDateStr(endDate));
// }
// if (exactDate == null || exactDate.length() == 0) {
// put(REQUEST_EXACT_DATE, Timestamp
// .padEndDateStr(partialDate));
// } else if (exactDate.length() < 14) {
// put(REQUEST_EXACT_DATE, Timestamp
// .padEndDateStr(exactDate));
// }
}
/**
* @return String hex-encoded GET CGI arguments which will duplicate this
* wayback request
*/
public String getQueryArguments() {
return getQueryArguments(pageNum);
}
/**
* @param pageNum
* @return String hex-encoded GET CGI arguments which will duplicate the
* same request, but for page 'pageNum' of the results
*/
public String getQueryArguments(int pageNum) {
int numPerPage = resultsPerPage;
StringBuffer queryString = new StringBuffer("");
Iterator<String> itr = filters.keySet().iterator();
while(itr.hasNext()) {
String key = itr.next();
boolean isStandard = false;
for(int i=0; i<standardHeaders.length; i++) {
if(standardHeaders[i].equals(key)) {
isStandard = true;
break;
}
}
if(isStandard) continue;
String val = filters.get(key);
if(val == null) continue;
if (queryString.length() > 0) {
queryString.append(" ");
}
queryString.append(key + ":" + val);
}
String escapedQuery = queryString.toString();
try {
escapedQuery = URLEncoder.encode(escapedQuery, "UTF-8");
} catch (UnsupportedEncodingException e) {
// oops.. what to do?
e.printStackTrace();
}
return OpenSearchRequestParser.SEARCH_QUERY + "=" + escapedQuery + "&"
+ OpenSearchRequestParser.SEARCH_RESULTS + "=" + numPerPage + "&"
+ OpenSearchRequestParser.START_PAGE + "=" + pageNum;
}
public WaybackRequest clone() {
WaybackRequest wbRequest = new WaybackRequest();
wbRequest.resultsPerPage = resultsPerPage;
wbRequest.pageNum = pageNum;
wbRequest.contextPrefix = contextPrefix;
wbRequest.serverPrefix = serverPrefix;
wbRequest.formatter = formatter;
wbRequest.accessPoint = accessPoint;
wbRequest.filters = new HashMap<String,String>();
Iterator<String> itr = filters.keySet().iterator();
while(itr.hasNext()) {
String key = itr.next();
String val = filters.get(key);
wbRequest.filters.put(key, val);
}
return wbRequest;
}
/**
*
* @return
* @deprecated
*/
public Set<String> keySet() {
return filters.keySet();
}
}