📄 trtrackerserverprocessortcp.java
字号:
http_port = Integer.parseInt( rhs );
}else if ( lhs.equals( "azver" )){
az_ver = Integer.parseInt( rhs );
}else if ( lhs.equals( "supportcrypto" )){
if ( crypto_level == TRTrackerServerPeer.CRYPTO_NONE ){
crypto_level = TRTrackerServerPeer.CRYPTO_SUPPORTED;
}
}else if ( lhs.equals( "requirecrypto" )){
crypto_level = TRTrackerServerPeer.CRYPTO_REQUIRED;
}else if ( lhs.equals( "cryptoport" )){
crypto_port = Integer.parseInt( rhs );
}else if ( lhs.equals( "azq" )){
stop_to_queue = true;
}else if ( lhs.equals( "azsf" )){
scrape_flags = rhs;
}else if ( TRTrackerServerImpl.supportsExtensions()){
if ( lhs.equals( "aznp" )){
try{
network_position = DHTNetworkPositionManager.deserialisePosition( Base32.decode( rhs ));
}catch( Throwable e ){
}
}else if ( lhs.equals( "azup" )){
up_speed = Integer.parseInt( rhs );
}
}
if ( p1 == -1 ){
break;
}
}
if ( crypto_level == TRTrackerServerPeer.CRYPTO_REQUIRED ){
if ( crypto_port != 0 ){
tcp_port = crypto_port;
}
}
byte[][] hashes = null;
if ( hash_list != null ){
hashes = new byte[hash_list.size()][];
hash_list.toArray( hashes );
}else if ( hash != null ){
hashes = new byte[][]{ hash };
}
// >= so that if this tracker is "old" and sees a version 3+ it replies with the
// best it can - version 2
if ( az_ver >= 2 ){
compact_mode = TRTrackerServerTorrentImpl.COMPACT_MODE_AZ_2;
}
Map[] root_out = new Map[1];
TRTrackerServerPeerImpl[] peer_out = new TRTrackerServerPeerImpl[1];
specific_torrent =
processTrackerRequest(
server, str,
root_out, peer_out,
request_type,
hashes, scrape_flags,
peer_id, no_peer_id, compact_mode, key,
event, stop_to_queue,
tcp_port&0xffff, udp_port&0xffff, http_port&0xffff,
real_ip_address,
client_ip_address,
downloaded, uploaded, left,
num_want,
crypto_level,
(byte)az_ver,
up_speed,
network_position );
root = root_out[0];
if ( request_type == TRTrackerServerRequest.RT_SCRAPE ){
// add in tracker type for az clients so they know this is an AZ tracker
if ( lowercase_input_header.indexOf( lc_azureus_name ) != -1 ){
root.put( "aztracker", new Long(1));
}
}
// only post-process if this isn't a cached entry
if ( root.get( "_data" ) == null ){
TRTrackerServerPeer post_process_peer = peer_out[0];
if ( post_process_peer == null ){
post_process_peer = new lightweightPeer( client_ip_address, tcp_port, peer_id );
}
server.postProcess( post_process_peer, specific_torrent, request_type, str, root );
}
}catch( Exception e ){
if ( e instanceof TRTrackerServerException ){
TRTrackerServerException tr_excep = (TRTrackerServerException)e;
int reason = tr_excep.getResponseCode();
if ( reason != -1 ){
String resp = "HTTP/1.1 " + reason + " " + tr_excep.getResponseText() + NL;
Map headers = tr_excep.getResponseHeaders();
Iterator it = headers.entrySet().iterator();
while( it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
String key = (String)entry.getKey();
String value = (String)entry.getValue();
resp += key + ": " + value + NL;
}
resp += NL;
os.write( resp.getBytes());
os.flush();
return;
}
}else if ( e instanceof NullPointerException ){
e.printStackTrace();
}
String message = e.getMessage();
// e.printStackTrace();
if ( message == null || message.length() == 0 ){
// e.printStackTrace();
message = e.toString();
}
root = new HashMap();
root.put( "failure reason", message );
}
setTaskState( "writing response" );
// cache both plain and gzip encoded data for possible reuse
byte[] data = (byte[])root.get( "_data" );
if ( data == null ){
data = BEncoder.encode( root );
root.put( "_data", data );
}
if ( gzip_reply ){
byte[] gzip_data = (byte[])root.get( "_gzipdata");
if ( gzip_data == null ){
ByteArrayOutputStream tos = new ByteArrayOutputStream(data.length);
GZIPOutputStream gos = new GZIPOutputStream( tos );
gos.write( data );
gos.close();
gzip_data = tos.toByteArray();
root.put( "_gzipdata", gzip_data );
}
data = gzip_data;
}
// System.out.println( "TRTrackerServerProcessor::reply: sending " + new String(data));
// write the response
setTaskState( "writing header" );
os.write( HTTP_RESPONSE_START );
byte[] length_bytes = String.valueOf(data.length).getBytes();
os.write( length_bytes );
int header_len = HTTP_RESPONSE_START.length + length_bytes.length;
setTaskState( "writing content" );
if ( gzip_reply ){
os.write( HTTP_RESPONSE_END_GZIP );
header_len += HTTP_RESPONSE_END_GZIP.length;
}else{
os.write( HTTP_RESPONSE_END_NOGZIP );
header_len += HTTP_RESPONSE_END_NOGZIP.length;
}
os.write( data );
server.updateStats( specific_torrent, input_header.length(), header_len+data.length );
}finally{
setTaskState( "final os flush" );
os.flush();
}
}
protected String
doAuthentication(
String url_path,
String header,
OutputStream os,
boolean tracker )
throws IOException
{
// System.out.println( "doAuth: " + server.isTrackerPasswordEnabled() + "/" + server.isWebPasswordEnabled());
boolean apply_web_password = (!tracker) && server.isWebPasswordEnabled();
boolean apply_torrent_password = tracker && server.isTrackerPasswordEnabled();
if ( apply_web_password &&
server.isWebPasswordHTTPSOnly() &&
!server.isSSL()){
os.write( ("HTTP/1.1 403 BAD\r\n\r\nAccess Denied\r\n").getBytes() );
os.flush();
return( null );
}else if ( apply_torrent_password ||
apply_web_password ){
int x = header.indexOf( "Authorization:" );
if ( x == -1 ){
// auth missing. however, if we have external auth defined
// and external auth is happy with junk then allow it through
if ( server.hasExternalAuthorisation()){
try{
String resource_str =
( server.isSSL()?"https":"http" ) + "://" +
server.getHost() + ":" + server.getPort() + url_path;
URL resource = new URL( resource_str );
if ( server.performExternalAuthorisation( resource, "", "" )){
return( "" );
}
}catch( MalformedURLException e ){
Debug.printStackTrace( e );
}
}
}else{
// Authorization: Basic dG9tY2F0OnRvbWNhdA==
int p1 = header.indexOf(' ', x );
int p2 = header.indexOf(' ', p1+1 );
String body = header.substring( p2, header.indexOf( '\r', p2 )).trim();
String decoded=new String( Base64.decode(body));
// username:password
int cp = decoded.indexOf(':');
String user = decoded.substring(0,cp);
String pw = decoded.substring(cp+1);
boolean auth_failed = false;
if ( server.hasExternalAuthorisation()){
try{
String resource_str =
( server.isSSL()?"https":"http" ) + "://" +
server.getHost() + ":" + server.getPort() + url_path;
URL resource = new URL( resource_str );
if ( server.performExternalAuthorisation( resource, user, pw )){
return( user );
}
}catch( MalformedURLException e ){
Debug.printStackTrace( e );
}
auth_failed = true;
}
if ( server.hasInternalAuthorisation() && !auth_failed ){
try{
SHA1Hasher hasher = new SHA1Hasher();
byte[] password = pw.getBytes();
byte[] encoded;
if( password.length > 0){
encoded = hasher.calculateHash(password);
}else{
encoded = new byte[0];
}
if ( user.equals( "<internal>")){
byte[] internal_pw = Base64.decode(pw);
if ( Arrays.equals( internal_pw, server.getPassword())){
return( user );
}
}else if ( user.equalsIgnoreCase(server.getUsername()) &&
Arrays.equals(encoded, server.getPassword())){
return( user );
}
}catch( Exception e ){
Debug.printStackTrace( e );
}
}
}
os.write( ("HTTP/1.1 401 BAD\r\nWWW-Authenticate: Basic realm=\"" + server.getName() + "\"\r\n\r\nAccess Denied\r\n").getBytes() );
os.flush();
return( null );
}else{
return( "" );
}
}
protected boolean
handleExternalRequest(
InetSocketAddress client_address,
String user,
String url,
String header,
InputStream is,
OutputStream os )
throws IOException
{
URL absolute_url = new URL( server_url + (url.startsWith("/")?url:("/"+url)));
return( server.handleExternalRequest(client_address,user,url,absolute_url,header, is, os));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -