📄 trtrackerserverprocessortcp.java
字号:
/*
* File : TRTrackerServerProcessor.java
* Created : 5 Oct. 2003
* By : Parg
*
* Azureus - a Java Bittorrent client
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* This program 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 General Public License for more details ( see the LICENSE file ).
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.gudy.azureus2.core3.tracker.server.impl.tcp;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.zip.GZIPOutputStream;
import org.gudy.azureus2.core3.tracker.server.*;
import org.gudy.azureus2.core3.tracker.server.impl.*;
import org.gudy.azureus2.core3.util.*;
import org.bouncycastle.util.encoders.Base64;
import com.aelitis.azureus.core.dht.netcoords.DHTNetworkPosition;
import com.aelitis.azureus.core.dht.netcoords.DHTNetworkPositionManager;
public abstract class
TRTrackerServerProcessorTCP
extends TRTrackerServerProcessor
{
protected static final int SOCKET_TIMEOUT = 5000;
protected static final char CR = '\015';
protected static final char FF = '\012';
protected static final String NL = "\015\012";
private static final String lc_azureus_name = Constants.AZUREUS_NAME.toLowerCase();
protected static final byte[] HTTP_RESPONSE_START = (
"HTTP/1.1 200 OK" + NL +
"Content-Type: text/html" + NL +
"Server: " + Constants.AZUREUS_NAME + " " + Constants.AZUREUS_VERSION + NL +
"Connection: close" + NL +
"Content-Length: ").getBytes();
protected static final byte[] HTTP_RESPONSE_END_GZIP = (NL + "Content-Encoding: gzip" + NL + NL).getBytes();
protected static final byte[] HTTP_RESPONSE_END_NOGZIP = (NL + NL).getBytes();
private TRTrackerServerTCP server;
private String server_url;
private boolean disable_timeouts = false;
protected
TRTrackerServerProcessorTCP(
TRTrackerServerTCP _server )
{
server = _server;
server_url = (server.isSSL()?"https":"http") + "://" + server.getHost() + ":" + server.getPort();
}
protected boolean
areTimeoutsDisabled()
{
return( disable_timeouts );
}
protected void
setTimeoutsDisabled(
boolean d )
{
disable_timeouts = d;
}
protected TRTrackerServerTCP
getServer()
{
return( server );
}
protected void
processRequest(
String input_header,
String lowercase_input_header,
String url_path,
InetSocketAddress client_address,
boolean announce_and_scrape_only,
InputStream is,
OutputStream os )
throws IOException
{
String str = url_path;
try{
Map root = null;
TRTrackerServerTorrentImpl specific_torrent = null;
boolean gzip_reply = false;
try{
int request_type;
if ( str.startsWith( "/announce?" )){
request_type = TRTrackerServerRequest.RT_ANNOUNCE;
str = str.substring(10);
}else if ( str.startsWith( "/scrape?" )){
request_type = TRTrackerServerRequest.RT_SCRAPE;
str = str.substring(8);
}else if ( str.equals( "/scrape" )){
request_type = TRTrackerServerRequest.RT_FULL_SCRAPE;
str = "";
}else{
String redirect = TRTrackerServerImpl.redirect_on_not_found;
if ( announce_and_scrape_only ){
if ( redirect.length() == 0 ){
throw( new Exception( "Tracker only supports announce and scrape functions" ));
}
}else{
setTaskState( "external request" );
disable_timeouts = true;
// check non-tracker authentication
String user = doAuthentication( url_path, input_header, os, false );
if ( user == null ){
return;
}
if ( handleExternalRequest( client_address, user, str, input_header, is, os )){
return;
}
}
if ( redirect.length() > 0 ){
os.write( ("HTTP/1.1 301 Moved Permanently" + NL + "Location: " + redirect + NL + NL).getBytes() );
}else{
os.write( ("HTTP/1.1 404 Not Found" + NL + NL ).getBytes() );
}
os.flush();
return; // throw( new Exception( "Unsupported Request Type"));
}
// OK, here its an announce, scrape or full scrape
// check tracker authentication
if ( doAuthentication( url_path, input_header, os, true ) == null ){
return;
}
int enc_pos = lowercase_input_header.indexOf( "accept-encoding:");
if ( enc_pos != -1 ){
int e_pos = input_header.indexOf( NL, enc_pos );
if ( e_pos != -1 ){
// check we've not found X-Accept-Encoding (for example)
if ( enc_pos > 0 ){
char c = lowercase_input_header.charAt(enc_pos-1);
if ( c != FF && c != ' ' ){
enc_pos = -1;
}
}
if ( enc_pos != -1 ){
String accept_encoding = lowercase_input_header.substring(enc_pos+16,e_pos);
int gzip_index = accept_encoding.indexOf("gzip");
if ( gzip_index != -1 ){
gzip_reply = true;
if ( accept_encoding.length() - gzip_index >= 8 ){
// gzip;q=0
// look to see if there's a q=0 (or 0.0) disabling gzip
char[] chars = accept_encoding.toCharArray();
boolean q_value = false;
for (int i=gzip_index+4;i<chars.length;i++){
char c = chars[i];
if ( c == ',' ){
break;
}else if ( c == '=' ){
q_value = true;
gzip_reply = false;
}else{
if ( q_value ){
if ( c != ' ' && c != '0' && c != '.' ){
gzip_reply = true;
break;
}
}
}
}
}
}
}
}
}
setTaskState( "decoding announce/scrape" );
int pos = 0;
byte[] hash = null;
List hash_list = null;
HashWrapper peer_id = null;
int tcp_port = 0;
String event = null;
long uploaded = 0;
long downloaded = 0;
long left = 0;
int num_want = -1;
boolean no_peer_id = false;
byte compact_mode = TRTrackerServerTorrentImpl.COMPACT_MODE_NONE;
String key = null;
byte crypto_level = TRTrackerServerPeer.CRYPTO_NONE;
int crypto_port = 0;
int udp_port = 0;
int http_port = 0;
int az_ver = 0;
boolean stop_to_queue = false;
String scrape_flags = null;
int up_speed = 0;
DHTNetworkPosition network_position = null;
String real_ip_address = client_address.getAddress().getHostAddress();
String client_ip_address = real_ip_address;
while(pos < str.length()){
int p1 = str.indexOf( '&', pos );
String token;
if ( p1 == -1 ){
token = str.substring( pos );
}else{
token = str.substring( pos, p1 );
pos = p1+1;
}
int p2 = token.indexOf('=');
if ( p2 == -1 ){
throw( new Exception( "format invalid" ));
}
String lhs = token.substring( 0, p2 ).toLowerCase();
String rhs = URLDecoder.decode(token.substring( p2+1 ), Constants.BYTE_ENCODING );
// System.out.println( "param:" + lhs + " = " + rhs );
if ( lhs.equals( "info_hash" )){
byte[] b = rhs.getBytes(Constants.BYTE_ENCODING);
if ( hash == null ){
hash = b;
}else{
if ( hash_list == null ){
hash_list = new ArrayList();
hash_list.add( hash );
}
hash_list.add( b );
}
}else if ( lhs.equals( "peer_id" )){
peer_id = new HashWrapper(rhs.getBytes(Constants.BYTE_ENCODING));
}else if ( lhs.equals( "no_peer_id" )){
no_peer_id = rhs.equals("1");
}else if ( lhs.equals( "compact" )){
if ( server.isCompactEnabled()){
if ( rhs.equals("1") && compact_mode == TRTrackerServerTorrentImpl.COMPACT_MODE_NONE ){
compact_mode = TRTrackerServerTorrentImpl.COMPACT_MODE_NORMAL;
}
}
}else if ( lhs.equals( "key" )){
if ( server.isKeyEnabled()){
key = rhs;
}
}else if ( lhs.equals( "port" )){
tcp_port = Integer.parseInt( rhs );
}else if ( lhs.equals( "event" )){
event = rhs;
}else if ( lhs.equals( "ip" )){
if ( AENetworkClassifier.categoriseAddress( rhs ) == AENetworkClassifier.AT_PUBLIC ){
// only accept public resolved addresses
for (int i=0;i<rhs.length();i++){
char c = rhs.charAt(i);
if ( c != '.' && !Character.isDigit( c )){
throw( new Exception( "IP override address must be resolved by the client" ));
}
}
}
client_ip_address = rhs;
}else if ( lhs.equals( "uploaded" )){
uploaded = Long.parseLong( rhs );
}else if ( lhs.equals( "downloaded" )){
downloaded = Long.parseLong( rhs );
}else if ( lhs.equals( "left" )){
left = Long.parseLong( rhs );
}else if ( lhs.equals( "numwant" )){
num_want = Integer.parseInt( rhs );
}else if ( lhs.equals( "azudp" )){
udp_port = Integer.parseInt( rhs );
// implicit compact mode for 2500 indicated by presence of udp port
compact_mode = TRTrackerServerTorrentImpl.COMPACT_MODE_AZ;
}else if ( lhs.equals( "azhttp" )){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -