1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package org.apache.jmeter.protocol.http.control; 20 21 import java.io.InterruptedIOException; 22 import java.net.ServerSocket; 23 import java.net.Socket; 24 25 import org.apache.jorphan.logging.LoggingManager; 26 import org.apache.jorphan.util.JOrphanUtils; 27 import org.apache.log.Logger; 28 29 /** 30 * Server daemon thread. 31 * Creates main socket and listens on it. 32 * For each client request, creates a thread to handle the request. 33 * 34 */ 35 public class HttpMirrorServer extends Thread { 36 private static final Logger log = LoggingManager.getLoggerForClass(); 37 38 /** 39 * The time (in milliseconds) to wait when accepting a client connection. 40 * The accept will be retried until the Daemon is told to stop. So this 41 * interval is the longest time that the Daemon will have to wait after 42 * being told to stop. 43 */ 44 private static final int ACCEPT_TIMEOUT = 1000; 45 46 /** The port to listen on. */ 47 private final int daemonPort; 48 49 /** True if the Daemon is currently running. */ 50 private volatile boolean running; 51 52 // Saves the error if one occurs 53 private volatile Exception except; 54 55 /** 56 * Create a new Daemon with the specified port and target. 57 * 58 * @param port 59 * the port to listen on. 60 */ 61 public HttpMirrorServer(int port) { 62 super("HttpMirrorServer"); 63 this.daemonPort = port; 64 } 65 66 /** 67 * Listen on the daemon port and handle incoming requests. This method will 68 * not exit until {@link #stopServer()} is called or an error occurs. 69 */ 70 public void run() { 71 except = null; 72 running = true; 73 ServerSocket mainSocket = null; 74 75 try { 76 log.info("Creating HttpMirror ... on port " + daemonPort); 77 mainSocket = new ServerSocket(daemonPort); 78 mainSocket.setSoTimeout(ACCEPT_TIMEOUT); 79 log.info("HttpMirror up and running!"); 80 81 while (running) { 82 try { 83 // Listen on main socket 84 Socket clientSocket = mainSocket.accept(); 85 if (running) { 86 // Pass request to new thread 87 HttpMirrorThread thd = new HttpMirrorThread(clientSocket); 88 log.info("Starting new Mirror thread"); 89 thd.start(); 90 } else { 91 log.warn("Server not running"); 92 JOrphanUtils.closeQuietly(clientSocket); 93 } 94 } catch (InterruptedIOException e) { 95 // Timeout occurred. Ignore, and keep looping until we're 96 // told to stop running. 97 } 98 } 99 log.info("HttpMirror Server stopped"); 100 } catch (Exception e) { 101 except = e; 102 log.warn("HttpMirror Server stopped", e); 103 } finally { 104 JOrphanUtils.closeQuietly(mainSocket); 105 } 106 } 107 108 public void stopServer() { 109 running = false; 110 } 111 112 public Exception getException(){ 113 return except; 114 } 115 116 public static void main(String args[]){ 117 int port = 8080; 118 if (args.length > 0){ 119 port = Integer.parseInt(args[0]); 120 } 121 HttpMirrorServer serv = new HttpMirrorServer(port); 122 serv.start(); 123 } 124 }