⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trtrackerserverprocessortcp.java

📁 Azureus is a powerful, full-featured, cross-platform java BitTorrent client
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -