📄 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;
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";
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,
String client_ip_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{
if ( announce_and_scrape_only ){
throw( new Exception( "Tracker only supports announce and scrape functions" ));
}
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_ip_address, user, str, input_header, is, os )){
return;
}
os.write( ("HTTP/1.1 404 Not Found\r\n\r\n").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 port = 0;
String event = null;
long uploaded = 0;
long downloaded = 0;
long left = 0;
int num_want = -1;
boolean no_peer_id = false;
boolean compact = false;
String key = null;
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()){
compact = rhs.equals("1");
}
}else if ( lhs.equals( "key" )){
if ( server.isKeyEnabled()){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -