/* * RED5 Open Source Flash Server - http://code.google.com/p/red5/ * * Copyright 2006-2012 by respective authors (see below). All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.red5.server.net.servlet; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.util.EntityUtils; import org.apache.mina.core.buffer.IoBuffer; import org.red5.logging.Red5LoggerFactory; import org.red5.server.util.HttpConnectionUtil; import org.slf4j.Logger; /** * Servlet to tunnel to the AMF gateway servlet. * * @author The Red5 Project (red5@osflash.org) * @author Paul Gregoire (mondain@gmail.com) */ public class AMFTunnelServlet extends HttpServlet { private static final long serialVersionUID = -35436145164322090L; protected Logger log = Red5LoggerFactory.getLogger(AMFTunnelServlet.class); private static final String REQUEST_TYPE = "application/x-amf"; private static String postAcceptorURL = "http://localhost:8080/gateway"; private static int connectionTimeout = 30000; @Override public void init(ServletConfig config) throws ServletException { super.init(config); //get the url for posting if (config.getInitParameter("tunnel.acceptor.url") != null) { postAcceptorURL = config.getInitParameter("tunnel.acceptor.url"); } log.debug("POST acceptor URL: {}", postAcceptorURL); //get the connection timeout if (config.getInitParameter("tunnel.timeout") != null) { connectionTimeout = Integer.valueOf(config.getInitParameter("tunnel.timeout")); } log.debug("POST connection timeout: {}", postAcceptorURL); } /** * Redirect to HTTP port. */ @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { DefaultHttpClient client = HttpConnectionUtil.getClient(); client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, connectionTimeout); //setup POST HttpPost post = null; try { post = new HttpPost(postAcceptorURL); String path = req.getContextPath(); if (path == null) { path = ""; } log.debug("Path: {}", path); if (req.getPathInfo() != null) { path += req.getPathInfo(); } log.debug("Path 2: {}", path); int reqContentLength = req.getContentLength(); if (reqContentLength > 0) { log.debug("Request content length: {}", reqContentLength); IoBuffer reqBuffer = IoBuffer.allocate(reqContentLength); ServletUtils.copy(req.getInputStream(), reqBuffer.asOutputStream()); reqBuffer.flip(); post.setEntity(new InputStreamEntity(reqBuffer.asInputStream(), reqContentLength)); post.addHeader("Content-Type", REQUEST_TYPE); // get.setPath(path); post.addHeader("Tunnel-request", path); // execute the method HttpResponse response = client.execute(post); int code = response.getStatusLine().getStatusCode(); log.debug("HTTP response code: {}", code); if (code == HttpStatus.SC_OK) { HttpEntity entity = response.getEntity(); if (entity != null) { resp.setContentType(REQUEST_TYPE); // get the response as bytes byte[] bytes = EntityUtils.toByteArray(entity); IoBuffer resultBuffer = IoBuffer.wrap(bytes); resultBuffer.flip(); ServletUtils.copy(resultBuffer.asInputStream(), resp.getOutputStream()); resp.flushBuffer(); } } else { resp.sendError(code); } } else { resp.sendError(HttpStatus.SC_BAD_REQUEST); } } catch (Exception ex) { log.error("", ex); post.abort(); } } }