// System.out.println( "Processor starts: " + socket.getRemoteSocketAddress());
boolean keep_alive = getServer().isKeepAliveEnabled();
try{
InputStream is = new BufferedInputStream( socket.getInputStream());
while( true ){
setTaskState( "entry" );
try{
if ( keep_alive ){
socket.setSoTimeout( KEEP_ALIVE_SOCKET_TIMEOUT );
setTimeoutsDisabled( true );
}else{
socket.setSoTimeout( SOCKET_TIMEOUT );
}
}catch ( Throwable e ){
// e.printStackTrace();
}
setTaskState( "reading header" );
try{
byte[] buffer = new byte[16*1024];
int header_pos = 0;
while( header_pos < buffer.length ){
int len = is.read( buffer, header_pos, 1);
if ( len != 1 ){
throw( new Exception( "Premature end of stream reading header" ));
}
header_pos++;
if ( header_pos >= 4 &&
buffer[header_pos-4] == CR &&
buffer[header_pos-3] == FF &&
buffer[header_pos-2] == CR &&
buffer[header_pos-1] == FF ){
break;
}
}
String header = new String( buffer, 0, header_pos, Constants.BYTE_ENCODING );
if ( Logger.isEnabled()){
String log_str = header;
int pos = log_str.indexOf( NL );
if ( pos != -1 ){
log_str = log_str.substring(0,pos);
}
Logger.log(new LogEvent(LOGID, "Tracker Server: received header '"
+ log_str + "' from " + socket.getRemoteSocketAddress()));
}
// System.out.println( "got header:" + header );
InputStream post_is = null;
File post_file = null;
String lowercase_header;
boolean head = false;
int url_start;
if ( header.startsWith( "GET " )){
timeout_ticks = 1;
lowercase_header = header.toLowerCase();
url_start = 4;
}else if ( header.startsWith( "HEAD " )){
timeout_ticks = 1;
lowercase_header = header.toLowerCase();
url_start = 5;
head = true;
}else if ( header.startsWith( "POST ")){
timeout_ticks = TRTrackerServerTCP.PROCESSING_POST_MULTIPLIER;
if ( timeout_ticks == 0 ){
setTimeoutsDisabled( true );
}
setTaskState( "reading content" );
lowercase_header = header.toLowerCase();
url_start = 5;
String cl_str = getHeaderField( header, lowercase_header, "content-length:" );
if ( cl_str == null ){
throw( new Exception( "Content-Length missing" ));
}
int content_length = Integer.parseInt( cl_str );
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();
post_file.deleteOnExit();
fos = new FileOutputStream( post_file );
data_os = fos;
}
while( content_length > 0 ){
int len = is.read( buffer, 0, Math.min( content_length, buffer.length ));
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{
int pos = header.indexOf(' ');
if ( pos == -1 ){
throw( new TRTrackerServerException( "header doesn't have space in right place" ));
}
timeout_ticks = 1;
lowercase_header = header.toLowerCase();
url_start = pos+1;
}
setTaskState( "processing request" );
current_request = header;
try{
if ( post_is == null ){
// set up a default input stream
post_is = new ByteArrayInputStream(new byte[0]);
}
int url_end = header.indexOf( " ", url_start );
if ( url_end == -1 ){
throw( new TRTrackerServerException( "header doesn't have space in right place" ));
}
String url = header.substring( url_start, url_end ).trim();
int nl_pos = header.indexOf( NL, url_end );
if ( nl_pos == -1 ){
throw( new TRTrackerServerException( "header doesn't have nl in right place" ));
}
String http_ver = header.substring( url_end, nl_pos ).trim();
String con_str = getHeaderField( header, lowercase_header, "connection:" );
if ( con_str == null ){
if ( http_ver.equalsIgnoreCase( "HTTP/1.0" )){
keep_alive = false;
}
}else if ( con_str.equalsIgnoreCase( "close" )){
keep_alive = false;
}
if ( head ){
ByteArrayOutputStream head_response = new ByteArrayOutputStream(4096);
if ( !processRequest(
header,
lowercase_header,
url,
(InetSocketAddress)socket.getLocalSocketAddress(),
(InetSocketAddress)socket.getRemoteSocketAddress(),
false,
keep_alive,
post_is,
head_response,
null )){
keep_alive = false;
}
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{
if( !processRequest(
header,
lowercase_header,
url,
(InetSocketAddress)socket.getLocalSocketAddress(),
(InetSocketAddress)socket.getRemoteSocketAddress(),
false,
keep_alive,
post_is,
socket.getOutputStream(),
null )){
keep_alive = false;
}
}
}finally{
if ( post_is != null ){
post_is.close();
}
if ( post_file != null ){
post_file.delete();