001/* 002 * ==================================================================== 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 * ==================================================================== 020 * 021 * This software consists of voluntary contributions made by many 022 * individuals on behalf of the Apache Software Foundation. For more 023 * information on the Apache Software Foundation, please see 024 * <http://www.apache.org/>. 025 * 026 */ 027package org.apache.http.impl.bootstrap; 028 029import java.io.IOException; 030import java.net.ServerSocket; 031import java.net.Socket; 032import java.util.concurrent.ExecutorService; 033import java.util.concurrent.atomic.AtomicBoolean; 034 035import org.apache.http.ExceptionLogger; 036import org.apache.http.HttpConnectionFactory; 037import org.apache.http.HttpServerConnection; 038import org.apache.http.config.SocketConfig; 039import org.apache.http.protocol.HttpService; 040 041/** 042 * @since 4.4 043 */ 044class RequestListener implements Runnable { 045 046 private final SocketConfig socketConfig; 047 private final ServerSocket serversocket; 048 private final HttpService httpService; 049 private final HttpConnectionFactory<? extends HttpServerConnection> connectionFactory; 050 private final ExceptionLogger exceptionLogger; 051 private final ExecutorService executorService; 052 private final AtomicBoolean terminated; 053 054 public RequestListener( 055 final SocketConfig socketConfig, 056 final ServerSocket serversocket, 057 final HttpService httpService, 058 final HttpConnectionFactory<? extends HttpServerConnection> connectionFactory, 059 final ExceptionLogger exceptionLogger, 060 final ExecutorService executorService) { 061 this.socketConfig = socketConfig; 062 this.serversocket = serversocket; 063 this.connectionFactory = connectionFactory; 064 this.httpService = httpService; 065 this.exceptionLogger = exceptionLogger; 066 this.executorService = executorService; 067 this.terminated = new AtomicBoolean(false); 068 } 069 070 @Override 071 public void run() { 072 try { 073 while (!isTerminated() && !Thread.interrupted()) { 074 final Socket socket = this.serversocket.accept(); 075 socket.setSoTimeout(this.socketConfig.getSoTimeout()); 076 socket.setKeepAlive(this.socketConfig.isSoKeepAlive()); 077 socket.setTcpNoDelay(this.socketConfig.isTcpNoDelay()); 078 if (this.socketConfig.getRcvBufSize() > 0) { 079 socket.setReceiveBufferSize(this.socketConfig.getRcvBufSize()); 080 } 081 if (this.socketConfig.getSndBufSize() > 0) { 082 socket.setSendBufferSize(this.socketConfig.getSndBufSize()); 083 } 084 if (this.socketConfig.getSoLinger() >= 0) { 085 socket.setSoLinger(true, this.socketConfig.getSoLinger()); 086 } 087 final HttpServerConnection conn = this.connectionFactory.createConnection(socket); 088 final Worker worker = new Worker(this.httpService, conn, this.exceptionLogger); 089 this.executorService.execute(worker); 090 } 091 } catch (final Exception ex) { 092 this.exceptionLogger.log(ex); 093 } 094 } 095 096 public boolean isTerminated() { 097 return this.terminated.get(); 098 } 099 100 public void terminate() throws IOException { 101 if (this.terminated.compareAndSet(false, true)) { 102 this.serversocket.close(); 103 } 104 } 105 106}