Пример #1
0
  static void readConfig() {
    tracker_ip = COConfigurationManager.getStringParameter("Tracker IP", "");

    tracker_ip = UrlUtils.expandIPV6Host(tracker_ip);

    String override_ips = COConfigurationManager.getStringParameter("Override Ip", "");

    StringTokenizer tok = new StringTokenizer(override_ips, ";");

    Map new_override_map = new HashMap();

    while (tok.hasMoreTokens()) {

      String ip = tok.nextToken().trim();

      if (ip.length() > 0) {

        new_override_map.put(AENetworkClassifier.categoriseAddress(ip), ip);
      }
    }

    override_map = new_override_map;

    InetAddress bad = NetworkAdmin.getSingleton().getSingleHomedServiceBindAddress();

    if (bad == null || bad.isAnyLocalAddress()) {

      bind_ip = "";

    } else {

      bind_ip = bad.getHostAddress();
    }
  }
Пример #2
0
  /**
   * @param transferData
   * @see org.eclipse.swt.dnd.Transfer#isSupportedType(org.eclipse.swt.dnd.TransferData)
   * @return
   */
  public boolean isSupportedType(TransferData transferData) {
    if (bCheckingString) return true;

    if (transferData == null) return false;

    // TODO: Check if it's a string list of URLs

    // String -- Check if URL, skip to next if not
    URLType url = null;

    if (DEBUG) System.out.println("Checking if type #" + transferData.type + " is URL");

    bCheckingString = true;
    try {
      byte[] buffer = (byte[]) super.nativeToJava(transferData);
      url = bytebufferToJava(buffer);
    } catch (Exception e) {
      Debug.out(e);
    } finally {
      bCheckingString = false;
    }

    if (url == null) {
      if (DEBUG) System.out.println("no, Null URL for type #" + transferData.type);
      return false;
    }

    if (UrlUtils.isURL(url.linkURL, false)) {
      if (DEBUG) System.out.println("Yes, " + url.linkURL + " of type #" + transferData.type);
      return true;
    }

    if (DEBUG) System.out.println("no, " + url.linkURL + " not URL for type #" + transferData.type);
    return false;
  }
  private Map executeHTTP(Map data_to_send, boolean v6) throws Exception {

    if (v6 && !enable_v6) {

      throw (new Exception("IPv6 is disabled"));
    }

    String host = getHost(v6, HTTP_SERVER_ADDRESS_V6, HTTP_SERVER_ADDRESS_V4);

    if (Logger.isEnabled())
      Logger.log(
          new LogEvent(
              LOGID,
              "VersionCheckClient retrieving "
                  + "version information from "
                  + host
                  + ":"
                  + HTTP_SERVER_PORT
                  + " via HTTP"));

    String url_str =
        "http://"
            + (v6 ? UrlUtils.convertIPV6Host(host) : host)
            + (HTTP_SERVER_PORT == 80 ? "" : (":" + HTTP_SERVER_PORT))
            + "/version?";

    url_str +=
        URLEncoder.encode(new String(BEncoder.encode(data_to_send), "ISO-8859-1"), "ISO-8859-1");

    URL url = new URL(url_str);

    HttpURLConnection url_connection = (HttpURLConnection) url.openConnection();

    url_connection.connect();

    try {
      InputStream is = url_connection.getInputStream();

      Map reply = BDecoder.decode(new BufferedInputStream(is));

      preProcessReply(reply, v6);

      return (reply);

    } finally {

      url_connection.disconnect();
    }
  }
  private static boolean checkForSpecialSearchTerm(String str) {
    str = str.trim();

    String hit = UrlUtils.parseTextForURL(str, true, true);

    if (hit == null) {

      return (false);
    }

    UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();

    new FileDownloadWindow(uiFunctions.getMainShell(), str, null, null, true);

    return (true);
  }
  private String getHTTPGetString(Map content, boolean for_proxy, boolean v6) {
    String host = getHost(v6, HTTP_SERVER_ADDRESS_V6, HTTP_SERVER_ADDRESS_V4);

    String get_str =
        "GET "
            + (for_proxy
                ? ("http://"
                    + (v6 ? UrlUtils.convertIPV6Host(host) : host)
                    + ":"
                    + HTTP_SERVER_PORT)
                : "")
            + "/version?";

    try {
      get_str +=
          URLEncoder.encode(new String(BEncoder.encode(content), "ISO-8859-1"), "ISO-8859-1");

    } catch (Throwable e) {
    }

    get_str += " HTTP/1.1" + "\015\012" + "\015\012";

    return (get_str);
  }
Пример #6
0
  public static URL[][] getAnnounceURLs() {
    String tracker_host = COConfigurationManager.getStringParameter("Tracker IP", "");

    List urls = new ArrayList();

    if (tracker_host.length() > 0) {

      if (COConfigurationManager.getBooleanParameter("Tracker Port Enable")) {

        int port = COConfigurationManager.getIntParameter("Tracker Port", TRHost.DEFAULT_PORT);

        try {
          List l = new ArrayList();

          l.add(
              new URL(
                  "http://" + UrlUtils.convertIPV6Host(tracker_host) + ":" + port + "/announce"));

          List ports =
              stringToPorts(COConfigurationManager.getStringParameter("Tracker Port Backups"));

          for (int i = 0; i < ports.size(); i++) {

            l.add(
                new URL(
                    "http://"
                        + UrlUtils.convertIPV6Host(tracker_host)
                        + ":"
                        + ((Integer) ports.get(i)).intValue()
                        + "/announce"));
          }

          urls.add(l);

        } catch (MalformedURLException e) {

          Debug.printStackTrace(e);
        }
      }

      if (COConfigurationManager.getBooleanParameter("Tracker Port SSL Enable")) {

        int port =
            COConfigurationManager.getIntParameter("Tracker Port SSL", TRHost.DEFAULT_PORT_SSL);

        try {
          List l = new ArrayList();

          l.add(
              new URL(
                  "https://" + UrlUtils.convertIPV6Host(tracker_host) + ":" + port + "/announce"));

          List ports =
              stringToPorts(COConfigurationManager.getStringParameter("Tracker Port SSL Backups"));

          for (int i = 0; i < ports.size(); i++) {

            l.add(
                new URL(
                    "https://"
                        + UrlUtils.convertIPV6Host(tracker_host)
                        + ":"
                        + ((Integer) ports.get(i)).intValue()
                        + "/announce"));
          }

          urls.add(l);

        } catch (MalformedURLException e) {

          Debug.printStackTrace(e);
        }
      }

      if (COConfigurationManager.getBooleanParameter("Tracker Port UDP Enable")) {

        int port = COConfigurationManager.getIntParameter("Tracker Port", TRHost.DEFAULT_PORT);

        boolean auth =
            COConfigurationManager.getBooleanParameter("Tracker Password Enable Torrent");

        try {
          List l = new ArrayList();

          l.add(
              new URL(
                  "udp://"
                      + UrlUtils.convertIPV6Host(tracker_host)
                      + ":"
                      + port
                      + "/announce"
                      + (auth ? "?auth" : "")));

          urls.add(l);

        } catch (MalformedURLException e) {

          Debug.printStackTrace(e);
        }
      }
    }

    URL[][] res = new URL[urls.size()][];

    for (int i = 0; i < urls.size(); i++) {

      List l = (List) urls.get(i);

      URL[] u = new URL[l.size()];

      l.toArray(u);

      res[i] = u;
    }

    return (res);
  }
Пример #7
0
 public static boolean isHosting(URL url_in) {
   return (tracker_ip.length() > 0
       && UrlUtils.expandIPV6Host(url_in.getHost()).equalsIgnoreCase(tracker_ip));
 }
  /** @param requiresAuthorization */
  protected static void processQueue(String queueID, Map mapQueue) {
    if (!initialized) {
      init();
    }

    final Map mapProcessing = new HashMap();

    boolean sendAZID = true;
    long contentNetworkID = ContentNetwork.CONTENT_NETWORK_VUZE;

    // Create urlStem (or post data)
    boolean isMulti = false;
    StringBuffer urlStem = new StringBuffer();
    long sequenceNo = 0;

    Map<String, Object> mapPayload = new HashMap<String, Object>();
    mapPayload.put("azid", ConstantsVuze.AZID);
    mapPayload.put("azv", Constants.AZUREUS_VERSION);
    // mapPayload.put("mode", FeatureManagerUI.getMode());
    mapPayload.putAll(mapExtra);
    List<Map> listCommands = new ArrayList<Map>();
    mapPayload.put("commands", listCommands);

    queue_mon.enter();
    try {
      String lastServer = null;
      // add one at a time, ensure relay server messages are seperate
      boolean first = true;
      for (Iterator iter = mapQueue.keySet().iterator(); iter.hasNext(); ) {
        PlatformMessage message = (PlatformMessage) iter.next();
        Object value = mapQueue.get(message);

        Map<String, Object> mapCmd = new HashMap<String, Object>();

        if (first) {
          sendAZID = message.sendAZID();
          contentNetworkID = message.getContentNetworkID();
          first = false;
        }

        // build urlStem
        message.setSequenceNo(sequenceNo);

        if (urlStem.length() > 0) {
          urlStem.append('&');
        }

        String listenerID = message.getListenerID();
        String messageID = message.getMessageID();
        Map params = message.getParameters();
        try {
          urlStem.append("msg=");
          urlStem.append(URLEncoder.encode(listenerID, "UTF-8"));
          urlStem.append(":");
          urlStem.append(URLEncoder.encode(message.getOperationID(), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
        }

        mapCmd.put("seq-id", sequenceNo);
        mapCmd.put("listener-id", listenerID);
        mapCmd.put("op-id", message.getOperationID());
        if (params != null) {
          mapCmd.put("values", params);
        }
        listCommands.add(mapCmd);

        // We used to check on MAX_POST_LENGTH, but with the changes that
        // would require converting the map to JSON on every iteration to get
        // the length.  For now, just limit to 10
        if (sequenceNo > 10) {
          debug("breaking up batch at " + sequenceNo + " because max limit would be exceeded");
          break;
        }

        String curServer = messageID + "-" + listenerID;
        if (lastServer != null && !lastServer.equals(curServer)) {
          isMulti = true;
        }
        lastServer = curServer;

        PlatformMessengerListener listener = (PlatformMessengerListener) mapProcessing.get(message);
        if (listener != null) {
          listener.messageSent(message);
        }
        sequenceNo++;

        // Adjust lists
        mapProcessing.put(message, value);

        iter.remove();

        if (!getAllowMulti()) {
          break;
        }
      }
    } finally {
      queue_mon.exit();
    }
    // debug("about to process " + mapProcessing.size());

    if (mapProcessing.size() == 0) {
      return;
    }

    // Build base RPC url based on listener and server

    // one day all this URL hacking should be moved into the ContentNetwork...

    ContentNetwork cn =
        ContentNetworkManagerFactory.getSingleton().getContentNetwork(contentNetworkID);
    if (cn == null) {
      cn = ConstantsVuze.getDefaultContentNetwork();
    }

    String sURL_RPC =
        ContentNetworkUtils.getUrl(cn, ContentNetwork.SERVICE_RPC) + "&" + urlStem.toString();

    // Build full url and data to send
    String sURL;
    String sPostData = null;
    String sJSONPayload = UrlUtils.encode(JSONUtils.encodeToJSON(mapPayload));
    if (USE_HTTP_POST) {
      sURL = sURL_RPC;

      sPostData = URL_POST_PLATFORM_DATA + "&payload=" + sJSONPayload;
      sPostData = cn.appendURLSuffix(sPostData, true, sendAZID);

      if (DEBUG_URL) {
        debug("POST for " + mapProcessing.size() + ": " + sURL + "\n   DATA: " + sPostData);
      } else {
        debug("POST for " + mapProcessing.size() + ": " + sURL);
      }
    } else {
      sURL = sURL_RPC + URL_PLATFORM_MESSAGE + "&payload=" + sJSONPayload;

      sURL = cn.appendURLSuffix(sURL, false, sendAZID);

      if (DEBUG_URL) {
        debug("GET: " + sURL);
      } else {
        debug("GET: " + sURL_RPC + URL_PLATFORM_MESSAGE);
      }
    }

    final String fURL = sURL;
    final String fPostData = sPostData;

    // one at a time to take advantage of keep-alive connections

    dispatcher.dispatch(
        new AERunnable() {
          public void runSupport() {
            try {
              processQueueAsync(fURL, fPostData, mapProcessing);
            } catch (Throwable e) {
              if (e instanceof ResourceDownloaderException) {
                debug("Error while sending message(s) to Platform: " + e.toString());
              } else {
                debug("Error while sending message(s) to Platform", e);
              }
              for (Iterator iter = mapProcessing.keySet().iterator(); iter.hasNext(); ) {
                PlatformMessage message = (PlatformMessage) iter.next();
                PlatformMessengerListener l =
                    (PlatformMessengerListener) mapProcessing.get(message);
                if (l != null) {
                  try {
                    HashMap map = new HashMap();
                    map.put("text", e.toString());
                    map.put("Throwable", e);
                    l.replyReceived(message, REPLY_EXCEPTION, map);
                  } catch (Throwable e2) {
                    debug("Error while sending replyReceived", e2);
                  }
                }
              }
            }
          }
        });
  }
  protected boolean handleLocalTunnel(
      TrackerWebPageRequest request, TrackerWebPageResponse response) throws IOException {
    start();

    if (SRP_VERIFIER == null || !active) {

      throw (new IOException("Secure pairing is not enabled"));
    }

    boolean good_request = false;

    try {
      // remove /pairing/tunnel/

      String url = request.getURL().substring(16);

      int q_pos = url.indexOf('?');

      Map<String, String> args = new HashMap<String, String>();

      if (q_pos != -1) {

        String args_str = url.substring(q_pos + 1);

        String[] bits = args_str.split("&");

        for (String arg : bits) {

          String[] x = arg.split("=");

          if (x.length == 2) {

            args.put(x[0].toLowerCase(), x[1]);
          }
        }

        url = url.substring(0, q_pos);
      }

      if (url.startsWith("create")) {

        String ac = args.get("ac");
        String sid = args.get("sid");

        if (ac == null || sid == null) {

          throw (new IOException("Access code or service id missing"));
        }

        if (!ac.equals(manager.peekAccessCode())) {

          throw (new IOException("Invalid access code"));
        }

        PairedServiceImpl ps = manager.getService(sid);

        if (ps == null) {

          good_request = true;

          throw (new IOException("Service '" + sid + "' not registered"));
        }

        PairedServiceRequestHandler handler = ps.getHandler();

        if (handler == null) {

          good_request = true;

          throw (new IOException("Service '" + sid + "' has no handler registered"));
        }

        JSONObject json = new JSONObject();

        JSONObject result = new JSONObject();

        json.put("result", result);

        byte[] ss = new byte[] {SRP_SALT[0], SRP_SALT[1], SRP_SALT[2], SRP_SALT[3]};

        long tunnel_id = RandomUtils.nextSecureAbsoluteLong();

        String tunnel_name = Base32.encode(ss) + "_" + tunnel_id;

        synchronized (local_server_map) {
          long diff = SystemTime.getMonotonousTime() - last_local_server_create_time;

          if (diff < 5000) {

            try {
              long sleep = 5000 - diff;

              System.out.println("Sleeping for " + sleep + " before starting srp");

              Thread.sleep(sleep);

            } catch (Throwable e) {
            }
          }

          SRP6Server server = new SRP6Server();

          server.init(N_3072, G_3072, SRP_VERIFIER, new SHA256Digest(), RandomUtils.SECURE_RANDOM);

          BigInteger B = server.generateServerCredentials();

          local_server_map.put(tunnel_name, new Object[] {server, handler, null, null});

          last_local_server_create_time = SystemTime.getMonotonousTime();

          total_local_servers++;

          result.put("srp_salt", Base32.encode(SRP_SALT));

          result.put("srp_b", Base32.encode(B.toByteArray()));

          Map<String, String> headers = request.getHeaders();

          String host = headers.get("host");

          // remove port number

          int pos = host.lastIndexOf("]");

          if (pos != -1) {

            // ipv6 literal

            host = host.substring(0, pos + 1);

          } else {

            pos = host.indexOf(':');

            if (pos != -1) {

              host = host.substring(0, pos);
            }
          }

          String abs_url = request.getAbsoluteURL().toString();

          // unfortunately there is some nasty code that uses a configured tracker
          // address as the default host

          abs_url = UrlUtils.setHost(new URL(abs_url), host).toExternalForm();

          pos = abs_url.indexOf("/create");

          String tunnel_url = abs_url.substring(0, pos) + "/id/" + tunnel_name;

          result.put("url", tunnel_url);
        }

        response.getOutputStream().write(JSONUtils.encodeToJSON(json).getBytes("UTF-8"));

        response.setContentType("application/json; charset=UTF-8");

        response.setGZIP(true);

        good_request = true;

        return (true);

      } else if (url.startsWith("id/")) {

        String tunnel_name = url.substring(3);

        Object[] entry;

        synchronized (local_server_map) {
          entry = local_server_map.get(tunnel_name);

          if (entry == null) {

            good_request = true;

            throw (new IOException("Unknown tunnel id"));
          }
        }

        String srp_a = args.get("srp_a");
        String enc_data = args.get("enc_data");
        String enc_iv = args.get("enc_iv");

        if (srp_a != null && enc_data != null && enc_iv != null) {

          try {
            synchronized (local_server_map) {
              long diff = SystemTime.getMonotonousTime() - last_local_server_agree_time;

              if (diff < 5000) {

                try {
                  long sleep = 5000 - diff;

                  System.out.println("Sleeping for " + sleep + " before completing srp");

                  Thread.sleep(sleep);

                } catch (Throwable e) {
                }
              }
            }

            JSONObject json = new JSONObject();

            JSONObject result = new JSONObject();

            json.put("result", result);

            SRP6Server server = (SRP6Server) entry[0];

            BigInteger A = new BigInteger(Base32.decode(srp_a));

            BigInteger serverS = server.calculateSecret(A);

            byte[] shared_secret = serverS.toByteArray();

            Cipher decipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

            byte[] key = new byte[16];

            System.arraycopy(shared_secret, 0, key, 0, 16);

            SecretKeySpec secret = new SecretKeySpec(key, "AES");

            decipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(Base32.decode(enc_iv)));

            byte[] dec = decipher.doFinal(Base32.decode(enc_data));

            JSONObject dec_json = (JSONObject) JSONUtils.decodeJSON(new String(dec, "UTF-8"));

            String tunnel_url = (String) dec_json.get("url");

            if (!tunnel_url.contains(tunnel_name)) {

              throw (new IOException("Invalid tunnel url"));
            }

            String endpoint_url = (String) dec_json.get("endpoint");

            entry[2] = secret;
            entry[3] = endpoint_url;

            result.put("state", "activated");

            response.getOutputStream().write(JSONUtils.encodeToJSON(json).getBytes("UTF-8"));

            response.setContentType("application/json; charset=UTF-8");

            response.setGZIP(true);

            good_request = true;

            return (true);

          } catch (Throwable e) {

            throw (new IOException(Debug.getNestedExceptionMessage(e)));

          } finally {

            last_local_server_agree_time = SystemTime.getMonotonousTime();
          }
        } else if (args.containsKey("close")) {

          synchronized (local_server_map) {
            local_server_map.remove(tunnel_name);
          }

          good_request = true;

          return (true);

        } else {

          PairedServiceRequestHandler request_handler = (PairedServiceRequestHandler) entry[1];

          SecretKeySpec secret = (SecretKeySpec) entry[2];

          String endpoint_url = (String) entry[3];

          if (secret == null) {

            throw (new IOException("auth not completed"));
          }

          byte[] request_data = FileUtil.readInputStreamAsByteArray(request.getInputStream());

          try {
            byte[] decrypted;

            {
              byte[] IV = new byte[16];

              System.arraycopy(request_data, 0, IV, 0, IV.length);

              Cipher decipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

              decipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(IV));

              decrypted = decipher.doFinal(request_data, 16, request_data.length - 16);
            }

            byte[] reply_bytes =
                request_handler.handleRequest(
                    request.getClientAddress2().getAddress(), endpoint_url, decrypted);

            {
              Cipher encipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

              encipher.init(Cipher.ENCRYPT_MODE, secret);

              AlgorithmParameters params = encipher.getParameters();

              byte[] IV = params.getParameterSpec(IvParameterSpec.class).getIV();

              byte[] enc = encipher.doFinal(reply_bytes);

              byte[] rep_bytes = new byte[IV.length + enc.length];

              System.arraycopy(IV, 0, rep_bytes, 0, IV.length);
              System.arraycopy(enc, 0, rep_bytes, IV.length, enc.length);

              response.getOutputStream().write(rep_bytes);

              response.setContentType("application/octet-stream");

              good_request = true;

              return (true);
            }
          } catch (Throwable e) {

            throw (new IOException(Debug.getNestedExceptionMessage(e)));
          }
        }
      }

      throw (new IOException("Unknown tunnel operation"));

    } finally {

      if (!good_request) {

        manager.recordRequest(
            "SRP", request.getClientAddress2().getAddress().getHostAddress(), false);
      }
    }
  }
Пример #10
0
  public void runSupport() {

    try {
      new URL(url_str); // determine if this is already a proper URL
    } catch (Throwable t) { // it's not

      //  			//check if the string is just a base32/hex-encoded torrent infohash
      //
      //  		String magnet_uri = UrlUtils.normaliseMagnetURI( url_str );
      //
      //  		if ( magnet_uri != null ){
      //
      //  			url_str = magnet_uri;
      //  		}
    }

    try {
      url = AddressUtils.adjustURL(new URL(url_str));

      String protocol = url.getProtocol().toLowerCase();

      // hack here - the magnet download process requires an additional paramter to cause it to
      // stall on error so the error can be reported

      //    	if ( protocol.equals( "magnet" ) || protocol.equals( "dht" )){
      //
      //    		url = AddressUtils.adjustURL( new URL(url_str+"&pause_on_error=true"));
      //    	}

      for (int i = 0; i < 2; i++) {
        try {

          //	      if ( protocol.equals("https")){
          //
          //	      	// see ConfigurationChecker for SSL client defaults
          //
          //	      	HttpsURLConnection ssl_con = (HttpsURLConnection)url.openConnection();
          //
          //	      	// allow for certs that contain IP addresses rather than dns names
          //
          //	      	ssl_con.setHostnameVerifier(
          //	      			new HostnameVerifier()
          //	      			{
          //	      				public boolean
          //	      				verify(
          //	      					String		host,
          //							SSLSession	session )
          //	      				{
          //	      					return( true );
          //	      				}
          //	      			});
          //
          //	      	con = ssl_con;
          //
          //	      }else{
          //
          con = (HttpURLConnection) url.openConnection();

          //	      }

          con.setRequestProperty(
              "User-Agent", Constants.AZUREUS_NAME + " " + Constants.AZUREUS_VERSION);

          if (referrer != null && referrer.length() > 0) {

            con.setRequestProperty("Referer", referrer);
          }

          if (request_properties != null) {

            Iterator it = request_properties.entrySet().iterator();

            while (it.hasNext()) {

              Map.Entry entry = (Map.Entry) it.next();

              String key = (String) entry.getKey();
              String value = (String) entry.getValue();

              // currently this code doesn't support gzip/deflate...

              if (!key.equalsIgnoreCase("Accept-Encoding")) {

                con.setRequestProperty(key, value);
              }
            }
          }

          this.con.connect();

          break;

          //      	}catch( SSLException e ){
          //
          //      		if ( i == 0 ){
          //
          //      			if ( SESecurityManager.installServerCertificates( url ) != null ){
          //
          //      				// certificate has been installed
          //
          //      				continue;	// retry with new certificate
          //      			}
          //      		}
          //
          //      		throw( e );
          //
        } catch (IOException e) {

          if (i == 0) {

            URL retry_url = UrlUtils.getIPV4Fallback(url);

            if (retry_url != null) {

              url = retry_url;

            } else {

              throw (e);
            }
          }
        }
      }

      int response = this.con.getResponseCode();
      if (!ignoreReponseCode) {
        if ((response != HttpURLConnection.HTTP_ACCEPTED)
            && (response != HttpURLConnection.HTTP_OK)) {
          this.error(response, Integer.toString(response) + ": " + this.con.getResponseMessage());
          return;
        }
      }

      /*
           Map headerFields = this.con.getHeaderFields();

           System.out.println("Header of download of " + url_str);
           for (Iterator iter = headerFields.keySet().iterator(); iter.hasNext();) {
      			String s = (String) iter.next();
      			System.out.println(s + ":" + headerFields.get(s));

      		}
      */
      filename = this.con.getHeaderField("Content-Disposition");
      if ((filename != null)
          && filename
              .toLowerCase()
              .matches(".*attachment.*")) // Some code to handle b0rked servers.
      while (filename.toLowerCase().charAt(0) != 'a') filename = filename.substring(1);
      if ((filename == null)
          || !filename.toLowerCase().startsWith("attachment")
          || (filename.indexOf('=') == -1)) {
        String tmp = this.url.getFile();
        if (tmp.length() == 0 || tmp.equals("/")) {
          filename = url.getHost();
        } else if (tmp.startsWith("?")) {

          // probably a magnet URI - use the hash
          // magnet:?xt=urn:sha1:VGC53ZWCUXUWVGX7LQPVZIYF4L6RXSU6

          String query = tmp.toUpperCase();

          int pos = query.indexOf("XT=URN:SHA1:");

          if (pos == -1) {

            pos = query.indexOf("XT=URN:BTIH:");
          }

          if (pos != -1) {

            pos += 12;

            int p2 = query.indexOf("&", pos);

            if (p2 == -1) {

              filename = query.substring(pos);

            } else {

              filename = query.substring(pos, p2);
            }
          } else {

            filename = "Torrent" + (long) (Math.random() * Long.MAX_VALUE);
          }

          filename += ".tmp";

        } else {
          if (tmp.lastIndexOf('/') != -1) tmp = tmp.substring(tmp.lastIndexOf('/') + 1);

          // remove any params in the url

          int param_pos = tmp.indexOf('?');

          if (param_pos != -1) {
            tmp = tmp.substring(0, param_pos);
          }

          filename = URLDecoder.decode(tmp, Constants.DEFAULT_ENCODING);
        }
      } else {
        filename = filename.substring(filename.indexOf('=') + 1);
        if (filename.startsWith("\"") && filename.endsWith("\""))
          filename = filename.substring(1, filename.lastIndexOf('\"'));

        filename = URLDecoder.decode(filename, Constants.DEFAULT_ENCODING);

        // not sure of this piece of logic here but I'm not changing it at the moment

        File temp = new File(filename);
        filename = temp.getName();
      }

      filename = FileUtil.convertOSSpecificChars(filename, false);

      //      directoryname =
      // COConfigurationManager.getDirectoryParameter("General_sDefaultTorrent_Directory");
      //      boolean useTorrentSave = COConfigurationManager.getBooleanParameter("Save Torrent
      // Files");
      directoryname = "D:\\Development\\testDownloads\\";
      boolean useTorrentSave = true;
      if (file_str != null) {
        // not completely sure about the whole logic in this block
        File temp = new File(file_str);

        // if we're not using a default torrent save dir
        if (!useTorrentSave || directoryname.length() == 0) {
          // if it's already a dir
          if (temp.isDirectory()) {
            // use it
            directoryname = temp.getCanonicalPath();
          }
          // it's a file
          else {
            // so use its parent dir
            directoryname = temp.getCanonicalFile().getParent();
          }
        }

        // if it's a file
        if (!temp.isDirectory()) {
          // set the file name
          filename = temp.getName();
        }
      }
      // what would happen here if directoryname == null and file_str == null??

      this.state = STATE_INIT;
      this.notifyListener();
    } catch (java.net.MalformedURLException e) {
      this.error(0, "Exception while parsing URL '" + url + "':" + e.getMessage());
    } catch (java.net.UnknownHostException e) {
      this.error(
          0,
          "Exception while initializing download of '"
              + url
              + "': Unknown Host '"
              + e.getMessage()
              + "'");
    } catch (java.io.IOException ioe) {
      this.error(0, "I/O Exception while initializing download of '" + url + "':" + ioe.toString());
    } catch (Throwable e) {
      this.error(0, "Exception while initializing download of '" + url + "':" + e.toString());
    }

    if (this.state == STATE_ERROR) {

      return;
    }

    try {
      final boolean status_reader_run[] = {true};

      this.state = STATE_START;

      notifyListener();

      this.state = STATE_DOWNLOADING;

      notifyListener();

      Thread status_reader =
          new AEThread("TorrentDownloader:statusreader") {
            public void runSupport() {
              boolean changed_status = false;

              while (true) {

                try {
                  Thread.sleep(100);

                  try {
                    this_mon.enter();

                    if (!status_reader_run[0]) {

                      break;
                    }
                  } finally {

                    this_mon.exit();
                  }

                  String s = con.getResponseMessage();

                  if (!s.equals(getStatus())) {

                    if (!s.toLowerCase().startsWith("error:")) {

                      if (s.toLowerCase().indexOf("alive") != -1) {

                        if (percentDone < 10) {

                          percentDone++;
                        }
                      }

                      int pos = s.indexOf('%');

                      if (pos != -1) {

                        int i;

                        for (i = pos - 1; i >= 0; i--) {

                          char c = s.charAt(i);

                          if (!Character.isDigit(c) && c != ' ') {

                            i++;

                            break;
                          }
                        }

                        try {
                          percentDone = Integer.parseInt(s.substring(i, pos).trim());

                        } catch (Throwable e) {

                        }
                      }

                      setStatus(s);

                    } else {

                      error(con.getResponseCode(), s.substring(6));
                    }

                    changed_status = true;
                  }

                } catch (Throwable e) {

                  break;
                }
              }

              if (changed_status) {

                setStatus("");
              }
            }
          };

      status_reader.setDaemon(true);

      status_reader.start();

      InputStream in;

      try {
        in = this.con.getInputStream();

      } catch (FileNotFoundException e) {
        if (ignoreReponseCode) {

          in = this.con.getErrorStream();
        } else {

          throw e;
        }

      } finally {

        try {
          this_mon.enter();

          status_reader_run[0] = false;

        } finally {

          this_mon.exit();
        }
      }

      // handle some servers that return gzip'd torrents even though we don't request it!

      String encoding = con.getHeaderField("content-encoding");

      if (encoding != null) {

        if (encoding.equalsIgnoreCase("gzip")) {

          in = new GZIPInputStream(in);

        } else if (encoding.equalsIgnoreCase("deflate")) {

          in = new InflaterInputStream(in);
        }
      }

      if (this.state != STATE_ERROR) {

        this.file = new File(this.directoryname, filename);

        boolean useTempFile = false;
        try {
          this.file.createNewFile();
          useTempFile = !this.file.exists();
        } catch (Throwable t) {
          useTempFile = true;
        }

        if (useTempFile) {
          this.file = File.createTempFile("AZU", ".torrent", new File(this.directoryname));
          this.file.createNewFile();
        }

        FileOutputStream fileout = new FileOutputStream(this.file, false);

        bufBytes = 0;

        int size = (int) UrlUtils.getContentLength(con);

        this.percentDone = -1;

        do {
          if (this.cancel) {
            break;
          }

          try {
            bufBytes = in.read(buf);

            this.readTotal += bufBytes;

            if (size != 0) {
              this.percentDone = (100 * this.readTotal) / size;
            }

            notifyListener();

          } catch (IOException e) {
          }

          if (bufBytes > 0) {
            fileout.write(buf, 0, bufBytes);
          }
        } while (bufBytes > 0);

        in.close();

        fileout.flush();

        fileout.close();

        if (this.cancel) {
          this.state = STATE_CANCELLED;
          if (deleteFileOnCancel) {
            this.cleanUpFile();
          }
        } else {
          if (this.readTotal <= 0) {
            this.error(0, "No data contained in '" + this.url.toString() + "'");
            return;
          }

          // if the file has come down with a not-so-useful name then we try to rename
          // it to something more useful

          try {
            if (!filename.toLowerCase().endsWith(".torrent")) {

              TOTorrent torrent = TorrentUtils.readFromFile(file, false);

              String name = TorrentUtils.getLocalisedName(torrent) + ".torrent";

              File new_file = new File(directoryname, name);

              if (file.renameTo(new_file)) {

                filename = name;

                file = new_file;
              }
            }
          } catch (Throwable e) {

            Debug.printStackTrace(e);
          }

          //	          TorrentUtils.setObtainedFrom( file, original_url );

          this.state = STATE_FINISHED;
        }
        this.notifyListener();
      }
    } catch (Exception e) {

      if (!cancel) {

        Debug.out("'" + this.directoryname + "' '" + filename + "'", e);
      }

      this.error(0, "Exception while downloading '" + this.url.toString() + "':" + e.getMessage());
    }
  }