@ -112,24 +112,24 @@ public class yacysearch {
final boolean searchAllowed = sb . getConfigBool ( SwitchboardConstants . PUBLIC_SEARCHPAGE , true ) | | adminAuthenticated ;
final boolean searchAllowed = sb . getConfigBool ( SwitchboardConstants . PUBLIC_SEARCHPAGE , true ) | | adminAuthenticated ;
boolean extendedSearchRights = adminAuthenticated ;
boolean extendedSearchRights = adminAuthenticated ;
if ( adminAuthenticated ) {
if ( adminAuthenticated ) {
authenticatedUserName = sb . getConfig ( SwitchboardConstants . ADMIN_ACCOUNT_USER_NAME , "admin" ) ;
authenticatedUserName = sb . getConfig ( SwitchboardConstants . ADMIN_ACCOUNT_USER_NAME , "admin" ) ;
} else {
} else {
final UserDB . Entry user = sb . userDB ! = null ? sb . userDB . getUser ( header ) : null ;
final UserDB . Entry user = sb . userDB ! = null ? sb . userDB . getUser ( header ) : null ;
if ( user ! = null ) {
if ( user ! = null ) {
extendedSearchRights = user . hasRight ( UserDB . AccessRight . EXTENDED_SEARCH_RIGHT ) ;
extendedSearchRights = user . hasRight ( UserDB . AccessRight . EXTENDED_SEARCH_RIGHT ) ;
authenticatedUserName = user . getUserName ( ) ;
authenticatedUserName = user . getUserName ( ) ;
}
}
}
}
final boolean localhostAccess = header . accessFromLocalhost ( ) ;
final boolean localhostAccess = header . accessFromLocalhost ( ) ;
final String promoteSearchPageGreeting =
final String promoteSearchPageGreeting =
( env . getConfigBool ( SwitchboardConstants . GREETING_NETWORK_NAME , false ) ) ? env . getConfig (
( env . getConfigBool ( SwitchboardConstants . GREETING_NETWORK_NAME , false ) ) ? env . getConfig (
"network.unit.description" ,
"network.unit.description" ,
"" ) : env . getConfig ( SwitchboardConstants . GREETING , "" ) ;
"" ) : env . getConfig ( SwitchboardConstants . GREETING , "" ) ;
final String client = header . getRemoteAddr ( ) ; // the search client who initiated the search
final String client = header . getRemoteAddr ( ) ; // the search client who initiated the search
// in case that the crawler is running and the search user is the peer admin, we expect that the user wants to check recently crawled document
// in case that the crawler is running and the search user is the peer admin, we expect that the user wants to check recently crawled document
// to ensure that recent crawl results are inside the search results, we do a soft commit here. This is also important for live demos!
// to ensure that recent crawl results are inside the search results, we do a soft commit here. This is also important for live demos!
if ( extendedSearchRights & & sb . getThread ( SwitchboardConstants . CRAWLJOB_LOCAL_CRAWL ) . getJobCount ( ) > 0 ) {
if ( extendedSearchRights & & sb . getThread ( SwitchboardConstants . CRAWLJOB_LOCAL_CRAWL ) . getJobCount ( ) > 0 ) {
@ -137,13 +137,14 @@ public class yacysearch {
}
}
final boolean focus = ( post = = null ) ? true : post . get ( "focus" , "1" ) . equals ( "1" ) ;
final boolean focus = ( post = = null ) ? true : post . get ( "focus" , "1" ) . equals ( "1" ) ;
// get query
// get query
final String originalquerystring = ( post = = null ) ? "" : post . get ( "query" , post . get ( "search" , "" ) ) . trim ( ) ;
String originalquerystring = ( post = = null ) ? "" : post . get ( "query" , post . get ( "search" , "" ) ) . trim ( ) ;
originalquerystring = originalquerystring . replace ( '<' , ' ' ) . replace ( '>' , ' ' ) ; // light xss protection
String querystring = originalquerystring ;
String querystring = originalquerystring ;
CacheStrategy snippetFetchStrategy = ( post = = null ) ? null : CacheStrategy . parse ( post . get ( "verify" , sb . getConfig ( "search.verify" , "" ) ) ) ;
CacheStrategy snippetFetchStrategy = ( post = = null ) ? null : CacheStrategy . parse ( post . get ( "verify" , sb . getConfig ( "search.verify" , "" ) ) ) ;
final servletProperties prop = new servletProperties ( ) ;
final servletProperties prop = new servletProperties ( ) ;
prop . put ( "topmenu" , sb . getConfigBool ( "publicTopmenu" , true ) ? 1 : 0 ) ;
prop . put ( "topmenu" , sb . getConfigBool ( "publicTopmenu" , true ) ? 1 : 0 ) ;
prop . put ( "authSearch" , authenticatedUserName ! = null ) ;
prop . put ( "authSearch" , authenticatedUserName ! = null ) ;
// produce vocabulary navigation sidebars
// produce vocabulary navigation sidebars
Collection < Tagging > vocabularies = LibraryProvider . autotagging . getVocabularies ( ) ;
Collection < Tagging > vocabularies = LibraryProvider . autotagging . getVocabularies ( ) ;
@ -161,7 +162,7 @@ public class yacysearch {
final boolean rss = "rss.atom" . contains ( EXT ) ;
final boolean rss = "rss.atom" . contains ( EXT ) ;
final boolean json = EXT . equals ( "json" ) ;
final boolean json = EXT . equals ( "json" ) ;
prop . put ( "promoteSearchPageGreeting" , promoteSearchPageGreeting ) ;
prop . put ( "promoteSearchPageGreeting" , promoteSearchPageGreeting ) ;
// adding some additional properties needed for the rss feed
// adding some additional properties needed for the rss feed
String peerContext = YaCyDefaultServlet . getContext ( header , sb ) ;
String peerContext = YaCyDefaultServlet . getContext ( header , sb ) ;
prop . put ( "searchBaseURL" , peerContext + "/yacysearch.html" ) ;
prop . put ( "searchBaseURL" , peerContext + "/yacysearch.html" ) ;
@ -172,7 +173,7 @@ public class yacysearch {
boolean p2pmode = sb . peers ! = null & & sb . peers . sizeConnected ( ) > 0 & & indexReceiveGranted ;
boolean p2pmode = sb . peers ! = null & & sb . peers . sizeConnected ( ) > 0 & & indexReceiveGranted ;
boolean global = post = = null | | ( ! post . get ( "resource-switch" , post . get ( "resource" , "global" ) ) . equals ( "local" ) & & p2pmode ) ;
boolean global = post = = null | | ( ! post . get ( "resource-switch" , post . get ( "resource" , "global" ) ) . equals ( "local" ) & & p2pmode ) ;
boolean stealthmode = p2pmode & & ! global ;
boolean stealthmode = p2pmode & & ! global ;
if ( post = = null | | indexSegment = = null | | env = = null | | ! searchAllowed ) {
if ( post = = null | | indexSegment = = null | | env = = null | | ! searchAllowed ) {
if ( indexSegment = = null ) ConcurrentLog . info ( "yacysearch" , "indexSegment == null" ) ;
if ( indexSegment = = null ) ConcurrentLog . info ( "yacysearch" , "indexSegment == null" ) ;
// we create empty entries for template strings
// we create empty entries for template strings
@ -214,18 +215,18 @@ public class yacysearch {
return prop ;
return prop ;
}
}
if ( post . containsKey ( "auth" ) & & authenticatedUserName = = null ) {
if ( post . containsKey ( "auth" ) & & authenticatedUserName = = null ) {
/ *
/ *
* Access to authentication protected features is explicitely requested here
* Access to authentication protected features is explicitely requested here
* but no authentication is provided : ask now for authentication .
* but no authentication is provided : ask now for authentication .
* Wihout this , after timeout of HTTP Digest authentication nonce , browsers no more send authentication information
* Wihout this , after timeout of HTTP Digest authentication nonce , browsers no more send authentication information
* and as this page is not private , protected features would simply be hidden without asking browser again for authentication .
* and as this page is not private , protected features would simply be hidden without asking browser again for authentication .
* ( see mantis 766 : http : //mantis.tokeek.de/view.php?id=766) *
* ( see mantis 766 : http : //mantis.tokeek.de/view.php?id=766) *
* /
* /
prop . authenticationRequired ( ) ;
prop . authenticationRequired ( ) ;
return prop ;
return prop ;
}
}
// check for JSONP
// check for JSONP
if ( post . containsKey ( "callback" ) ) {
if ( post . containsKey ( "callback" ) ) {
final String jsonp = post . get ( "callback" ) + "([" ;
final String jsonp = post . get ( "callback" ) + "([" ;
@ -245,7 +246,7 @@ public class yacysearch {
// time zone
// time zone
int timezoneOffset = post . getInt ( "timezoneOffset" , 0 ) ;
int timezoneOffset = post . getInt ( "timezoneOffset" , 0 ) ;
// collect search attributes
// collect search attributes
// check an determine items per page (max of [100 or configured default]}
// check an determine items per page (max of [100 or configured default]}
@ -295,18 +296,18 @@ public class yacysearch {
// find search domain
// find search domain
final Classification . ContentDomain contentdom = post = = null | | ! post . containsKey ( "contentdom" ) ? ContentDomain . ALL : ContentDomain . contentdomParser ( post . get ( "contentdom" , "all" ) ) ;
final Classification . ContentDomain contentdom = post = = null | | ! post . containsKey ( "contentdom" ) ? ContentDomain . ALL : ContentDomain . contentdomParser ( post . get ( "contentdom" , "all" ) ) ;
// Strict/extended content domain constraint : configured setting may be overriden by request param
// Strict/extended content domain constraint : configured setting may be overriden by request param
final boolean strictContentDom = ! Boolean . FALSE . toString ( ) . equalsIgnoreCase ( post . get ( "strictContentDom" ,
final boolean strictContentDom = ! Boolean . FALSE . toString ( ) . equalsIgnoreCase ( post . get ( "strictContentDom" ,
sb . getConfig ( SwitchboardConstants . SEARCH_STRICT_CONTENT_DOM ,
sb . getConfig ( SwitchboardConstants . SEARCH_STRICT_CONTENT_DOM ,
String . valueOf ( SwitchboardConstants . SEARCH_STRICT_CONTENT_DOM_DEFAULT ) ) ) ) ;
String . valueOf ( SwitchboardConstants . SEARCH_STRICT_CONTENT_DOM_DEFAULT ) ) ) ) ;
/* Maximum number of suggestions to display in the first results page */
/* Maximum number of suggestions to display in the first results page */
final int meanMax = post . getInt ( "meanCount" , 0 ) ;
final int meanMax = post . getInt ( "meanCount" , 0 ) ;
boolean jsResort = global
boolean jsResort = global
& & ( contentdom = = ContentDomain . ALL | | contentdom = = ContentDomain . TEXT ) // For now JavaScript resorting can only be applied for text search
& & ( contentdom = = ContentDomain . ALL | | contentdom = = ContentDomain . TEXT ) // For now JavaScript resorting can only be applied for text search
& & sb . getConfigBool ( SwitchboardConstants . SEARCH_JS_RESORT , SwitchboardConstants . SEARCH_JS_RESORT_DEFAULT ) ;
& & sb . getConfigBool ( SwitchboardConstants . SEARCH_JS_RESORT , SwitchboardConstants . SEARCH_JS_RESORT_DEFAULT ) ;
// check the search tracker
// check the search tracker
TreeSet < Long > trackerHandles = sb . localSearchTracker . get ( client ) ;
TreeSet < Long > trackerHandles = sb . localSearchTracker . get ( client ) ;
@ -328,16 +329,16 @@ public class yacysearch {
ConcurrentLog . warn ( "LOCAL_SEARCH" , "ACCESS CONTROL: BLACKLISTED CLIENT FROM "
ConcurrentLog . warn ( "LOCAL_SEARCH" , "ACCESS CONTROL: BLACKLISTED CLIENT FROM "
+ client
+ client
+ " gets no permission to search" ) ;
+ " gets no permission to search" ) ;
if ( ! "html" . equals ( EXT ) ) {
if ( ! "html" . equals ( EXT ) ) {
/* API request : return the relevant HTTP status */
/* API request : return the relevant HTTP status */
throw new TemplateProcessingException ( "You are not allowed to search the web with this peer." ,
throw new TemplateProcessingException ( "You are not allowed to search the web with this peer." ,
HttpStatus . SC_FORBIDDEN ) ;
HttpStatus . SC_FORBIDDEN ) ;
}
}
} else if ( ! extendedSearchRights & & ! localhostAccess & & ! intranetMode ) {
} else if ( ! extendedSearchRights & & ! localhostAccess & & ! intranetMode ) {
// in case that we do a global search or we want to fetch snippets, we check for DoS cases
// in case that we do a global search or we want to fetch snippets, we check for DoS cases
final int accInThreeSeconds ;
final int accInThreeSeconds ;
final int accInOneMinute ;
final int accInOneMinute ;
final int accInTenMinutes ;
final int accInTenMinutes ;
synchronized ( trackerHandles ) {
synchronized ( trackerHandles ) {
accInThreeSeconds =
accInThreeSeconds =
trackerHandles . tailSet ( Long . valueOf ( System . currentTimeMillis ( ) - 3000 ) ) . size ( ) ;
trackerHandles . tailSet ( Long . valueOf ( System . currentTimeMillis ( ) - 3000 ) ) . size ( ) ;
@ -348,14 +349,14 @@ public class yacysearch {
}
}
// protections against too strong YaCy network load, reduces remote search
// protections against too strong YaCy network load, reduces remote search
if ( global ) {
if ( global ) {
if ( accInTenMinutes > = sb . getConfigInt ( SearchAccessRateConstants . PUBLIC_MAX_P2P_ACCESS_10MN . getKey ( ) ,
if ( accInTenMinutes > = sb . getConfigInt ( SearchAccessRateConstants . PUBLIC_MAX_P2P_ACCESS_10MN . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_P2P_ACCESS_10MN . getDefaultValue ( ) )
SearchAccessRateConstants . PUBLIC_MAX_P2P_ACCESS_10MN . getDefaultValue ( ) )
| | accInOneMinute > = sb . getConfigInt (
| | accInOneMinute > = sb . getConfigInt (
SearchAccessRateConstants . PUBLIC_MAX_P2P_ACCESS_1MN . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_P2P_ACCESS_1MN . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_P2P_ACCESS_1MN . getDefaultValue ( ) )
SearchAccessRateConstants . PUBLIC_MAX_P2P_ACCESS_1MN . getDefaultValue ( ) )
| | accInThreeSeconds > = sb . getConfigInt (
| | accInThreeSeconds > = sb . getConfigInt (
SearchAccessRateConstants . PUBLIC_MAX_P2P_ACCESS_3S . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_P2P_ACCESS_3S . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_P2P_ACCESS_3S . getDefaultValue ( ) ) ) {
SearchAccessRateConstants . PUBLIC_MAX_P2P_ACCESS_3S . getDefaultValue ( ) ) ) {
global = false ;
global = false ;
jsResort = false ;
jsResort = false ;
ConcurrentLog . warn ( "LOCAL_SEARCH" , "ACCESS CONTROL: CLIENT FROM "
ConcurrentLog . warn ( "LOCAL_SEARCH" , "ACCESS CONTROL: CLIENT FROM "
@ -369,13 +370,13 @@ public class yacysearch {
+ "/600s, "
+ "/600s, "
+ " requests, disallowed global search" ) ;
+ " requests, disallowed global search" ) ;
} else if ( accInTenMinutes > = sb . getConfigInt ( SearchAccessRateConstants . PUBLIC_MAX_P2P_JSRESORT_ACCESS_10MN . getKey ( ) ,
} else if ( accInTenMinutes > = sb . getConfigInt ( SearchAccessRateConstants . PUBLIC_MAX_P2P_JSRESORT_ACCESS_10MN . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_P2P_JSRESORT_ACCESS_10MN . getDefaultValue ( ) )
SearchAccessRateConstants . PUBLIC_MAX_P2P_JSRESORT_ACCESS_10MN . getDefaultValue ( ) )
| | accInOneMinute > = sb . getConfigInt (
| | accInOneMinute > = sb . getConfigInt (
SearchAccessRateConstants . PUBLIC_MAX_P2P_JSRESORT_ACCESS_1MN . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_P2P_JSRESORT_ACCESS_1MN . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_P2P_JSRESORT_ACCESS_1MN . getDefaultValue ( ) )
SearchAccessRateConstants . PUBLIC_MAX_P2P_JSRESORT_ACCESS_1MN . getDefaultValue ( ) )
| | accInThreeSeconds > = sb . getConfigInt (
| | accInThreeSeconds > = sb . getConfigInt (
SearchAccessRateConstants . PUBLIC_MAX_P2P_JSRESORT_ACCESS_3S . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_P2P_JSRESORT_ACCESS_3S . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_P2P_JSRESORT_ACCESS_3S . getDefaultValue ( ) ) ) {
SearchAccessRateConstants . PUBLIC_MAX_P2P_JSRESORT_ACCESS_3S . getDefaultValue ( ) ) ) {
jsResort = false ;
jsResort = false ;
ConcurrentLog . warn ( "LOCAL_SEARCH" , "ACCESS CONTROL: CLIENT FROM "
ConcurrentLog . warn ( "LOCAL_SEARCH" , "ACCESS CONTROL: CLIENT FROM "
+ client
+ client
@ -391,15 +392,15 @@ public class yacysearch {
}
}
// protection against too many remote server snippet loads (protects traffic on server)
// protection against too many remote server snippet loads (protects traffic on server)
if ( snippetFetchStrategy ! = null & & snippetFetchStrategy . isAllowedToFetchOnline ( ) ) {
if ( snippetFetchStrategy ! = null & & snippetFetchStrategy . isAllowedToFetchOnline ( ) ) {
if ( accInTenMinutes > = sb . getConfigInt (
if ( accInTenMinutes > = sb . getConfigInt (
SearchAccessRateConstants . PUBLIC_MAX_REMOTE_SNIPPET_ACCESS_10MN . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_REMOTE_SNIPPET_ACCESS_10MN . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_REMOTE_SNIPPET_ACCESS_10MN . getDefaultValue ( ) )
SearchAccessRateConstants . PUBLIC_MAX_REMOTE_SNIPPET_ACCESS_10MN . getDefaultValue ( ) )
| | accInOneMinute > = sb . getConfigInt (
| | accInOneMinute > = sb . getConfigInt (
SearchAccessRateConstants . PUBLIC_MAX_REMOTE_SNIPPET_ACCESS_1MN . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_REMOTE_SNIPPET_ACCESS_1MN . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_REMOTE_SNIPPET_ACCESS_1MN . getDefaultValue ( ) )
SearchAccessRateConstants . PUBLIC_MAX_REMOTE_SNIPPET_ACCESS_1MN . getDefaultValue ( ) )
| | accInThreeSeconds > = sb . getConfigInt (
| | accInThreeSeconds > = sb . getConfigInt (
SearchAccessRateConstants . PUBLIC_MAX_REMOTE_SNIPPET_ACCESS_3S . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_REMOTE_SNIPPET_ACCESS_3S . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_REMOTE_SNIPPET_ACCESS_3S . getDefaultValue ( ) ) ) {
SearchAccessRateConstants . PUBLIC_MAX_REMOTE_SNIPPET_ACCESS_3S . getDefaultValue ( ) ) ) {
snippetFetchStrategy = CacheStrategy . CACHEONLY ;
snippetFetchStrategy = CacheStrategy . CACHEONLY ;
ConcurrentLog . warn ( "LOCAL_SEARCH" , "ACCESS CONTROL: CLIENT FROM "
ConcurrentLog . warn ( "LOCAL_SEARCH" , "ACCESS CONTROL: CLIENT FROM "
+ client
+ client
@ -415,23 +416,23 @@ public class yacysearch {
}
}
// general load protection
// general load protection
String timePeriodMsg = "" ;
String timePeriodMsg = "" ;
if ( accInTenMinutes > = sb . getConfigInt ( SearchAccessRateConstants . PUBLIC_MAX_ACCESS_10MN . getKey ( ) ,
if ( accInTenMinutes > = sb . getConfigInt ( SearchAccessRateConstants . PUBLIC_MAX_ACCESS_10MN . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_ACCESS_10MN . getDefaultValue ( ) ) ) {
SearchAccessRateConstants . PUBLIC_MAX_ACCESS_10MN . getDefaultValue ( ) ) ) {
block = true ;
block = true ;
timePeriodMsg = "ten minutes" ;
timePeriodMsg = "ten minutes" ;
prop . put ( "num-results_blockReason" , 2 ) ;
prop . put ( "num-results_blockReason" , 2 ) ;
} else if ( accInOneMinute > = sb . getConfigInt ( SearchAccessRateConstants . PUBLIC_MAX_ACCESS_1MN . getKey ( ) ,
} else if ( accInOneMinute > = sb . getConfigInt ( SearchAccessRateConstants . PUBLIC_MAX_ACCESS_1MN . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_ACCESS_1MN . getDefaultValue ( ) ) ) {
SearchAccessRateConstants . PUBLIC_MAX_ACCESS_1MN . getDefaultValue ( ) ) ) {
block = true ;
block = true ;
timePeriodMsg = "one minute" ;
timePeriodMsg = "one minute" ;
prop . put ( "num-results_blockReason" , 3 ) ;
prop . put ( "num-results_blockReason" , 3 ) ;
} else if ( accInThreeSeconds > = sb . getConfigInt ( SearchAccessRateConstants . PUBLIC_MAX_ACCESS_3S . getKey ( ) ,
} else if ( accInThreeSeconds > = sb . getConfigInt ( SearchAccessRateConstants . PUBLIC_MAX_ACCESS_3S . getKey ( ) ,
SearchAccessRateConstants . PUBLIC_MAX_ACCESS_3S . getDefaultValue ( ) ) ) {
SearchAccessRateConstants . PUBLIC_MAX_ACCESS_3S . getDefaultValue ( ) ) ) {
block = true ;
block = true ;
timePeriodMsg = "three seconds" ;
timePeriodMsg = "three seconds" ;
prop . put ( "num-results_blockReason" , 4 ) ;
prop . put ( "num-results_blockReason" , 4 ) ;
}
}
if ( block ) {
if ( block ) {
ConcurrentLog . warn ( "LOCAL_SEARCH" , "ACCESS CONTROL: CLIENT FROM "
ConcurrentLog . warn ( "LOCAL_SEARCH" , "ACCESS CONTROL: CLIENT FROM "
+ client
+ client
+ ": "
+ ": "
@ -442,21 +443,21 @@ public class yacysearch {
+ accInTenMinutes
+ accInTenMinutes
+ "/600s, "
+ "/600s, "
+ " requests, disallowed search" ) ;
+ " requests, disallowed search" ) ;
if ( ! "html" . equals ( EXT ) ) {
if ( ! "html" . equals ( EXT ) ) {
/ *
/ *
* API request : return the relevant HTTP status ( 429 - Too Many Requests - see
* API request : return the relevant HTTP status ( 429 - Too Many Requests - see
* https : //tools.ietf.org/html/rfc6585#section-4)
* https : //tools.ietf.org/html/rfc6585#section-4)
* /
* /
throw new TemplateProcessingException (
throw new TemplateProcessingException (
"You have reached the maximum allowed number of accesses to this search service within "
"You have reached the maximum allowed number of accesses to this search service within "
+ timePeriodMsg + ". Please try again later or log in as administrator or as a user with extended search right." ,
+ timePeriodMsg + ". Please try again later or log in as administrator or as a user with extended search right." ,
429 ) ;
429 ) ;
}
}
}
}
}
}
if ( block ) {
if ( block ) {
prop . put ( "num-results" , 5 ) ;
prop . put ( "num-results" , 5 ) ;
} else {
} else {
String urlmask = ( post = = null ) ? ".*" : post . get ( "urlmaskfilter" , ".*" ) ; // the expression must be a subset of the java Match syntax described in http://lucene.apache.org/core/4_4_0/core/org/apache/lucene/util/automaton/RegExp.html
String urlmask = ( post = = null ) ? ".*" : post . get ( "urlmaskfilter" , ".*" ) ; // the expression must be a subset of the java Match syntax described in http://lucene.apache.org/core/4_4_0/core/org/apache/lucene/util/automaton/RegExp.html
String tld = null ;
String tld = null ;
@ -475,7 +476,7 @@ public class yacysearch {
// read collection
// read collection
modifier . collection = post . get ( "collection" , modifier . collection ) ; // post arguments may overrule parsed collection values
modifier . collection = post . get ( "collection" , modifier . collection ) ; // post arguments may overrule parsed collection values
int stp = querystring . indexOf ( '*' ) ;
int stp = querystring . indexOf ( '*' ) ;
if ( stp > = 0 ) {
if ( stp > = 0 ) {
// if the star appears as a single entry, use the catchallstring
// if the star appears as a single entry, use the catchallstring
@ -554,7 +555,7 @@ public class yacysearch {
if ( mt ! = null ) {
if ( mt ! = null ) {
metatags . add ( mt ) ;
metatags . add ( mt ) ;
} else {
} else {
}
}
}
}
}
}
@ -587,13 +588,13 @@ public class yacysearch {
querystring = querystring . replace ( "/heuristic" , "" ) ;
querystring = querystring . replace ( "/heuristic" , "" ) ;
modifier . add ( "/heuristic" ) ;
modifier . add ( "/heuristic" ) ;
}
}
final String tldModifierPrefix = "tld:" ;
final String tldModifierPrefix = "tld:" ;
final int tldp = querystring . indexOf ( tldModifierPrefix , 0 ) ;
final int tldp = querystring . indexOf ( tldModifierPrefix , 0 ) ;
if ( tldp > = 0 ) {
if ( tldp > = 0 ) {
int ftb = querystring . indexOf ( ' ' , tldp ) ;
int ftb = querystring . indexOf ( ' ' , tldp ) ;
if ( ftb = = - 1 ) {
if ( ftb = = - 1 ) {
ftb = querystring . length ( ) ;
ftb = querystring . length ( ) ;
}
}
tld = querystring . substring ( tldp + tldModifierPrefix . length ( ) , ftb ) ;
tld = querystring . substring ( tldp + tldModifierPrefix . length ( ) , ftb ) ;
querystring = querystring . replace ( tldModifierPrefix + tld , "" ) ;
querystring = querystring . replace ( tldModifierPrefix + tld , "" ) ;
@ -602,20 +603,20 @@ public class yacysearch {
tld = tld . substring ( 1 ) ;
tld = tld . substring ( 1 ) ;
}
}
if ( tld . length ( ) = = 0 ) {
if ( tld . length ( ) = = 0 ) {
tld = null ;
tld = null ;
} else {
} else {
try {
try {
/* Convert to the same lower case ASCII Compatible Encoding that is used in normalized URLs */
/* Convert to the same lower case ASCII Compatible Encoding that is used in normalized URLs */
tld = IDN . toASCII ( tld , 0 ) ;
tld = IDN . toASCII ( tld , 0 ) ;
} catch ( final IllegalArgumentException e ) {
} catch ( final IllegalArgumentException e ) {
ConcurrentLog . warn ( "LOCAL_SEARCH" , "Failed to convert tld modifier value " + tld + "to ASCII Compatible Encoding (ACE)" , e ) ;
ConcurrentLog . warn ( "LOCAL_SEARCH" , "Failed to convert tld modifier value " + tld + "to ASCII Compatible Encoding (ACE)" , e ) ;
}
}
/* Domain name in an URL is case insensitive : convert now modifier to lower case for further processing over normalized URLs */
/* Domain name in an URL is case insensitive : convert now modifier to lower case for further processing over normalized URLs */
tld = tld . toLowerCase ( Locale . ROOT ) ;
tld = tld . toLowerCase ( Locale . ROOT ) ;
}
}
}
}
if ( urlmask = = null | | urlmask . isEmpty ( ) ) urlmask = ".*" ; //if no urlmask was given
if ( urlmask = = null | | urlmask . isEmpty ( ) ) urlmask = ".*" ; //if no urlmask was given
// read the language from the language-restrict option 'lr'
// read the language from the language-restrict option 'lr'
@ -644,12 +645,12 @@ public class yacysearch {
// filter out stopwords
// filter out stopwords
final SortedSet < String > filtered = SetTools . joinConstructiveByTest ( qg . getIncludeWords ( ) , Switchboard . stopwords ) ; //find matching stopwords
final SortedSet < String > filtered = SetTools . joinConstructiveByTest ( qg . getIncludeWords ( ) , Switchboard . stopwords ) ; //find matching stopwords
qg . removeIncludeWords ( filtered ) ;
qg . removeIncludeWords ( filtered ) ;
// if a minus-button was hit, remove a special reference first
// if a minus-button was hit, remove a special reference first
if ( post ! = null & & post . containsKey ( "deleteref" ) ) {
if ( post ! = null & & post . containsKey ( "deleteref" ) ) {
try {
try {
if ( ! sb . verifyAuthentication ( header ) ) {
if ( ! sb . verifyAuthentication ( header ) ) {
prop . authenticationRequired ( ) ;
prop . authenticationRequired ( ) ;
return prop ;
return prop ;
}
}
@ -680,7 +681,7 @@ public class yacysearch {
// if a plus-button was hit, create new voting message
// if a plus-button was hit, create new voting message
if ( post ! = null & & post . containsKey ( "recommendref" ) ) {
if ( post ! = null & & post . containsKey ( "recommendref" ) ) {
if ( ! sb . verifyAuthentication ( header ) ) {
if ( ! sb . verifyAuthentication ( header ) ) {
prop . authenticationRequired ( ) ;
prop . authenticationRequired ( ) ;
return prop ;
return prop ;
}
}
final String recommendHash = post . get ( "recommendref" , "" ) ; // urlhash
final String recommendHash = post . get ( "recommendref" , "" ) ; // urlhash
@ -783,10 +784,10 @@ public class yacysearch {
sb . getConfigSet ( "search.navigation" ) ) ;
sb . getConfigSet ( "search.navigation" ) ) ;
theQuery . setStrictContentDom ( strictContentDom ) ;
theQuery . setStrictContentDom ( strictContentDom ) ;
theQuery . setMaxSuggestions ( meanMax ) ;
theQuery . setMaxSuggestions ( meanMax ) ;
theQuery . setStandardFacetsMaxCount ( sb . getConfigInt ( SwitchboardConstants . SEARCH_NAVIGATION_MAXCOUNT ,
theQuery . setStandardFacetsMaxCount ( sb . getConfigInt ( SwitchboardConstants . SEARCH_NAVIGATION_MAXCOUNT ,
QueryParams . FACETS_STANDARD_MAXCOUNT_DEFAULT ) ) ;
QueryParams . FACETS_STANDARD_MAXCOUNT_DEFAULT ) ) ;
theQuery . setDateFacetMaxCount ( sb . getConfigInt ( SwitchboardConstants . SEARCH_NAVIGATION_DATES_MAXCOUNT ,
theQuery . setDateFacetMaxCount ( sb . getConfigInt ( SwitchboardConstants . SEARCH_NAVIGATION_DATES_MAXCOUNT ,
QueryParams . FACETS_DATE_MAXCOUNT_DEFAULT ) ) ;
QueryParams . FACETS_DATE_MAXCOUNT_DEFAULT ) ) ;
EventTracker . delete ( EventTracker . EClass . SEARCH ) ;
EventTracker . delete ( EventTracker . EClass . SEARCH ) ;
EventTracker . update ( EventTracker . EClass . SEARCH , new ProfilingGraph . EventSearch (
EventTracker . update ( EventTracker . EClass . SEARCH , new ProfilingGraph . EventSearch (
theQuery . id ( true ) ,
theQuery . id ( true ) ,
@ -837,9 +838,9 @@ public class yacysearch {
sb . getConfigLong (
sb . getConfigLong (
SwitchboardConstants . REMOTESEARCH_MAXTIME_USER ,
SwitchboardConstants . REMOTESEARCH_MAXTIME_USER ,
sb . getConfigLong ( SwitchboardConstants . REMOTESEARCH_MAXTIME_DEFAULT , 3000 ) ) ) ;
sb . getConfigLong ( SwitchboardConstants . REMOTESEARCH_MAXTIME_DEFAULT , 3000 ) ) ) ;
if ( post . getBoolean ( "resortCachedResults" ) & & cachedEvent = = theSearch ) {
if ( post . getBoolean ( "resortCachedResults" ) & & cachedEvent = = theSearch ) {
theSearch . resortCachedResults ( ) ;
theSearch . resortCachedResults ( ) ;
}
}
if ( startRecord = = 0 & & extendedSearchRights & & ! stealthmode ) {
if ( startRecord = = 0 & & extendedSearchRights & & ! stealthmode ) {
@ -888,9 +889,9 @@ public class yacysearch {
try {
try {
suggestion = meanIt . next ( ) . toString ( ) ;
suggestion = meanIt . next ( ) . toString ( ) ;
prop . put ( "didYouMean_suggestions_" + meanCount + "_word" , suggestion ) ;
prop . put ( "didYouMean_suggestions_" + meanCount + "_word" , suggestion ) ;
prop . put ( "didYouMean_suggestions_" + meanCount + "_url" ,
prop . put ( "didYouMean_suggestions_" + meanCount + "_url" ,
QueryParams . navUrlWithNewQueryString ( RequestHeader . FileType . HTML , 0 , theQuery ,
QueryParams . navUrlWithNewQueryString ( RequestHeader . FileType . HTML , 0 , theQuery ,
suggestion , authenticatedUserName ! = null ) ) ;
suggestion , authenticatedUserName ! = null ) ) ;
prop . put ( "didYouMean_suggestions_" + meanCount + "_sep" , "|" ) ;
prop . put ( "didYouMean_suggestions_" + meanCount + "_sep" , "|" ) ;
meanCount + + ;
meanCount + + ;
} catch ( final ConcurrentModificationException e ) {
} catch ( final ConcurrentModificationException e ) {
@ -926,7 +927,7 @@ public class yacysearch {
prop . put ( "geoinfo_loc" , i ) ;
prop . put ( "geoinfo_loc" , i ) ;
prop . put ( "geoinfo" , "1" ) ;
prop . put ( "geoinfo" , "1" ) ;
}
}
// update the search tracker
// update the search tracker
try {
try {
synchronized ( trackerHandles ) {
synchronized ( trackerHandles ) {
@ -957,17 +958,17 @@ public class yacysearch {
prop . put ( "num-results_globalresults_remoteResourceSize" , Formatter . number ( theSearch . remote_rwi_stored . get ( ) + theSearch . remote_solr_stored . get ( ) , true ) ) ;
prop . put ( "num-results_globalresults_remoteResourceSize" , Formatter . number ( theSearch . remote_rwi_stored . get ( ) + theSearch . remote_solr_stored . get ( ) , true ) ) ;
prop . put ( "num-results_globalresults_remoteIndexCount" , Formatter . number ( theSearch . remote_rwi_available . get ( ) + theSearch . remote_solr_available . get ( ) , true ) ) ;
prop . put ( "num-results_globalresults_remoteIndexCount" , Formatter . number ( theSearch . remote_rwi_available . get ( ) + theSearch . remote_solr_available . get ( ) , true ) ) ;
prop . put ( "num-results_globalresults_remotePeerCount" , Formatter . number ( theSearch . remote_rwi_peerCount . get ( ) + theSearch . remote_solr_peerCount . get ( ) , true ) ) ;
prop . put ( "num-results_globalresults_remotePeerCount" , Formatter . number ( theSearch . remote_rwi_peerCount . get ( ) + theSearch . remote_solr_peerCount . get ( ) , true ) ) ;
prop . put ( "jsResort" , jsResort ) ;
prop . put ( "jsResort" , jsResort ) ;
prop . put ( "num-results_jsResort" , jsResort ) ;
prop . put ( "num-results_jsResort" , jsResort ) ;
/ * In p2p mode only and if JavaScript resorting is not enabled , add a link allowing user to resort already drained results ,
/ * In p2p mode only and if JavaScript resorting is not enabled , add a link allowing user to resort already drained results ,
* eventually including fetched results with higher ranks from the Solr and RWI stacks * /
* eventually including fetched results with higher ranks from the Solr and RWI stacks * /
prop . put ( "resortEnabled" , ! jsResort & & global & & ! stealthmode & & theSearch . resortCacheAllowed . availablePermits ( ) > 0 ? 1 : 0 ) ;
prop . put ( "resortEnabled" , ! jsResort & & global & & ! stealthmode & & theSearch . resortCacheAllowed . availablePermits ( ) > 0 ? 1 : 0 ) ;
prop . put ( "resortEnabled_url" ,
prop . put ( "resortEnabled_url" ,
QueryParams . navurlBase ( RequestHeader . FileType . HTML , theQuery , null , true , authenticatedUserName ! = null )
QueryParams . navurlBase ( RequestHeader . FileType . HTML , theQuery , null , true , authenticatedUserName ! = null )
. append ( "&startRecord=" ) . append ( startRecord ) . append ( "&resortCachedResults=true" )
. append ( "&startRecord=" ) . append ( startRecord ) . append ( "&resortCachedResults=true" )
. toString ( ) ) ;
. toString ( ) ) ;
// generate the search result lines; the content will be produced by another servlet
// generate the search result lines; the content will be produced by another servlet
for ( int i = 0 ; i < theQuery . itemsPerPage ( ) ; i + + ) {
for ( int i = 0 ; i < theQuery . itemsPerPage ( ) ; i + + ) {
@ -1005,36 +1006,36 @@ public class yacysearch {
prop . put ( "depth" , "0" ) ;
prop . put ( "depth" , "0" ) ;
prop . put ( "localQuery" , theSearch . query . isLocal ( ) ? "1" : "0" ) ;
prop . put ( "localQuery" , theSearch . query . isLocal ( ) ? "1" : "0" ) ;
prop . put ( "jsResort_localQuery" , theSearch . query . isLocal ( ) ? "1" : "0" ) ;
prop . put ( "jsResort_localQuery" , theSearch . query . isLocal ( ) ? "1" : "0" ) ;
final boolean showLogin = sb . getConfigBool ( SwitchboardConstants . SEARCH_PUBLIC_TOP_NAV_BAR_LOGIN ,
final boolean showLogin = sb . getConfigBool ( SwitchboardConstants . SEARCH_PUBLIC_TOP_NAV_BAR_LOGIN ,
SwitchboardConstants . SEARCH_PUBLIC_TOP_NAV_BAR_LOGIN_DEFAULT ) ;
SwitchboardConstants . SEARCH_PUBLIC_TOP_NAV_BAR_LOGIN_DEFAULT ) ;
if ( showLogin ) {
if ( showLogin ) {
if ( authenticatedUserName ! = null ) {
if ( authenticatedUserName ! = null ) {
/* Show the name of the authenticated user */
/* Show the name of the authenticated user */
prop . put ( "showLogin" , 1 ) ;
prop . put ( "showLogin" , 1 ) ;
prop . put ( "showLogin_userName" , authenticatedUserName ) ;
prop . put ( "showLogin_userName" , authenticatedUserName ) ;
} else {
} else {
/* Show a login link */
/* Show a login link */
prop . put ( "showLogin" , 2 ) ;
prop . put ( "showLogin" , 2 ) ;
prop . put ( "showLogin_loginURL" ,
prop . put ( "showLogin_loginURL" ,
QueryParams . navurlBase ( RequestHeader . FileType . HTML , theQuery , null , true , true ) . toString ( ) ) ;
QueryParams . navurlBase ( RequestHeader . FileType . HTML , theQuery , null , true , true ) . toString ( ) ) ;
}
}
} else {
} else {
prop . put ( "showLogin" , 0 ) ;
prop . put ( "showLogin" , 0 ) ;
}
}
}
}
prop . put ( "focus" , focus ? 1 : 0 ) ; // focus search field
prop . put ( "focus" , focus ? 1 : 0 ) ; // focus search field
prop . put ( "searchagain" , global ? "1" : "0" ) ;
prop . put ( "searchagain" , global ? "1" : "0" ) ;
String former = originalquerystring . replaceAll ( Segment . catchallString , "*" ) ;
String former = originalquerystring . replaceAll ( Segment . catchallString , "*" ) ; // hide catchallString in output
prop . putHTML ( "former" , former ) ;
prop . putHTML ( "former" , former ) ;
try {
try {
prop . put ( "formerEncoded" , URLEncoder . encode ( former , StandardCharsets . UTF_8 . name ( ) ) ) ;
prop . put ( "formerEncoded" , URLEncoder . encode ( former , StandardCharsets . UTF_8 . name ( ) ) ) ;
} catch ( UnsupportedEncodingException e ) {
} catch ( UnsupportedEncodingException e ) {
ConcurrentLog . warn ( "LOCAL_SEARCH" , "Unsupported UTF-8 encoding!" ) ;
ConcurrentLog . warn ( "LOCAL_SEARCH" , "Unsupported UTF-8 encoding!" ) ;
prop . put ( "formerEncoded" , former ) ;
prop . put ( "formerEncoded" , former ) ;
}
}
prop . put ( "count" , itemsPerPage ) ;
prop . put ( "count" , itemsPerPage ) ;
prop . put ( "offset" , startRecord ) ;
prop . put ( "offset" , startRecord ) ;
prop . put ( "resource" , global ? "global" : "local" ) ;
prop . put ( "resource" , global ? "global" : "local" ) ;