Package org.gudy.azureus2.ui.webplugin

Source Code of org.gudy.azureus2.ui.webplugin.WebPlugin

/*
* File    : WebPlugin.java
* Created : 23-Jan-2004
* 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.ui.webplugin;

/**
* @author parg
*
*/

import java.io.*;
import java.util.*;
import java.net.*;

import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.plugins.*;
import org.gudy.azureus2.plugins.logging.*;
import org.gudy.azureus2.plugins.ipfilter.*;
import org.gudy.azureus2.plugins.tracker.*;
import org.gudy.azureus2.plugins.tracker.web.*;
import org.gudy.azureus2.plugins.ui.*;
import org.gudy.azureus2.plugins.ui.config.*;
import org.gudy.azureus2.plugins.ui.model.*;

import com.aelitis.azureus.core.pairing.PairedService;
import com.aelitis.azureus.core.pairing.PairingConnectionData;
import com.aelitis.azureus.core.pairing.PairingManager;
import com.aelitis.azureus.core.pairing.PairingManagerFactory;
import com.aelitis.azureus.core.pairing.PairingManagerListener;
import com.aelitis.azureus.core.pairing.PairingTest;
import com.aelitis.azureus.core.pairing.PairingTestListener;
import com.aelitis.azureus.plugins.upnp.UPnPMapping;
import com.aelitis.azureus.plugins.upnp.UPnPPlugin;

public class
WebPlugin
  implements Plugin, TrackerWebPageGenerator
{
  public static final String  PR_ENABLE          = "Enable";            // Boolean
  public static final String  PR_DISABLABLE        = "Disablable";          // Boolean
  public static final String  PR_PORT            = "Port";            // Integer
  public static final String  PR_BIND_IP          = "Bind IP";          // String
  public static final String  PR_ROOT_RESOURCE      = "Root Resource";        // String
  public static final String  PR_ROOT_DIR          = "Root Dir";          // String
  public static final String  PR_ACCESS          = "Access";            // String
  public static final String  PR_LOG            = "DefaultLoggerChannel";    // LoggerChannel
  public static final String  PR_CONFIG_MODEL_PARAMS    = "DefaultConfigModelParams"// String[] params to use when creating config model
  public static final String  PR_CONFIG_MODEL        = "DefaultConfigModel";      // BasicPluginConfigModel
  public static final String  PR_VIEW_MODEL        = "DefaultViewModel";      // BasicPluginViewModel
  public static final String  PR_HIDE_RESOURCE_CONFIG    = "DefaultHideResourceConfig"// Boolean
  public static final String  PR_ENABLE_KEEP_ALIVE    = "DefaultEnableKeepAlive";    // Boolean
  public static final String  PR_PAIRING_SID        = "PairingSID";          // String
 
  public static final String  PROPERTIES_MIGRATED    = "Properties Migrated";
  public static final String  CONFIG_MIGRATED      = "Config Migrated";
  public static final String  PAIRING_MIGRATED    = "Pairing Migrated";
  public static final String  PAIRING_SESSION_KEY    = "Pairing Session Key";

  public static final String  CONFIG_PASSWORD_ENABLE      = "Password Enable";
  public static final boolean  CONFIG_PASSWORD_ENABLE_DEFAULT  = false;
 
  public static final String  CONFIG_PAIRING_ENABLE      = "Pairing Enable";
  public static final boolean  CONFIG_PAIRING_ENABLE_DEFAULT  = true;

  public static final String  CONFIG_PORT_OVERRIDE      = "Port Override";
 
  public static final String  CONFIG_PAIRING_AUTO_AUTH      = "Pairing Auto Auth";
  public static final boolean  CONFIG_PAIRING_AUTO_AUTH_DEFAULT  = true;

 
  public static final String  CONFIG_ENABLE          = PR_ENABLE;
  public        boolean  CONFIG_ENABLE_DEFAULT      = true;
 
  public static final String  CONFIG_USER            = "User";
  public static final String  CONFIG_USER_DEFAULT        = "";
 
  public static final String  CONFIG_PASSWORD          = "Password";
  public static final byte[]  CONFIG_PASSWORD_DEFAULT      = {};
 
  public static final String   CONFIG_PORT            = PR_PORT;
  public int           CONFIG_PORT_DEFAULT        = 8089;
 
  public static final String   CONFIG_BIND_IP          = PR_BIND_IP;
  public String         CONFIG_BIND_IP_DEFAULT      = "";

  public static final String   CONFIG_PROTOCOL          = "Protocol";
  public static final String   CONFIG_PROTOCOL_DEFAULT      = "HTTP";

  public static final String  CONFIG_UPNP_ENABLE        = "UPnP Enable";
  public static final boolean  CONFIG_UPNP_ENABLE_DEFAULT    = true;

  public static final String   CONFIG_HOME_PAGE        = "Home Page";
  public static final String   CONFIG_HOME_PAGE_DEFAULT    = "index.html";
 
  public static final String   CONFIG_ROOT_DIR          = PR_ROOT_DIR;
  public            String   CONFIG_ROOT_DIR_DEFAULT      = "";
 
  public static final String   CONFIG_ROOT_RESOURCE      = PR_ROOT_RESOURCE;
  public              String   CONFIG_ROOT_RESOURCE_DEFAULT  = "";
 
  public static final String   CONFIG_MODE            = "Mode";
  public static final String   CONFIG_MODE_FULL        = "full";
  public static final String   CONFIG_MODE_DEFAULT        = CONFIG_MODE_FULL;
 
  public static final String   CONFIG_ACCESS          = PR_ACCESS;
  public            String   CONFIG_ACCESS_DEFAULT      = "all";
 
  protected static final String  NL      = "\r\n";
 
  protected static final String[]    welcome_pages = {"index.html", "index.htm", "index.php", "index.tmpl" };
  protected static File[]        welcome_files;
 
  protected PluginInterface      plugin_interface;  // unfortunately this is accessed by webui - fix sometime
 
  private LoggerChannel      log;
  private PluginConfig      plugin_config;
  private BasicPluginViewModel   view_model;
  private BasicPluginConfigModel  config_model;
 
  private StringParameter      param_home;
  private StringParameter      param_rootdir;
  private StringParameter      param_rootres;

  private IntParameter      param_port;
  private StringListParameter    param_protocol;
  private StringParameter      param_bind;
 
  private StringParameter      param_access;
 
  private BooleanParameter    p_upnp_enable;
 
  private BooleanParameter    pw_enable;
  private StringParameter      p_user_name;
  private PasswordParameter    p_password;
 
  private BooleanParameter    param_auto_auth;
  private IntParameter      param_port_or;
  private boolean          setting_auto_auth;
  private String          pairing_access_code;
  private String          pairing_session_code;
 
  private boolean        plugin_enabled;
 
  private String        home_page;
  private String        file_root;
  private String        resource_root;
 
  private String        root_dir;
 
  private boolean        ip_range_all  = false;
  private List<IPRange>    ip_ranges;
 
  private TrackerWebContext      tracker_context;
  private UPnPMapping          upnp_mapping;
  private PairingManagerListener    pairing_listener;
 
  private Properties  properties;
 
  private static ThreadLocal<String>    tls  =
    new ThreadLocal<String>()
    {
      public String
      initialValue()
      {
        return( null );
      }
    };
 
  private static final int  LOGOUT_GRACE_MILLIS  = 5*1000;
  private static final String  GRACE_PERIOD_MARKER  = "<grace_period>";
 
  private Map<String,Long>  logout_timer     = new HashMap<String, Long>();
 
  public
  WebPlugin()
  {
    properties  = new Properties();
  }
 
  public
  WebPlugin(
    Properties    defaults )
  { 
    properties  = defaults;
  }
 
  public void
  initialize(
    PluginInterface _plugin_interface )
 
    throws PluginException
 
    plugin_interface  = _plugin_interface;
   
    plugin_config = plugin_interface.getPluginconfig();

    Properties plugin_properties = plugin_interface.getPluginProperties();
   
    if ( plugin_properties != null ){
     
      Object o = plugin_properties.get( "plugin." + PR_ROOT_DIR.replaceAll( " ", "_" ));
     
      if ( o instanceof String ){
       
        properties.put( PR_ROOT_DIR, o );
      }
    }
   
    Boolean  pr_enable = (Boolean)properties.get(PR_ENABLE);
   
    if ( pr_enable != null ){
   
      CONFIG_ENABLE_DEFAULT  = pr_enable.booleanValue();
    }
   
    Integer  pr_port = (Integer)properties.get(PR_PORT);
   
    if ( pr_port != null ){
   
      CONFIG_PORT_DEFAULT  = pr_port.intValue();
    }
   
    String  pr_bind_ip = (String)properties.get(PR_BIND_IP);
   
    if ( pr_bind_ip != null ){
   
      CONFIG_BIND_IP_DEFAULT  = pr_bind_ip.trim();
    }
   
    String  pr_root_resource = (String)properties.get( PR_ROOT_RESOURCE );
   
    if( pr_root_resource != null ){
     
      CONFIG_ROOT_RESOURCE_DEFAULT  = pr_root_resource;
    }
   
    String  pr_root_dir = (String)properties.get( PR_ROOT_DIR );
   
    if( pr_root_dir != null ){
     
      CONFIG_ROOT_DIR_DEFAULT  = pr_root_dir;
    }
   
    String  pr_access = (String)properties.get( PR_ACCESS );
   
    if( pr_access != null ){
     
      CONFIG_ACCESS_DEFAULT  = pr_access;
    }
   
    Boolean  pr_hide_resource_config = (Boolean)properties.get( PR_HIDE_RESOURCE_CONFIG );
   
    log = (LoggerChannel)properties.get( PR_LOG );
   
    if ( log == null ){
     
      log = plugin_interface.getLogger().getChannel("WebPlugin");
    }
   
    UIManager  ui_manager = plugin_interface.getUIManager();
   
    view_model = (BasicPluginViewModel)properties.get( PR_VIEW_MODEL );

    if ( view_model == null ){
     
      view_model = ui_manager.createBasicPluginViewModel( plugin_interface.getPluginName());
    }
   
    String sConfigSectionID = "plugins." + plugin_interface.getPluginID();
   
    view_model.setConfigSectionID(sConfigSectionID);
    view_model.getStatus().setText( "Running" );
    view_model.getActivity().setVisible( false );
    view_model.getProgress().setVisible( false );
   
    log.addListener(
      new LoggerChannelListener()
      {
        public void
        messageLogged(
          int    type,
          String  message )
        {
          view_model.getLogArea().appendText( message+"\n");
        }
       
        public void
        messageLogged(
          String    str,
          Throwable  error )
        {
          view_model.getLogArea().appendText( str + "\n" );
          view_model.getLogArea().appendText( error.toString() + "\n" );
        }
      });
   
   
    config_model = (BasicPluginConfigModel)properties.get( PR_CONFIG_MODEL );
   
    if ( config_model == null ){
     
      String[] cm_params = (String[])properties.get( PR_CONFIG_MODEL_PARAMS );
 
      if ( cm_params == null || cm_params.length == 0 ){
       
        config_model = ui_manager.createBasicPluginConfigModel(ConfigSection.SECTION_PLUGINS, sConfigSectionID);
       
      }else if ( cm_params.length == 1 ){
       
        config_model = ui_manager.createBasicPluginConfigModel( cm_params[0] );
 
      }else{
       
        config_model = ui_manager.createBasicPluginConfigModel( cm_params[0], cm_params[1] );
      }
    }
   
    boolean  save_needed = false;
   
    if ( !plugin_config.getPluginBooleanParameter( CONFIG_MIGRATED, false )){
     
      plugin_config.setPluginParameter( CONFIG_MIGRATED, true );
     
      save_needed  = true;
     
      plugin_config.setPluginParameter(
          CONFIG_PASSWORD_ENABLE,
          plugin_config.getBooleanParameter(
              "Tracker Password Enable Web", CONFIG_PASSWORD_ENABLE_DEFAULT ));
     
      plugin_config.setPluginParameter(
          CONFIG_USER,
          plugin_config.getStringParameter(
              "Tracker Username", CONFIG_USER_DEFAULT ));
     
      plugin_config.setPluginParameter(
          CONFIG_PASSWORD,
          plugin_config.getByteParameter(
              "Tracker Password", CONFIG_PASSWORD_DEFAULT ));
         
    }
   
    if ( !plugin_config.getPluginBooleanParameter( PROPERTIES_MIGRATED, false )){
     
      plugin_config.setPluginParameter( PROPERTIES_MIGRATED, true );
           
      Properties  props = plugin_interface.getPluginProperties();
     
        // make sure we've got an old properties file too
     
      if ( props.getProperty( "port", "" ).length() > 0 ){
       
        save_needed = true;
       
        String  prop_port    = props.getProperty( "port",      ""+CONFIG_PORT_DEFAULT );
        String  prop_protocol  = props.getProperty( "protocol",     CONFIG_PROTOCOL_DEFAULT );
        String  prop_home    = props.getProperty( "homepage",     CONFIG_HOME_PAGE_DEFAULT );
        String  prop_rootdir  = props.getProperty( "rootdir",     CONFIG_ROOT_DIR_DEFAULT );
        String  prop_rootres  = props.getProperty( "rootresource",   CONFIG_ROOT_RESOURCE_DEFAULT );
        String  prop_mode    = props.getProperty( "mode",       CONFIG_MODE_DEFAULT );
        String  prop_access    = props.getProperty( "access",       CONFIG_ACCESS_DEFAULT );
 
        int  prop_port_int = CONFIG_PORT_DEFAULT;
       
        try{
          prop_port_int  = Integer.parseInt( prop_port );
         
        }catch( Throwable e ){
        }
   
        plugin_config.setPluginParameter(CONFIG_PORT, prop_port_int );
        plugin_config.setPluginParameter(CONFIG_PROTOCOL, prop_protocol );
        plugin_config.setPluginParameter(CONFIG_HOME_PAGE, prop_home );
        plugin_config.setPluginParameter(CONFIG_ROOT_DIR, prop_rootdir );
        plugin_config.setPluginParameter(CONFIG_ROOT_RESOURCE, prop_rootres );
        plugin_config.setPluginParameter(CONFIG_MODE, prop_mode );
        plugin_config.setPluginParameter(CONFIG_ACCESS, prop_access );
               
        File  props_file = new File( plugin_interface.getPluginDirectoryName(), "plugin.properties" );
       
        PrintWriter pw = null;
       
        try{
          File  backup = new File( plugin_interface.getPluginDirectoryName(), "plugin.properties.bak" );
         
          props_file.renameTo( backup );
         
          pw = new PrintWriter( new FileWriter( props_file ));
 
          pw.println( "plugin.class=" + props.getProperty( "plugin.class" ));
          pw.println( "plugin.name=" + props.getProperty( "plugin.name" ));
          pw.println( "plugin.version=" + props.getProperty( "plugin.version" ));
          pw.println( "plugin.id=" + props.getProperty( "plugin.id" ));
          pw.println( "" );
          pw.println( "# configuration has been migrated to plugin config - see view->config->plugins" );
          pw.println( "# in the SWT user interface" );
         
          log.logAlert(   LoggerChannel.LT_INFORMATION,
              plugin_interface.getPluginName() + " - plugin.properties settings migrated to plugin configuration." );
     
        }catch( Throwable  e ){
         
          Debug.printStackTrace( e );
         
          log.logAlert(   LoggerChannel.LT_ERROR,
                  plugin_interface.getPluginName() + " - plugin.properties settings migration failed." );
         
        }finally{
         
          if ( pw != null ){
           
            pw.close();
          }
        } 
      }
    }
   
    if ( save_needed ){
     
      plugin_config.save();
    }
   
    Boolean  disablable = (Boolean)properties.get( PR_DISABLABLE );
       
    final BooleanParameter  param_enable;
   
    if ( disablable != null && disablable ){
     
      param_enable =
        config_model.addBooleanParameter2( CONFIG_ENABLE, "webui.enable", CONFIG_ENABLE_DEFAULT );
     
      plugin_enabled = param_enable.getValue();
     
    }else{
      param_enable   = null;
     
      plugin_enabled   = true;
    }
   
    initStage(1);
   
      // connection group
   
    param_port = config_model.addIntParameter2(    CONFIG_PORT, "webui.port", CONFIG_PORT_DEFAULT );
   
    param_bind = config_model.addStringParameter2CONFIG_BIND_IP, "webui.bindip", CONFIG_BIND_IP_DEFAULT );
   
    param_protocol =
      config_model.addStringListParameter2(
          CONFIG_PROTOCOL, "webui.protocol", new String[]{ "http", "https" }, CONFIG_PROTOCOL_DEFAULT );
   
    ParameterListener update_server_listener =
      new ParameterListener()
      {
        public void
        parameterChanged(
          Parameter param )
        {
          setupServer();
        }
      };
   
    param_port.addListener( update_server_listener );
    param_bind.addListener( update_server_listener );
    param_protocol.addListener( update_server_listener );   
   
    p_upnp_enable =
      config_model.addBooleanParameter2(
              CONFIG_UPNP_ENABLE,
              "webui.upnpenable",
              CONFIG_UPNP_ENABLE_DEFAULT );

    p_upnp_enable.addListener(
      new ParameterListener()
      {
        public void
        parameterChanged(
          Parameter param )
        {
          setupUPnP();
        }
      })
   
    plugin_interface.addListener(
        new PluginListener()
        {
          public void
          initializationComplete()
          {
            setupUPnP();
          }
         
          public void
          closedownInitiated()
          {
          }
         
          public void
          closedownComplete()
          { 
          }
        });
   
   
    final String p_sid = (String)properties.get( PR_PAIRING_SID );
   
    final LabelParameter    pairing_info;
    final BooleanParameter    pairing_enable;
    final HyperlinkParameter  pairing_test;
    final HyperlinkParameter  connection_test;
   
    if ( p_sid != null ){
     
      final PairingManager pm = PairingManagerFactory.getSingleton();

      pairing_info = config_model.addLabelParameter2( "webui.pairing.info." + (pm.isEnabled()?"y":"n"));
       
      pairing_enable = config_model.addBooleanParameter2( CONFIG_PAIRING_ENABLE, "webui.pairingenable", CONFIG_PAIRING_ENABLE_DEFAULT );
     
      if ( !plugin_config.getPluginBooleanParameter( PAIRING_MIGRATED, false )){
     
          // if they already have a password, don't override it by setting auto-auth
       
        boolean  has_pw_enabled = plugin_config.getPluginBooleanParameter( CONFIG_PASSWORD_ENABLE, CONFIG_PASSWORD_ENABLE_DEFAULT );
       
        if ( has_pw_enabled ){
         
          plugin_config.setPluginParameter( CONFIG_PAIRING_AUTO_AUTH, false );
        }
       
        plugin_config.setPluginParameter( PAIRING_MIGRATED, true );
      }
     
      param_port_or  =  config_model.addIntParameter2( CONFIG_PORT_OVERRIDE, "webui.port.override", 0 );

      param_auto_auth = config_model.addBooleanParameter2( CONFIG_PAIRING_AUTO_AUTH, "webui.pairing.autoauth", CONFIG_PAIRING_AUTO_AUTH_DEFAULT );
     
      param_auto_auth.addListener(
        new ParameterListener()
        {
          public void
          parameterChanged(
            Parameter param )
          {
            if ( pairing_enable.getValue() && pm.isEnabled()){
         
              setupAutoAuth();
            }
          }
        });
           
      connection_test = config_model.addHyperlinkParameter2( "webui.connectiontest", getConnectionTestURL( p_sid ));

      pairing_test = config_model.addHyperlinkParameter2( "webui.pairingtest", "http://remote.vuze.com/?sid=" + p_sid );

        // listeners setup later as they depend on userame params etc
     
    }else{
      pairing_info  = null;
      pairing_enable   = null;
      param_auto_auth  = null;
      param_port_or  = null;
      pairing_test  = null;
      connection_test  = null;
    }
     
    config_model.createGroup(
        "ConfigView.section.Pairing",
        new Parameter[]{
          pairing_info, pairing_enable, param_port_or, param_auto_auth, connection_test, pairing_test,
        });
   
    config_model.createGroup(
      "ConfigView.section.server",
      new Parameter[]{
        param_port, param_bind, param_protocol, p_upnp_enable,
      });
   
    param_home     = config_model.addStringParameter2CONFIG_HOME_PAGE, "webui.homepage", CONFIG_HOME_PAGE_DEFAULT );
    param_rootdir   = config_model.addStringParameter2CONFIG_ROOT_DIR, "webui.rootdir", CONFIG_ROOT_DIR_DEFAULT );
    param_rootres  = config_model.addStringParameter2CONFIG_ROOT_RESOURCE, "webui.rootres", CONFIG_ROOT_RESOURCE_DEFAULT );
   
    if ( pr_hide_resource_config != null && pr_hide_resource_config.booleanValue()){
     
      param_home.setVisible( false );
      param_rootdir.setVisible( false );
      param_rootres.setVisible( false );
     
    }else{
     
      ParameterListener update_resources_listener =
        new ParameterListener()
        {
          public void
          parameterChanged(
            Parameter param )
          {
            setupResources();
          }
        };
       
      param_home.addListener( update_resources_listener );
      param_rootdir.addListener( update_resources_listener );
      param_rootres.addListener( update_resources_listener );
    }
   
      // access group
   
    LabelParameter a_label1 = config_model.addLabelParameter2( "webui.mode.info" );
    StringListParameter param_mode =
      config_model.addStringListParameter2
          CONFIG_MODE, "webui.mode", new String[]{ "full", "view" }, CONFIG_MODE_DEFAULT );
   
   
    LabelParameter a_label2 = config_model.addLabelParameter2( "webui.access.info" );
   
    param_access  = config_model.addStringParameter2CONFIG_ACCESS, "webui.access", CONFIG_ACCESS_DEFAULT );
   
    param_access.addListener(
      new ParameterListener()
      {
        public void
        parameterChanged(
          Parameter param )
        {
          setupAccess();
        }   
      });
   
    pw_enable =
      config_model.addBooleanParameter2(
              CONFIG_PASSWORD_ENABLE,
              "webui.passwordenable",
              CONFIG_PASSWORD_ENABLE_DEFAULT );
   
    p_user_name =
      config_model.addStringParameter2(
              CONFIG_USER,
              "webui.user",
              CONFIG_USER_DEFAULT );
   
    p_password =
      config_model.addPasswordParameter2(
              CONFIG_PASSWORD,
              "webui.password",
              PasswordParameter.ET_SHA1,
              CONFIG_PASSWORD_DEFAULT );
   
    pw_enable.addEnabledOnSelection( p_user_name );
    pw_enable.addEnabledOnSelection( p_password );
   
    ParameterListener auth_change_listener =
      new ParameterListener()
      {
        public void
        parameterChanged(
          Parameter param )
        {
          if ( param_auto_auth != null ){
           
            if ( !setting_auto_auth ){
             
              log( "Disabling pairing auto-authentication as overridden by user" );
             
              param_auto_auth.setValue( false );
            }
          }
        }
      };

    p_user_name.addListener( auth_change_listener );
    p_password.addListener( auth_change_listener );
    pw_enable.addListener( auth_change_listener );
     
    config_model.createGroup(
      "webui.group.access",
      new Parameter[]{
        a_label1, param_mode, a_label2, param_access,
        pw_enable, p_user_name, p_password,
      });
         
    if ( p_sid != null ){
     
      final PairingManager pm = PairingManagerFactory.getSingleton();

      pairing_enable.addListener(
          new ParameterListener()
          {
            public void
            parameterChanged(
              Parameter param )
            {
              boolean enabled = pairing_enable.getValue();
             
              param_auto_auth.setEnabled( pm.isEnabled() && enabled );
              param_port_or.setEnabled( pm.isEnabled() && enabled );
             
              boolean test_ok = pm.isEnabled() && pairing_enable.getValue() && pm.peekAccessCode() != null && !pm.hasActionOutstanding();

              pairing_test.setEnabled( test_ok );
              connection_test.setEnabled( test_ok );

              setupPairing( p_sid, enabled );
            }
          });
             
      pairing_listener =
        new PairingManagerListener()
        {
          public void
          somethingChanged(
            PairingManager pm )
          {
            pairing_info.setLabelKey( "webui.pairing.info." + (pm.isEnabled()?"y":"n"));
 
            if ( plugin_enabled ){
             
              pairing_enable.setEnabled( pm.isEnabled());
               
              param_auto_auth.setEnabled( pm.isEnabled() && pairing_enable.getValue() );
              param_port_or.setEnabled( pm.isEnabled() && pairing_enable.getValue() );
             
              boolean test_ok = pm.isEnabled() && pairing_enable.getValue() && pm.peekAccessCode() != null && !pm.hasActionOutstanding();
             
              pairing_test.setEnabled( test_ok );
              connection_test.setEnabled( test_ok );
            }
           
            connection_test.setHyperlink( getConnectionTestURL( p_sid ));
                         
            setupPairing( p_sid, pairing_enable.getValue());
          }
        };
       
      pairing_listener.somethingChanged( pm );
     
      pm.addListener( pairing_listener );

      setupPairing( p_sid, pairing_enable.getValue());
     
      ParameterListener update_pairing_listener =
        new ParameterListener()
        {
          public void
          parameterChanged(
            Parameter param )
          {
            updatePairing( p_sid );
           
            setupUPnP();
          }
        };
       
      param_port.addListener( update_pairing_listener );
     
      param_port_or.addListener( update_pairing_listener );
     
      param_protocol.addListener( update_pairing_listener );
     
      /*
      config_model.addActionParameter2( "test", "test" ).addListener(
        new ParameterListener()
        {
          public void
          parameterChanged(
            Parameter param )
          {
            try{
              pm.testService(
                p_sid,
                new PairingTestListener()
                {
                  public void
                  testStarted(
                    PairingTest test )
                  {
                    System.out.println( "Test starts" );
                  }
                 
                  public void
                  testComplete(
                    PairingTest test)
                  {
                    System.out.println( "Test complete: " + test.getOutcome() + "/" + test.getErrorMessage());
                  }
                });
            }catch( Throwable e ){
             
              Debug.out( e );
            }
          }
        });
      */
    }
   
    if ( param_enable != null ){
           
      final List<Parameter> changed_params = new ArrayList<Parameter>();
     
      if ( !plugin_enabled){
       
        Parameter[] params = config_model.getParameters();

        for ( Parameter param: params ){
         
          if ( param == param_enable ){
           
            continue;
          }
         
          if ( param.isEnabled()){
           
            changed_params.add( param );
         
            param.setEnabled( false );
          }
        }
      }
     
      param_enable.addListener(
        new ParameterListener()
        {
          public void
          parameterChanged(
            Parameter e_p )
          {
              // this doesn't quite work as tne enabler/disabler parameter logic is implemented
              // badly and only toggles the UI component, not the enabled state of the
              // underlying parameter. grr. better than nothing though
           
            plugin_enabled = ((BooleanParameter)e_p).getValue();
           
            if ( plugin_enabled ){
           
              for ( Parameter p: changed_params ){
               
                p.setEnabled( true );
              }
            }else{
             
              changed_params.clear();
             
              Parameter[] params = config_model.getParameters();
             
              for ( Parameter param: params ){
               
                if ( param == e_p ){
                 
                  continue;
                }
               
                if ( param.isEnabled()){
                 
                  changed_params.add( param );
               
                  param.setEnabled( false );
                }
              }
            }
           
            setupServer();
           
            setupUPnP();
           
            if ( p_sid != null ){
           
              setupPairing( p_sid, pairing_enable.getValue());
            }
          }
        });
    }
   
      // end config
       
    setupResources();
     
    setupAccess();
                       
    setupServer();
  }
 
  protected void
  initStage(
    int  num )
  { 
  }
 
  private String
  getConnectionTestURL(
    String    sid )
  {
    String res = "http://pair.vuze.com/pairing/web/test?sid=" + sid;
   
    PairingManager pm = PairingManagerFactory.getSingleton();
   
    if ( pm.isEnabled()){
     
      String ac = pm.peekAccessCode();
     
      if ( ac != null ){
       
        res += "&ac=" + ac;
      }
    }
   
    return( res );
  }
 
  protected boolean
  isPluginEnabled()
  {
    return( plugin_enabled );
  }
 
  protected void
  unloadPlugin()
  {
    if ( view_model != null ){
   
      view_model.destroy();
   
      view_model = null;
    }
   
    if ( config_model != null ){
     
      config_model.destroy();
     
      config_model = null;
    }
 
    if ( tracker_context != null ){
     
      tracker_context.destroy();
     
      tracker_context = null;
    }
   
    if ( upnp_mapping != null ){
     
      upnp_mapping.destroy();
     
      upnp_mapping = null;
    }
   
    if ( pairing_listener != null ){
   
      PairingManager pm = PairingManagerFactory.getSingleton();
     
      pm.removeListener( pairing_listener );
     
      pairing_listener = null;
    }
  }
 
  private void
  setupResources()
  {
    home_page = param_home.getValue().trim();
   
    if ( home_page.length() == 0 ){
       
      home_page = null;
       
    }else if (!home_page.startsWith("/" )){
     
      home_page = "/" + home_page;
    }
   
    resource_root = param_rootres.getValue().trim();
       
    if ( resource_root.length() == 0 ){
       
      resource_root = null;
       
    }else if ( resource_root.startsWith("/" )){
     
      resource_root = resource_root.substring(1);
    }
   
    root_dir  = param_rootdir.getValue().trim();
   
    if ( root_dir.length() == 0 ){
     
      file_root = plugin_interface.getPluginDirectoryName();
     
      if ( file_root == null ){
       
        file_root = SystemProperties.getUserPath() + "web";
      }
    }else{
     
        // absolute or relative
     
      if ( root_dir.startsWith(File.separator) || root_dir.indexOf(":") != -1 ){
       
        file_root = root_dir;
       
      }else{
       
        if ( File.separatorChar != '/' && root_dir.contains( "/" )){
         
          root_dir = root_dir.replace( '/', File.separatorChar );
        }
       
          // try relative to plugin dir
       
        file_root = plugin_interface.getPluginDirectoryName();

        if ( file_root != null ){
         
          file_root = file_root + File.separator + root_dir;
         
          if ( !new File(file_root).exists()){
           
            file_root = null;
          }
        }
       
        if ( file_root == null ){
         
          file_root = SystemProperties.getUserPath() + "web" + File.separator + root_dir;
        }
      }
    }

    File  f_root = new File( file_root );
   
    if ( !f_root.exists()){
 
      String  error = "WebPlugin: root dir '" + file_root + "' doesn't exist";
     
      log.log( LoggerChannel.LT_ERROR, error );
     
    }else if ( !f_root.isDirectory()){
     
      String  error = "WebPlugin: root dir '" + file_root + "' isn't a directory";
     
      log.log( LoggerChannel.LT_ERROR, error );
    }
   
    welcome_files = new File[welcome_pages.length];
   
    for (int i=0;i<welcome_pages.length;i++){
     
      welcome_files[i] = new File( file_root + File.separator + welcome_pages[i] );
    }
  }
 
  private void
  setupAccess()
  {
    String  access_str = param_access.getValue().trim();
   
    String ip_ranges_str = "";
   
    ip_ranges     = null;
    ip_range_all  = false;
   
    if ( access_str.length() > 7 && Character.isDigit(access_str.charAt(0))){
     
      String[] ranges = access_str.replace( ';', ',' ).split( "," );
     
      ip_ranges = new ArrayList<IPRange>();
     
      for ( String range: ranges ){
       
        range = range.trim();
       
        if ( range.length() > 7 ){
         
          IPRange ip_range  = plugin_interface.getIPFilter().createRange(true);
     
          int  sep = range.indexOf("-");
       
          if ( sep == -1 ){
       
            ip_range.setStartIP( range );
       
            ip_range.setEndIP( range );
       
          }else{       
       
            ip_range.setStartIP( range.substring(0,sep).trim());
       
            ip_range.setEndIP( range.substring( sep+1 ).trim());
          }
     
          ip_range.checkValid();
     
          if (!ip_range.isValid()){
     
            log.log( LoggerChannel.LT_ERROR, "Access parameter '" + range + "' is invalid" );
           
          }else{
           
            ip_ranges.add( ip_range );
           
            ip_ranges_str += (ip_ranges_str.length()==0?"":", ") + ip_range.getStartIP() + " - " + ip_range.getEndIP();
          }
        }
      }
     
      if ( ip_ranges.size() == 0 ){
       
        ip_ranges = null;
      }
    }else{
     
      if ( access_str.equalsIgnoreCase( "all" ) || access_str.length() == 0 ){
               
        ip_range_all  = true;       
      }
    }
   
    log.log(   LoggerChannel.LT_INFORMATION,
        "Acceptable IP range = " +
          ( ip_ranges==null?
            (ip_range_all?"all":"local"):
            (ip_ranges_str)));
  }
 
  protected void
  setupServer()
  {
    try{
      if ( !plugin_enabled ){
       
        if ( tracker_context != null ){
         
          tracker_context.destroy();
         
          tracker_context = null;
        }
       
        return;
      }
     
      final int port  = param_port.getValue();

      String  protocol_str = param_protocol.getValue().trim();
     
      String bind_ip_str = param_bind.getValue().trim();
     
      InetAddress  bind_ip = null;
     
      if ( bind_ip_str.length() > 0 ){
       
        try{
          bind_ip = InetAddress.getByName( bind_ip_str );
         
        }catch( Throwable  e ){
         
          log.log( LoggerChannel.LT_ERROR, "Bind IP parameter '" + bind_ip_str + "' is invalid" );
   
        }
      }
     
      if ( tracker_context != null ){
       
        URL  url = tracker_context.getURLs()[0];
       
        String    existing_protocol   = url.getProtocol();
        int      existing_port    = url.getPort()==-1?url.getDefaultPort():url.getPort();
        InetAddress existing_bind_ip   = tracker_context.getBindIP();
       
        if (   existing_port == port &&
            existing_protocol.equalsIgnoreCase( protocol_str ) &&
            sameAddress( bind_ip, existing_bind_ip )){
         
          return;
        }
       
        tracker_context.destroy();
       
        tracker_context = null;
      }

     

      int  protocol = protocol_str.equalsIgnoreCase( "HTTP")?Tracker.PR_HTTP:Tracker.PR_HTTPS;
   
      log.log(   LoggerChannel.LT_INFORMATION,
            "Server initialisation: port = " + port +
            (bind_ip == null?"":(", bind = " + bind_ip_str + ")")) +
            ", protocol = " + protocol_str + (root_dir.length()==0?"":(", root = " + root_dir )));

      tracker_context =
        plugin_interface.getTracker().createWebContext(
            Constants.APP_NAME + " - " + plugin_interface.getPluginName(),
            port, protocol, bind_ip );
   
      Boolean  pr_enable_keep_alive = (Boolean)properties.get( PR_ENABLE_KEEP_ALIVE );

      if ( pr_enable_keep_alive != null && pr_enable_keep_alive ){
     
        tracker_context.setEnableKeepAlive( true );
      }
     
      tracker_context.addPageGenerator( this );
 
      tracker_context.addAuthenticationListener(
        new TrackerAuthenticationAdapter()
        {
          private String  last_pw    = "";
          private byte[]  last_hash  = {};
         
          private final int DELAY = 10*1000;
         
          private Map<String,Object[]>  fail_map = new HashMap<String, Object[]>();
         
          public boolean
          authenticate(
            String    headers,
            URL      resource,
            String    user,
            String    pw )
          {
            long  now = SystemTime.getMonotonousTime();

            String  client_address = getHeaderField( headers, "X-Real-IP" );
           
            if ( client_address == null ){
             
              client_address = "<unknown>";
            }

            synchronized( logout_timer ){
             
              Long logout_time = logout_timer.get( client_address );
             
              if ( logout_time != null && now - logout_time <= LOGOUT_GRACE_MILLIS ){
                               
                tls.set( GRACE_PERIOD_MARKER );
               
                return( true );
              }
            }
           
            boolean  result = authenticateSupport( headers, resource, user, pw );
                                       
            if ( !result ){
             
              AESemaphore waiter = null;
             
              synchronized( fail_map ){

               
                Object[] x = fail_map.get( client_address );
             
                if ( x == null ){
                 
                  x = new Object[]{ new AESemaphore( "af:waiter" ), new Long(-1), new Long(-1), now };
                 
                  fail_map.put( client_address, x );
                 
                }else{
                 
                  x[1] = x[2];
                  x[2] = x[3];
                  x[3] = now;
                 
                  long t = (Long)x[1];
                 
                  if ( now - t < 10*1000 ){
                   
                    log( "Too many recent authentication failures from '" + client_address + "' - rate limiting" );

                    x[2] = now+DELAY;
                   
                    waiter = (AESemaphore)x[0];
                  }
                }
              }
             
              if ( waiter != null ){
               
                waiter.reserve( DELAY );
              }
            }
           
            return( result );
          }
         
          private boolean
          authenticateSupport(
            String    headers,
            URL      resource,
            String    user,
            String    pw )
          {
            boolean  result;
           
            boolean  auto_auth =  param_auto_auth != null && param_auto_auth.getValue();

            if ( !pw_enable.getValue()){
                           
              result = true;
             
            }else{
                         
              if ( auto_auth ){
               
                user = user.trim().toLowerCase();
              }
             
              if ( !user.equals( p_user_name.getValue())){
               
                result = false;
               
              }else{
             
                byte[]  hash = last_hash;
               
                if !last_pw.equals( pw )){
                               
                  hash = plugin_interface.getUtilities().getSecurityManager().calculateSHA1(
                      auto_auth?pw.toUpperCase().getBytes():pw.getBytes());
                 
                  last_pw    = pw;
                  last_hash  = hash;
                }
               
                result = Arrays.equals( hash, p_password.getValue());
              }
            }
           
            if ( result ){
           
                // user name and password match, see if we've come from the pairing process
             
              checkCookieSet( headers, resource );
             
            }else if ( auto_auth  ){
             
                // either the ac is in the url, referer or we have a cookie set
                           
              int x = checkCookieSet( headers, resource );
             
              if ( x == 1 ){
               
                result = true;
               
              }else if ( x == 0 ){
                           
                result = hasOurCookie( getHeaderField( headers, "Cookie" ));
              }
            }
           
            return( result );
          }
         
            /**
             *
             * @param headers
             * @param resource
             * @return 0 = unknown, 1 = ok, 2 = bad
             */
         
          private int
          checkCookieSet(
            String    headers,
            URL      resource )
          {
            if ( pairing_access_code == null ){
           
              return( 2 );
            }
           
            String[]  locations = { resource.getQuery(), getHeaderField( headers, "Referer" )};
           
            for ( String location: locations ){
           
              if ( location != null ){
               
                int p1 = location.indexOf( "vuze_pairing_ac=" );
               
                if ( p1 != -1 ){
                 
                  int p2 = location.indexOf( '&', p1 );
                 
                  String ac = location.substring( p1+16, p2==-1?location.length():p2 ).trim();
                 
                  p2 = ac.indexOf( '#' );
                 
                  if ( p2 != -1 ){
                   
                    ac = ac.substring( 0, p2 );
                  }
                               
                  if ( ac.equalsIgnoreCase( pairing_access_code )){
               
                    tls.set( pairing_session_code );
                   
                    return( 1 );
                   
                  }else{
                   
                    return( 2 );
                  }
                }
              }
            }
           
            return( 0 );
          }
         
          private String
          getHeaderField(
            String  headers,
            String  field )
          {
            String lc_headers = headers.toLowerCase();
           
            int p1 = lc_headers.indexOf( field.toLowerCase() + ":" );
           
            if ( p1 != -1 ){
           
              int  p2 = lc_headers.indexOf( '\n', p1 );
             
              if ( p2 != -1 ){
               
                return( headers.substring( p1+field.length()+1, p2 ).trim());
              }
            }
           
            return( null );
          }
        });
     
    }catch( TrackerException e ){
     
      log.log( "Server initialisation failed", e );
    }
  }
 
  private boolean
  hasOurCookie(
    String    cookies )
  {
    if ( cookies == null ){
     
      return( false );
    }
   
    String[] cookie_list = cookies.split( ";" );
   
    for ( String cookie: cookie_list ){
     
      String[] bits = cookie.split( "=" );
     
      if ( bits.length == 2 ){
       
        if ( bits[0].trim().equals( "vuze_pairing_sc" )){
         
          if ( bits[1].trim().equals( pairing_session_code )){
           
            return( true );
          }
        }
      }
    }
   
    return( false );
  }
 
  private boolean
  sameAddress(
    InetAddress  a1,
    InetAddress a2 )
  {
    if ( a1 == null && a2 == null ){
     
      return( true );
     
    }else if ( a1 == null || a2 == null ){
     
      return( false );
     
    }else{
     
      return( a1.equals( a2 ));
    }
  }
 
  protected void
  setupUPnP()
  {
    if ( !plugin_enabled  || !p_upnp_enable.getValue()){
     
      if ( upnp_mapping != null ){
       
        log( "Removing UPnP mapping" );
       
        upnp_mapping.destroy();
       
        upnp_mapping = null;
      }
     
      return;
    }
   
    PluginInterface pi_upnp = plugin_interface.getPluginManager().getPluginInterfaceByClass( UPnPPlugin.class );
   
    if ( pi_upnp == null ){
     
      log.log( "No UPnP plugin available, not attempting port mapping");
     
    }else{
     
      int port = param_port.getValue();
     
      if ( upnp_mapping != null ){
       
        if ( upnp_mapping.getPort() == port ){
         
          return;
        }
       
        log( "Updating UPnP mapping" );
       
        upnp_mapping.destroy();
       
      }else{
       
        log( "Creating UPnP mapping" );
      }
           
      upnp_mapping = ((UPnPPlugin)pi_upnp.getPlugin()).addMapping( plugin_interface.getPluginName(), true, port, true );
    }
  }
 
  protected void
  setupPairing(
    String    sid,
    boolean    pairing_enabled )
  {
    PairingManager pm = PairingManagerFactory.getSingleton();
   
    PairedService service = pm.getService( sid );
   
    if ( plugin_enabled && pairing_enabled && pm.isEnabled()){
     
      setupAutoAuth();
     
      if ( service == null ){
       
        log( "Adding pairing service" );
       
        service =  pm.addService( sid );
       
        PairingConnectionData cd = service.getConnectionData();

        try{         
          updatePairing( cd );
       
        }finally{
       
          cd.sync();
        }
      }
    }else{
     
      pairing_access_code   = null;
      pairing_session_code  = null;
     
      if ( service != null ){
       
        log( "Removing pairing service" );
       
        service.remove();
      }
    }
  }
   
  protected void
  setupAutoAuth()
  {
    PairingManager pm = PairingManagerFactory.getSingleton();

    String ac = pm.peekAccessCode();
   
    if ( ac != null && ( pairing_access_code == null || !ac.equals( pairing_access_code ))){
     
      synchronized( this ){
     
        String existing_key = plugin_config.getPluginStringParameter( PAIRING_SESSION_KEY, "" );
     
        String[]  bits = existing_key.split( "=" );
       
        if ( bits.length == 2 && bits[0].equals( ac )){
         
          pairing_session_code = bits[1];
         
        }else{
     
          pairing_session_code = Base32.encode( RandomUtils.nextSecureHash());
         
          plugin_config.setPluginParameter( PAIRING_SESSION_KEY, ac + "=" + pairing_session_code );
        }
      }
    }
   
    pairing_access_code = ac;
   
      // good time to check the default pairing auth settings
   
    if ( pairing_access_code != null ){
     
      if ( param_auto_auth.getValue()){
       
        try{
          setting_auto_auth = true;
         
          if ( !p_user_name.getValue().equals( "vuze" )){
           
            p_user_name.setValue( "vuze" );
          }
         
              SHA1Hasher hasher = new SHA1Hasher();
             
              byte[] encoded = hasher.calculateHash( pairing_access_code.getBytes());
             
          if ( !Arrays.equals( p_password.getValue(), encoded )){
           
            p_password.setValue( pairing_access_code );
          }
         
          if ( !pw_enable.getValue()){
           
            pw_enable.setValue( true );
          }
        }finally{
         
          setting_auto_auth = false;
        }
      }
    }
  }
  protected void
  updatePairing(
    String    sid )
  {
    PairingManager pm = PairingManagerFactory.getSingleton();
   
    PairedService service = pm.getService( sid );
   
    if ( service != null ){
     
      PairingConnectionData cd = service.getConnectionData();
     
      log( "Updating pairing information" );
     
      try{
        updatePairing( cd );
       
      }finally{
       
        cd.sync();
      }
    }
  }

  protected void
  updatePairing(
    PairingConnectionData    cd )
  {
    cd.setAttribute( PairingConnectionData.ATTR_PORT,     String.valueOf( param_port.getValue()));
   
    int  override = param_port_or==null?0:param_port_or.getValue();
   
    if ( override > 0 ){
     
      cd.setAttribute( PairingConnectionData.ATTR_PORT_OVERRIDE,   String.valueOf( override ));
     
    }else{
     
      cd.setAttribute( PairingConnectionData.ATTR_PORT_OVERRIDE, null );
    }
   
    cd.setAttribute( PairingConnectionData.ATTR_PROTOCOL,   param_protocol.getValue());
  }

  protected int
  getPort()
  {
    return( param_port.getValue());
  }
 
  protected String
  getProtocol()
  {
    return( param_protocol.getValue());
  }
 
  public void
  setUserAndPassword(
    String    user,
    String    password )
  {
    p_user_name.setValue( user );
    p_password.setValue( password );
    pw_enable.setValue( true );
  }
 
  public void
  unsetUserAndPassword()
  {
    pw_enable.setValue( false );
  }
     
  public boolean
  generateSupport(
    TrackerWebPageRequest    request,
    TrackerWebPageResponse    response )
 
    throws IOException
  {
    return( false );
  }
 
  public boolean
  generate(
    TrackerWebPageRequest    request,
    TrackerWebPageResponse    response )
 
    throws IOException
  {
    // System.out.println( request.getURL());
   
    String  client = request.getClientAddress();

    if ( !ip_range_all ){
         
      // System.out.println( "client = " + client );
     
      try{
        boolean valid_ip = true;
        InetAddress ia = InetAddress.getByName( client );
       
        if ( ip_ranges == null ){
         
          if ( !ia.isLoopbackAddress()){
       
            log.log( LoggerChannel.LT_ERROR, "Client '" + client + "' is not local, rejecting" );
            valid_ip = false;
          }
        }else{
         
          boolean ok = false;
         
          for ( IPRange range: ip_ranges ){
           
            if ( range.isInRange( ia.getHostAddress())){
           
              ok = true;
            }
          }
         
          if ( !ok ){
           
            log.log( LoggerChannel.LT_ERROR, "Client '" + client + "' (" + ia.getHostAddress() + ") is not in range, rejecting" );
            valid_ip = false;
          }
        }
       
        if ( !valid_ip ){
         
          response.setReplyStatus( 403 );
         
          return( returnTextPlain( response, "Cannot access resource from this IP address." ));
        }
       
      }catch( Throwable e ){
       
        Debug.printStackTrace( e );
       
        return( false );
      }
    }
   
    String url = request.getURL();
   
 
    if ( url.toString().endsWith(".class")){
     
      System.out.println( "WebPlugin::generate:" + url );
    }
 
    String  cookie_to_set = tls.get();
   
    if ( cookie_to_set == GRACE_PERIOD_MARKER ){
     
      return( returnTextPlain( response, "Logout in progress, please try again later." ));
    }
   
    if ( cookie_to_set != null ){
     
        // set session cookie
   
      response.setHeader( "Set-Cookie", "vuze_pairing_sc=" + cookie_to_set + "; HttpOnly" );
     
      tls.set( null );
    }
   
    URL full_url = request.getAbsoluteURL();
   
    String  full_url_path = full_url.getPath();
   
    if ( full_url_path.equals( "/isPairedServiceAvailable" )){
     
      String redirect = getArgumentFromURL( full_url, "redirect_to" );
     
      if ( redirect != null ){
       
        try{
          URL target = new URL( redirect );
         
          String  host = target.getHost();
         
          if ( !Constants.isAzureusDomain( host )){
         
            if ( !InetAddress.getByName(host).isLoopbackAddress()){
             
              log( "Invalid redirect host: " + host );
             
              redirect = null;
            }
          }
        }catch( Throwable e ){
         
          Debug.out( e );
         
          redirect = null;
        }
      }
     
      if ( redirect != null ){
               
        response.setReplyStatus( 302 );
       
        response.setHeader( "Location", redirect );
       
        return( true );
      }
     
      String callback = getArgumentFromURL( full_url, "jsoncallback" );
       
      if ( callback != null ){
         
        return( returnTextPlain( response,  callback + "( {'pairedserviceavailable':true} )"));
      }
    }else if ( full_url_path.equals( "/isServicePaired" )){
     
      boolean paired = cookie_to_set != null || hasOurCookie((String)request.getHeaders().get( "cookie" ));
     
      return( returnJSON( response, "{ 'servicepaired': " + ( paired?"true":"false" ) + " }" ));
     
    }else if ( full_url_path.equals( "/pairedServiceLogout")){
     
      synchronized( logout_timer ){
       
        logout_timer.put( client, SystemTime.getMonotonousTime());
      }
     
      response.setHeader( "Set-Cookie", "vuze_pairing_sc=<deleted>, expires=" + TimeFormatter.getCookieDate(0));
     
      String redirect = getArgumentFromURL( full_url, "redirect_to" );
     
      if ( redirect != null ){
       
        try{
          URL target = new URL( redirect );
         
          String  host = target.getHost();
         
          if ( !Constants.isAzureusDomain( host )){
         
            if ( !InetAddress.getByName(host).isLoopbackAddress()){
             
              log( "Invalid redirect host: " + host );
             
              redirect = null;
            }
          }
        }catch( Throwable e ){
         
          Debug.out( e );
         
          redirect = null;
        }
      }
      if ( redirect == null ){
         
        return( returnTextPlain( response, "" ));
       
      }else{
       
        response.setReplyStatus( 302 );
       
        response.setHeader( "Location", redirect );
       
        return( true );
      }
    }
 
    if ( generateSupport( request, response )){
     
      return(true);
    }
       
    if ( url.equals("/") || url.startsWith( "/?" )){
     
      url = "/";
     
      if ( home_page != null ){
       
        url = home_page;
       
      }else{
     
        for (int i=0;i<welcome_files.length;i++){
         
          if ( welcome_files[i].exists()){
           
            url = "/" + welcome_pages[i];
           
            break;
          }
        } 
      }
    }
 
      // first try file system for data
   
    if ( response.useFile( file_root, url )){
     
      return( true );
    }
   
        // now try jars   
     
    String  resource_name = url;
   
    if (resource_name.startsWith("/")){
     
      resource_name = resource_name.substring(1);
    }
         
    int  pos = resource_name.lastIndexOf(".");
   
    if ( pos != -1 ){
     
      String  type = resource_name.substring( pos+1 );
   
      ClassLoader  cl = plugin_interface.getPluginClassLoader();
     
      InputStream is = cl.getResourceAsStream( resource_name );
   
      if ( is == null ){
       
        // failed absolute load, try relative
       
        if ( resource_root != null ){
         
          resource_name = resource_root + "/" + resource_name;
         
          is = cl.getResourceAsStream( resource_name )
        }
      }
     
      // System.out.println( resource_name + "->" + is + ", url = " + url );
   
      if (is != null ){
     
        try{
          response.useStream( type, is );
       
        }finally{
       
          is.close();
        }
     
        return( true );
      }
    }
   
    return( false );
  }
 
  private String
  getArgumentFromURL(
    URL      url,
    String    argument )
  {
    String query = url.getQuery();
   
    if ( query != null ){
           
      String[] args = query.split( "&" );
     
      for ( String arg: args ){
       
        String [] x = arg.split( "=" );
       
        if ( x.length == 2 ){
         
          if ( x[0].equals( argument )){
           
            return( UrlUtils.decode( x[1] ));
          }
        }
      }
    }
   
    return( null );
  }
 
  private boolean
  returnTextPlain(
    TrackerWebPageResponse    response,
    String            str )
  {
    return( returnStuff( response, "text/plain", str ));
  }
 
  private boolean
  returnJSON(
    TrackerWebPageResponse    response,
    String            str )
  {
    return( returnStuff( response, "text/plain", str ));
  }
 
  private boolean
  returnStuff(
    TrackerWebPageResponse    response,
    String            content_type,
    String            str )
  {
    response.setContentType( content_type );
   
    PrintWriter pw = new PrintWriter( response.getOutputStream());
   
    pw.println( str );
   
    pw.flush();
   
    pw.close();
 
    return( true );
  }
 
  protected BasicPluginConfigModel
  getConfigModel()
  {
    return( config_model );
  }
 
  protected BasicPluginViewModel getViewModel() {
    return this.view_model;
  }
 
  protected void
  log(
    String  str )
  {
    log.log( str );
  }
 
  protected void
  log(
    String    str,
    Throwable   e )
  {
    log.log( str, e );
  }
}
TOP

Related Classes of org.gudy.azureus2.ui.webplugin.WebPlugin

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.