package jenkins.slaves; import hudson.Extension; import org.jenkinsci.Symbol; import org.jenkinsci.remoting.engine.JnlpServerHandshake; import org.jenkinsci.remoting.nio.NioChannelHub; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.Socket; /** * {@link JnlpSlaveAgentProtocol} Version 2. * * <p> * This protocol extends the version 1 protocol by adding a per-client cookie, * so that we can detect a reconnection from the agent and take appropriate action, * when the connection disappeared without the master noticing. * * @author Kohsuke Kawaguchi * @since 1.467 */ @Extension @Symbol("jnlp2") public class JnlpSlaveAgentProtocol2 extends JnlpSlaveAgentProtocol { @Override public String getName() { return "JNLP2-connect"; } /** * {@inheritDoc} */ @Override public boolean isOptIn() { return false; } /** * {@inheritDoc} */ @Override public String getDisplayName() { return Messages.JnlpSlaveAgentProtocol2_displayName(); } @Override public void handle(Socket socket) throws IOException, InterruptedException { new Handler2(hub.getHub(),socket).run(); } protected static class Handler2 extends Handler { /** * @deprecated as of 1.559 * Use {@link #Handler2(NioChannelHub, Socket)} */ @Deprecated public Handler2(Socket socket) throws IOException { super(socket); } public Handler2(NioChannelHub hub, Socket socket) throws IOException { super(hub, socket); } /** * Handles JNLP agent connection request (v2 protocol) */ @Override protected void run() throws IOException, InterruptedException { request.load(new ByteArrayInputStream(in.readUTF().getBytes("UTF-8"))); final String nodeName = request.getProperty("Node-Name"); for (JnlpAgentReceiver recv : JnlpAgentReceiver.all()) { try { if (recv.handle(nodeName,this)) return; } catch (AbstractMethodError e) { if (recv.handle(nodeName,new JnlpSlaveHandshake(this))) return; } } error("JNLP2-connect: rejected connection for node: " + nodeName); } } }