Search in sources :

Example 1 with ExternalSeedException

use of com.biglybt.plugin.extseed.ExternalSeedException in project BiglyBT by BiglySoftware.

the class ExternalSeedReaderRequest method getBuffer.

@Override
public byte[] getBuffer() throws ExternalSeedException {
    if (current_request_index >= requests.size()) {
        throw (new ExternalSeedException("Insufficient buffers to satisfy request"));
    }
    current_request = (PeerReadRequest) requests.get(current_request_index++);
    current_buffer = new byte[current_request.getLength()];
    current_position = 0;
    return (current_buffer);
}
Also used : ExternalSeedException(com.biglybt.plugin.extseed.ExternalSeedException)

Example 2 with ExternalSeedException

use of com.biglybt.plugin.extseed.ExternalSeedException in project BiglyBT by BiglySoftware.

the class ExternalSeedReaderGetRight method readData.

@Override
protected void readData(int start_piece_number, int start_piece_offset, int length, final ExternalSeedHTTPDownloaderListener listener) throws ExternalSeedException {
    setupDownloaders();
    setReconnectDelay(RECONNECT_DEFAULT, false);
    long request_start = start_piece_number * (long) piece_size + start_piece_offset;
    int request_length = length;
    if (http_downloaders.length == 1) {
        ExternalSeedHTTPDownloader http_downloader = http_downloaders[0];
        try {
            http_downloader.downloadRange(request_start, request_length, listener, isTransient());
        } catch (ExternalSeedException ese) {
            if (http_downloader.getLastResponse() == 503 && http_downloader.getLast503RetrySecs() >= 0) {
                int retry_secs = http_downloader.getLast503RetrySecs();
                setReconnectDelay(retry_secs * 1000, true);
                throw (new ExternalSeedException("Server temporarily unavailable, retrying in " + retry_secs + " seconds"));
            } else {
                throw (ese);
            }
        }
    } else {
        long request_end = request_start + request_length;
        // System.out.println( "Req: start=" + request_start + ", len=" + request_length );
        final byte[][] overlap_buffer = { null };
        final int[] overlap_buffer_position = { 0 };
        for (int i = 0; i < http_downloaders.length; i++) {
            long this_start = downloader_offsets[i];
            long this_end = this_start + downloader_lengths[i];
            if (this_end <= request_start) {
                continue;
            }
            if (this_start >= request_end) {
                break;
            }
            long sub_request_start = Math.max(request_start, this_start);
            long sub_request_end = Math.min(request_end, this_end);
            final int sub_len = (int) (sub_request_end - sub_request_start);
            if (sub_len == 0) {
                continue;
            }
            ExternalSeedHTTPDownloader http_downloader = http_downloaders[i];
            // System.out.println( "    sub_req: start=" + sub_request_start + ", len=" + sub_len + ",url=" + http_downloader.getURL());
            ExternalSeedHTTPDownloaderListener sub_request = new ExternalSeedHTTPDownloaderListener() {

                private int bytes_read;

                private byte[] current_buffer = overlap_buffer[0];

                private int current_buffer_position = overlap_buffer_position[0];

                private int current_buffer_length = current_buffer == null ? -1 : Math.min(current_buffer.length, current_buffer_position + sub_len);

                @Override
                public byte[] getBuffer() throws ExternalSeedException {
                    if (current_buffer == null) {
                        current_buffer = listener.getBuffer();
                        current_buffer_position = 0;
                        current_buffer_length = Math.min(current_buffer.length, sub_len - bytes_read);
                    }
                    return (current_buffer);
                }

                @Override
                public void setBufferPosition(int position) {
                    current_buffer_position = position;
                    listener.setBufferPosition(position);
                }

                @Override
                public int getBufferPosition() {
                    return (current_buffer_position);
                }

                @Override
                public int getBufferLength() {
                    return (current_buffer_length);
                }

                @Override
                public int getPermittedBytes() throws ExternalSeedException {
                    return (listener.getPermittedBytes());
                }

                @Override
                public int getPermittedTime() {
                    return (listener.getPermittedTime());
                }

                @Override
                public void reportBytesRead(int num) {
                    bytes_read += num;
                    listener.reportBytesRead(num);
                }

                @Override
                public boolean isCancelled() {
                    return (listener.isCancelled());
                }

                @Override
                public void done() {
                    // the current buffer is full up to the declared length
                    int rem = current_buffer.length - current_buffer_length;
                    if (bytes_read == sub_len) {
                        if (rem == 0) {
                            overlap_buffer[0] = null;
                            overlap_buffer_position[0] = 0;
                        } else {
                            overlap_buffer[0] = current_buffer;
                            overlap_buffer_position[0] = current_buffer_length;
                        }
                    }
                    // prepare for next buffer if needed
                    current_buffer = null;
                    if (rem == 0) {
                        listener.done();
                    }
                }
            };
            try {
                http_downloader.downloadRange(sub_request_start - this_start, sub_len, sub_request, isTransient());
            } catch (ExternalSeedException ese) {
                if (http_downloader.getLastResponse() == 503 && http_downloader.getLast503RetrySecs() >= 0) {
                    int retry_secs = http_downloader.getLast503RetrySecs();
                    setReconnectDelay(retry_secs * 1000, true);
                    throw (new ExternalSeedException("Server temporarily unavailable, retrying in " + retry_secs + " seconds"));
                } else {
                    throw (ese);
                }
            }
        }
    }
}
Also used : ExternalSeedHTTPDownloader(com.biglybt.plugin.extseed.util.ExternalSeedHTTPDownloader) ExternalSeedHTTPDownloaderListener(com.biglybt.plugin.extseed.util.ExternalSeedHTTPDownloaderListener) ExternalSeedException(com.biglybt.plugin.extseed.ExternalSeedException)

Example 3 with ExternalSeedException

use of com.biglybt.plugin.extseed.ExternalSeedException in project BiglyBT by BiglySoftware.

the class ExternalSeedReaderWebSeed method readData.

@Override
protected void readData(int piece_number, int piece_offset, int length, ExternalSeedHTTPDownloaderListener listener) throws ExternalSeedException {
    long piece_end = piece_offset + length - 1;
    String str = url_prefix + "&piece=" + piece_number + "&ranges=" + piece_offset + "-" + piece_end;
    setReconnectDelay(RECONNECT_DEFAULT, false);
    ExternalSeedHTTPDownloader http_downloader = null;
    try {
        http_downloader = new ExternalSeedHTTPDownloaderRange(new URL(str), getUserAgent());
        if (supports_503) {
            http_downloader.downloadSocket(length, listener, isTransient());
        } else {
            http_downloader.download(length, listener, isTransient());
        }
    } catch (ExternalSeedException ese) {
        if (http_downloader.getLastResponse() == 503 && http_downloader.getLast503RetrySecs() >= 0) {
            int retry_secs = http_downloader.getLast503RetrySecs();
            setReconnectDelay(retry_secs * 1000, true);
            throw (new ExternalSeedException("Server temporarily unavailable, retrying in " + retry_secs + " seconds"));
        } else {
            throw (ese);
        }
    } catch (MalformedURLException e) {
        throw (new ExternalSeedException("URL encode fails", e));
    }
}
Also used : ExternalSeedHTTPDownloaderRange(com.biglybt.plugin.extseed.util.ExternalSeedHTTPDownloaderRange) ExternalSeedHTTPDownloader(com.biglybt.plugin.extseed.util.ExternalSeedHTTPDownloader) MalformedURLException(java.net.MalformedURLException) URL(java.net.URL) ExternalSeedException(com.biglybt.plugin.extseed.ExternalSeedException)

Example 4 with ExternalSeedException

use of com.biglybt.plugin.extseed.ExternalSeedException in project BiglyBT by BiglySoftware.

the class ExternalSeedHTTPDownloaderLinear method deactivate.

@Override
public void deactivate() {
    Downloader to_destroy = null;
    synchronized (this) {
        if (downloader != null) {
            to_destroy = downloader;
            downloader = null;
        }
    }
    if (to_destroy != null) {
        to_destroy.destroy(new ExternalSeedException("deactivated"));
    }
}
Also used : ExternalSeedException(com.biglybt.plugin.extseed.ExternalSeedException)

Example 5 with ExternalSeedException

use of com.biglybt.plugin.extseed.ExternalSeedException in project BiglyBT by BiglySoftware.

the class ExternalSeedHTTPDownloaderRange method downloadSocket.

public void downloadSocket(String[] prop_names, String[] prop_values, int length, ExternalSeedHTTPDownloaderListener listener, boolean con_fail_is_perm_fail) throws ExternalSeedException {
    Socket socket = null;
    boolean connected = false;
    PluginProxy plugin_proxy = null;
    boolean proxy_ok = false;
    try {
        String output_header = "GET " + very_original_url.getPath() + "?" + very_original_url.getQuery() + " HTTP/1.1" + NL + "Host: " + very_original_url.getHost() + (very_original_url.getPort() == -1 ? "" : (":" + very_original_url.getPort())) + NL + "Accept: */*" + NL + "Connection: Close" + // if we want to support keep-alive we'll need to implement a socket cache etc.
        NL + "User-Agent: " + user_agent + NL;
        for (int i = 0; i < prop_names.length; i++) {
            output_header += prop_names[i] + ":" + prop_values[i] + NL;
        }
        output_header += NL;
        int time_remaining = listener.getPermittedTime();
        URL original_url = very_original_url;
        URL current_url = original_url;
        Proxy current_proxy = null;
        if (AENetworkClassifier.categoriseAddress(very_original_url.getHost()) != AENetworkClassifier.AT_PUBLIC) {
            plugin_proxy = AEProxyFactory.getPluginProxy("webseed", original_url);
            if (plugin_proxy != null) {
                current_url = plugin_proxy.getURL();
                current_proxy = plugin_proxy.getProxy();
            }
        }
        if (time_remaining > 0) {
            if (current_proxy == null) {
                socket = new Socket();
            } else {
                socket = new Socket(current_proxy);
            }
            socket.connect(new InetSocketAddress(current_url.getHost(), current_url.getPort() == -1 ? current_url.getDefaultPort() : current_url.getPort()), time_remaining);
        } else {
            if (current_proxy == null) {
                socket = new Socket(current_url.getHost(), current_url.getPort() == -1 ? current_url.getDefaultPort() : current_url.getPort());
            } else {
                socket = new Socket(current_proxy);
                socket.connect(new InetSocketAddress(current_url.getHost(), current_url.getPort() == -1 ? current_url.getDefaultPort() : current_url.getPort()));
            }
        }
        connected = true;
        proxy_ok = true;
        time_remaining = listener.getPermittedTime();
        if (time_remaining < 0) {
            throw (new IOException("Timeout during connect"));
        } else if (time_remaining > 0) {
            socket.setSoTimeout(time_remaining);
        }
        OutputStream os = socket.getOutputStream();
        os.write(output_header.getBytes("ISO-8859-1"));
        os.flush();
        InputStream is = socket.getInputStream();
        try {
            String input_header = "";
            while (true) {
                byte[] buffer = new byte[1];
                int len = is.read(buffer);
                if (len < 0) {
                    throw (new IOException("input too short reading header"));
                }
                input_header += (char) buffer[0];
                if (input_header.endsWith(NL + NL)) {
                    break;
                }
            }
            // HTTP/1.1 403 Forbidden
            int line_end = input_header.indexOf(NL);
            if (line_end == -1) {
                throw (new IOException("header too short"));
            }
            String first_line = input_header.substring(0, line_end);
            StringTokenizer tok = new StringTokenizer(first_line, " ");
            tok.nextToken();
            int response = Integer.parseInt(tok.nextToken());
            last_response = response;
            last_response_retry_after_secs = -1;
            String response_str = tok.nextToken();
            if (response == HttpURLConnection.HTTP_ACCEPTED || response == HttpURLConnection.HTTP_OK || response == HttpURLConnection.HTTP_PARTIAL) {
                byte[] buffer = null;
                int buffer_pos = 0;
                int buffer_len = 0;
                int pos = 0;
                while (pos < length) {
                    if (buffer == null) {
                        buffer = listener.getBuffer();
                        buffer_pos = listener.getBufferPosition();
                        buffer_len = listener.getBufferLength();
                    }
                    int to_read = buffer_len - buffer_pos;
                    int permitted = listener.getPermittedBytes();
                    if (permitted < to_read) {
                        to_read = permitted;
                    }
                    int len = is.read(buffer, buffer_pos, to_read);
                    if (len < 0) {
                        break;
                    }
                    listener.reportBytesRead(len);
                    pos += len;
                    buffer_pos += len;
                    if (buffer_pos == buffer_len) {
                        listener.done();
                        buffer = null;
                        buffer_pos = 0;
                    }
                }
                if (pos != length) {
                    String log_str;
                    if (buffer == null) {
                        log_str = "No buffer assigned";
                    } else {
                        log_str = new String(buffer, 0, buffer_pos > 64 ? 64 : buffer_pos);
                    }
                    throw (new ExternalSeedException("Connection failed: data too short - " + length + "/" + pos + " [last=" + log_str + "]"));
                }
            // System.out.println( "download length: " + pos );
            } else if (response == 503) {
                // webseed support for temp unavail - read the data
                String data_str = "";
                while (true) {
                    byte[] buffer = new byte[1];
                    int len = is.read(buffer);
                    if (len < 0) {
                        break;
                    }
                    data_str += (char) buffer[0];
                }
                last_response_retry_after_secs = Integer.parseInt(data_str);
                throw (new IOException("Server overloaded"));
            } else {
                ExternalSeedException error = new ExternalSeedException("Connection failed: " + response_str);
                error.setPermanentFailure(true);
                throw (error);
            }
        } finally {
            is.close();
        }
    } catch (IOException e) {
        if (con_fail_is_perm_fail && !connected) {
            ExternalSeedException error = new ExternalSeedException("Connection failed: " + e.getMessage());
            error.setPermanentFailure(true);
            throw (error);
        } else {
            String outcome = "Connection failed: " + Debug.getNestedExceptionMessage(e);
            if (last_response_retry_after_secs >= 0) {
                outcome += ", Retry-After: " + last_response_retry_after_secs + " seconds";
            }
            throw (new ExternalSeedException(outcome, e));
        }
    } catch (Throwable e) {
        if (e instanceof ExternalSeedException) {
            throw ((ExternalSeedException) e);
        }
        throw (new ExternalSeedException("Connection failed", e));
    } finally {
        if (socket != null) {
            try {
                socket.close();
            } catch (Throwable e) {
            }
        }
        if (plugin_proxy != null) {
            plugin_proxy.setOK(proxy_ok);
        }
    }
}
Also used : InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) PluginProxy(com.biglybt.core.proxy.AEProxyFactory.PluginProxy) IOException(java.io.IOException) ExternalSeedException(com.biglybt.plugin.extseed.ExternalSeedException) PluginProxy(com.biglybt.core.proxy.AEProxyFactory.PluginProxy) StringTokenizer(java.util.StringTokenizer)

Aggregations

ExternalSeedException (com.biglybt.plugin.extseed.ExternalSeedException)6 PluginProxy (com.biglybt.core.proxy.AEProxyFactory.PluginProxy)2 ExternalSeedHTTPDownloader (com.biglybt.plugin.extseed.util.ExternalSeedHTTPDownloader)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 ExternalSeedHTTPDownloaderListener (com.biglybt.plugin.extseed.util.ExternalSeedHTTPDownloaderListener)1 ExternalSeedHTTPDownloaderRange (com.biglybt.plugin.extseed.util.ExternalSeedHTTPDownloaderRange)1 FileNotFoundException (java.io.FileNotFoundException)1 OutputStream (java.io.OutputStream)1 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 HashSet (java.util.HashSet)1 StringTokenizer (java.util.StringTokenizer)1