Package com.aelitis.azureus.core.networkmanager.impl.http

Source Code of com.aelitis.azureus.core.networkmanager.impl.http.HTTPNetworkConnectionWebSeed

/*
* Created on 4 Oct 2006
* Created by Paul Gardner
* Copyright (C) 2006 Aelitis, All Rights Reserved.
*
* 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, or (at your option) any later version.
* 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.
* 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.
*
* AELITIS, SAS au capital de 63.529,40 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/

package com.aelitis.azureus.core.networkmanager.impl.http;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.peer.impl.PEPeerControl;
import org.gudy.azureus2.core3.peer.impl.PEPeerTransport;
import org.gudy.azureus2.core3.util.Debug;

import com.aelitis.azureus.core.networkmanager.NetworkConnection;

public class
HTTPNetworkConnectionWebSeed
  extends HTTPNetworkConnection
{
  private boolean  switching;

  protected
  HTTPNetworkConnectionWebSeed(
    HTTPNetworkManager    _manager,
    NetworkConnection    _connection,
    PEPeerTransport      _peer )
  {
    super( _manager, _connection, _peer );
  }
 
  protected void
  decodeHeader(
    final HTTPMessageDecoder  decoder,
    final String        header )
 
    throws IOException
  {
    if ( switching ){
   
      Debug.out( "new header received while paused" );
     
      throw( new IOException( "Bork" ));
    }
   
    if ( !isSeed()){
     
      return;
    }
   
    PEPeerControl  control = getPeerControl();
   
    try{
      int  pos = header.indexOf( NL );
     
      String  line = header.substring(4,pos);
     
      pos = line.lastIndexOf( ' ' );
     
      String  url = line.substring( 0, pos ).trim();
     
      pos = url.indexOf( '?' );
     
      if ( pos != -1 ){
       
        url = url.substring( pos+1 );
      }
     
      StringTokenizer  tok = new StringTokenizer( url, "&" );
     
      int    piece   = -1;
      List  ranges   = new ArrayList();
     
      while( tok.hasMoreElements()){
       
        String  token = tok.nextToken();
       
        pos = token.indexOf('=');
       
        if ( pos != -1 ){
         
          String  lhs = token.substring(0,pos).toLowerCase( MessageText.LOCALE_ENGLISH );
          String  rhs = token.substring(pos+1);
         
          if ( lhs.equals( "info_hash" )){
           
              final byte[]  old_hash = control.getHash();
             
              final byte[]  new_hash = URLDecoder.decode( rhs, "ISO-8859-1" ).getBytes( "ISO-8859-1" );

            if ( !Arrays.equals( new_hash, old_hash )){
                             
              switching    = true;
             
              decoder.pauseInternally();
               
              flushRequests(
                new flushListener()
                {
                  private boolean triggered;
                 
                  public void
                  flushed()
                  {
                    synchronized( this ){
                     
                      if ( triggered ){
                       
                        return;
                      }
                     
                      triggered = true;
                    }
                   
                    getManager().reRoute(
                        HTTPNetworkConnectionWebSeed.this,
                        old_hash, new_hash, header );
                  }
                });
               
              return;
            }
          }else if ( lhs.equals( "piece" )){
           
            try{
              piece = Integer.parseInt( rhs );
             
            }catch( Throwable e ){
             
              throw( new IOException( "Invalid piece number '" + rhs +"'" ));
            }
          }else if ( lhs.equals( "ranges" )){
           
            StringTokenizer  range_tok = new StringTokenizer( rhs, "," );
           
            while( range_tok.hasMoreTokens()){
             
              String  range = range_tok.nextToken();
             
              int  sep = range.indexOf( '-' );
             
              if ( sep == -1 ){
               
                throw( new IOException( "Invalid range specification '" + rhs + "'" ));
              }
             
              try{
                ranges.add(
                    new int[]{
                      Integer.parseInt( range.substring(0,sep)),
                      Integer.parseInt( range.substring( sep+1 ))});
               
              }catch( Throwable e ){
               
                throw( new IOException( "Invalid range specification '" + rhs + "'" ));
              }
            }
          }
        }
      }
     
      if ( piece == -1 ){
       
        throw( new IOException( "Piece number not specified" ));
      }
     
      boolean  keep_alive = header.toLowerCase( MessageText.LOCALE_ENGLISH ).indexOf( "keep-alive" ) != -1;
     
      int  this_piece_size = control.getPieceLength( piece );
     
      if ( ranges.size() == 0 ){
       
        ranges.add( new int[]{ 0, this_piece_size-1});
      }
         
      long[]  offsets  = new long[ranges.size()];
      long[]  lengths  = new long[ranges.size()];
     
      long  piece_offset = piece * control.getPieceLength(0);
     
      for (int i=0;i<ranges.size();i++){
       
        int[]  range = (int[])ranges.get(i);
       
        int  start   = range[0];
        int end    = range[1];
       
        if (   start < 0 || start >= this_piece_size ||
            end < 0 || end >= this_piece_size ||
            start > end ){
         
          throw( new IOException( "Invalid range specification '" + start + "-" + end + "'" ));
        }
       
        offsets[i]   = piece_offset + start;
        lengths[i= ( end - start ) + 1;
      }
     
      addRequest( new httpRequest( offsets, lengths, 0, false, keep_alive ));
     
    }catch( Throwable e ){
     
      Debug.outNoStack( "Decode of '" + (header.length()>128?(header.substring(0,128) + "..."):header) + "' - " + Debug.getNestedExceptionMessageAndStack(e));
     
      if ( e instanceof IOException ){
       
        throw((IOException)e);
       
      }else{
       
        throw( new IOException( "Decode failed: " + Debug.getNestedExceptionMessage(e)));
      }
    }
  }
}
TOP

Related Classes of com.aelitis.azureus.core.networkmanager.impl.http.HTTPNetworkConnectionWebSeed

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.