/* * [LinkProbe.java] * * Summary: For thread to probe one site URL to see if it alive. This is transient info about the probe. * * Copyright: (c) 2012-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.0 2012-02-26 initial version */ package com.mindprod.brokenlinks; import com.mindprod.http.Fetch; import com.mindprod.http.Probe; import java.io.File; import java.net.URL; import java.util.concurrent.Semaphore; import static java.lang.System.*; /** * For thread to probe one site URL to see if it alive. This is transient info about the probe. *

* LinkInfo contains permanent info about the link. * run does the probe. * * @author Roedy Green, Canadian Mind Products * @version 1.0 2012-02-26 initial version * @since 2012-02-26 */ class LinkProbe implements Runnable { /** * number of probes to queue up ready to be executed */ static final int TASK_POOL_SIZE = 32; /** * number of threads in pool to do store probes */ static final int THREAD_POOL_SIZE = 30; /** * true to turn off threads */ private static final boolean DEBUGGING = false; private static final int BROKEN_LINKS_FILE_NOT_FOUND = -15; private static final int BROKEN_LINKS_FILE_OK = -16; /** * throttles how many probes in queue or executing */ private static final Semaphore semaphore = new Semaphore( TASK_POOL_SIZE ); /** * URL to probe */ final URL url; /** * LinkInfo where info about this link is stored, where we record status of link */ private final LinkInfo b; /** * 0=use GET 1=use HEAD 2=use HEAD then GET, 3=use FETCH, 4 = use File.exists(). */ private final int howProbe; /** * to probe one url at one site, constructs packet later executed. * * @param url URL to probe * @param b LinkInfo where info about this link is stored, where we record status of link */ LinkProbe( final URL url, final LinkInfo b ) { this.url = url; this.b = b; this.howProbe = b.getHowProbe(); // the pool will not block when full, so we do it manually. try { if ( !DEBUGGING ) { semaphore.acquire(); } } catch ( InterruptedException e ) { // will block until can increment the semaphore } } /** * method to run on separate thread. Probe and set status. No messages though. */ public void run() { try { switch ( howProbe ) { case 0 /* use GET */ : case 1 /* use HEAD */ : case 2 /* use HEAD then GET */ : { Probe probe = new Probe(); probe.setInstanceFollowRedirects( false ); final int response = probe.send( url, howProbe ); // takes a fair while to complete final String actualResponseMessage = probe.getResponseMessage(); // don't bother with getInterruptResponseMessage() // b is info about this link synchronized ( b ) { b.setHowProbe( probe.getSupportsHEAD() ); out.println( " reprobe: " + StatusKind.verboseStatusMessage( response, actualResponseMessage ) + ( b.useSNI() ? " sni" : "" ) + "\n" + b.toString() // with old status + "\n" ); b.setStatus( response ); } } break; case 3:/* use fetch */ { Fetch fetch = new Fetch(); fetch.setInstanceFollowRedirects( false ); fetch.send( url, Fetch.UTF8 ); final int response = fetch.getResponseCode(); final String actualResponseMessage = fetch.getResponseMessage(); // don't bother with getInterruptResponseMessage() synchronized ( b ) { out.println( " reprobe: " + StatusKind.verboseStatusMessage( response, actualResponseMessage ) + ( b.useSNI() ? " sni" : "" ) + "\n" + b.toString() + "\n" ); b.setStatus( response ); } break; } case 4: /* use File.exists() */ { // was file: // trim lead / final File file = new File( url.getFile().substring( 1 ) ); final int response = file.exists() ? BROKEN_LINKS_FILE_OK : BROKEN_LINKS_FILE_NOT_FOUND; synchronized ( b ) { out.println( " reprobe: " + StatusKind.terseStatusMessage( response ) + ( b.useSNI() ? " sni" : "" ) + "\n" + b.toString() + "\n" ); b.setStatus( response ); } break; } default: throw new IllegalArgumentException( "bad howProbe case" ); } } finally { if ( !DEBUGGING ) { semaphore.release(); } } } }