📄 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 sun.misc.BASE64Decoder;
import org.gudy.azureus2.core3.tracker.server.*;
import org.gudy.azureus2.core3.tracker.server.impl.*;
import org.gudy.azureus2.core3.logging.*;
import org.gudy.azureus2.core3.util.*;
public 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();
protected TRTrackerServerTCP server;
protected Socket socket;
protected int timeout_ticks = 1;
protected boolean disable_timeouts = false;
protected String current_request;
protected
TRTrackerServerProcessorTCP(
TRTrackerServerTCP _server,
Socket _socket )
{
server = _server;
socket = _socket;
}
public void
runSupport()
{
try{
setTaskState( "entry" );
try{
socket.setSoTimeout( SOCKET_TIMEOUT );
}catch ( SocketException e ){
// e.printStackTrace();
}
String header_plus = "";
setTaskState( "reading header" );
try{
InputStream is = socket.getInputStream();
byte[] buffer = new byte[1024];
while( header_plus.length()< 4096 ){
int len = is.read(buffer);
if ( len == -1 ){
break;
}
header_plus += new String( buffer, 0, len, Constants.BYTE_ENCODING );
if ( header_plus.endsWith(NL+NL) ||
header_plus.indexOf( NL+NL ) != -1 ){
break;
}
}
if ( LGLogger.isLoggingOn()){
String log_str = header_plus;
int pos = log_str.indexOf( NL );
if ( pos != -1 ){
log_str = log_str.substring(0,pos);
}
LGLogger.log(0, 0, LGLogger.INFORMATION, "Tracker Server: received header '" + log_str + "'" );
}
// System.out.println( "got header:" + header_plus );
InputStream post_is = null;
File post_file = null;
String actual_header;
String lowercase_header;
boolean head = false;
if ( header_plus.startsWith( "GET " )){
timeout_ticks = 1;
actual_header = header_plus;
lowercase_header = actual_header.toLowerCase();
}else if ( header_plus.startsWith( "HEAD " )){
timeout_ticks = 1;
actual_header = header_plus;
lowercase_header = actual_header.toLowerCase();
head = true;
}else if ( header_plus.startsWith( "POST ")){
timeout_ticks = TRTrackerServerTCP.PROCESSING_POST_MULTIPLIER;
if ( timeout_ticks == 0 ){
disable_timeouts = true;
}
setTaskState( "reading content" );
int header_end = header_plus.indexOf(NL+NL);
if ( header_end == -1 ){
throw( new TRTrackerServerException( "header truncated" ));
}
actual_header = header_plus.substring(0,header_end+4);
lowercase_header = actual_header.toLowerCase();
int cl_start = lowercase_header.indexOf("content-length:");
if ( cl_start == -1 ){
throw( new TRTrackerServerException( "header Content-Length start missing" ));
}
int cl_end = actual_header.indexOf( NL, cl_start );
if ( cl_end == -1 ){
throw( new TRTrackerServerException( "header Content-Length end missing" ));
}
int content_length = Integer.parseInt( actual_header.substring(cl_start+15,cl_end ).trim());
ByteArrayOutputStream baos = null;
FileOutputStream fos = null;
OutputStream data_os;
if ( content_length <= 256*1024 ){
baos = new ByteArrayOutputStream();
data_os = baos;
}else{
post_file = AETemporaryFileHandler.createTempFile( "AZU", null );
post_file.deleteOnExit();
fos = new FileOutputStream( post_file );
data_os = fos;
}
// if we have X<NL><NL>Y get Y
int rem = header_plus.length() - (header_end+4);
if ( rem > 0 ){
content_length -= rem;
data_os.write( header_plus.substring(header_plus.length()-rem).getBytes( Constants.BYTE_ENCODING ));
}
while( content_length > 0 ){
int len = is.read( buffer );
if ( len < 0 ){
throw( new TRTrackerServerException( "premature end of input stream" ));
}
data_os.write( buffer, 0, len );
content_length -= len;
}
if ( baos != null ){
post_is = new ByteArrayInputStream(baos.toByteArray());
}else{
fos.close();
post_is = new BufferedInputStream( new FileInputStream( post_file ), 256*1024 );
}
// System.out.println( "TRTrackerServerProcessorTCP: request data = " + baos.size());
}else{
throw( new TRTrackerServerException( "header doesn't start with GET or POST ('" + (header_plus.length()>256?header_plus.substring(0,256):header_plus)+"')" ));
}
setTaskState( "processing request" );
current_request = actual_header;
try{
if ( post_is == null ){
// set up a default input stream
post_is = new ByteArrayInputStream(new byte[0]);
}
String url = actual_header.substring(4).trim();
int pos = url.indexOf( " " );
if ( pos == -1 ){
throw( new TRTrackerServerException( "header doesn't have space in right place" ));
}
url = url.substring(0,pos);
if ( head ){
ByteArrayOutputStream head_response = new ByteArrayOutputStream(4096);
processRequest( actual_header,
lowercase_header,
url,
socket.getInetAddress().getHostAddress(),
post_is,
head_response );
byte[] head_data = head_response.toByteArray();
int header_length = head_data.length;
for (int i=3;i<head_data.length;i++){
if ( head_data[i-3] == CR &&
head_data[i-2] == FF &&
head_data[i-1] == CR &&
head_data[i] == FF ){
header_length = i+1;
break;
}
}
setTaskState( "writing head response" );
socket.getOutputStream().write( head_data, 0, header_length );
socket.getOutputStream().flush();
}else{
processRequest( actual_header,
lowercase_header,
url,
socket.getInetAddress().getHostAddress(),
post_is,
socket.getOutputStream() );
}
}finally{
if ( post_is != null ){
post_is.close();
}
if ( post_file != null ){
post_file.delete();
}
}
}catch( SocketTimeoutException e ){
// System.out.println( "TRTrackerServerProcessor: timeout reading header, got '" + header + "'");
// ignore it
}catch( Throwable e ){
// e.printStackTrace();
}
}finally{
setTaskState( "final socket close" );
try{
socket.close();
}catch( Throwable e ){
// e.printStackTrace();
}
}
}
public void
interruptTask()
{
try{
if ( disable_timeouts ){
// Debug.out( "External tracker request timeout ignored: state = " + getTaskState() + ", req = " + current_request );
}else{
timeout_ticks--;
if ( timeout_ticks <= 0 ){
Debug.out( "Tracker task interrupted in state '" + getTaskState() + "' : processing time limit exceeded" );
socket.close();
}
}
}catch( Throwable e ){
// e.printStackTrace();
}
}
protected void
processRequest(
String input_header,
String lowercase_input_header,
String url_path,
String client_ip_address,
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{
setTaskState( "external request" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -