Package org.openhab.ui.internal.proxy

Source Code of org.openhab.ui.internal.proxy.ProxyServlet

/**
* Copyright (c) 2010-2014, openHAB.org and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.ui.internal.proxy;

import java.io.IOException;
import java.net.URI;
import java.util.Hashtable;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.io.IOUtils;
import org.openhab.io.net.http.SecureHttpContext;
import org.openhab.model.core.ModelRepository;
import org.openhab.model.sitemap.Image;
import org.openhab.model.sitemap.Sitemap;
import org.openhab.model.sitemap.Video;
import org.openhab.model.sitemap.Webview;
import org.openhab.model.sitemap.Widget;
import org.openhab.ui.items.ItemUIRegistry;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The proxy servlet is used by image and video widgets. As its name suggests, it proxies the content, so
* that it is possible to include resources (images/videos) from the LAN in the openHAB UI. This is
* especially useful for webcams as you would not want to make them directly available to the internet.
*
* The servlet registers as "/proxy" and expects the two parameters "sitemap" and "widgetId". It will
* hence provide the data of the url specified in the according widget. Note that it does NOT allow
* general access to any servers in the LAN - only urls that are specified in a sitemap are accessible.
*
* It is also possible to use credentials in a url, e.g. "http://user:pwd@localserver/image.jpg" -
* the proxy servlet will be able to access the content and provide it to the openHAB UIs through the
* standard openHAB authentication mechanism (if enabled).
*
* This servlet also supports data streams, such as a webcam video stream etc.
*
* @author Kai Kreuzer
* @since 1.3.0
*/
public class ProxyServlet extends HttpServlet {

  /** the alias for this servlet */
  public static final String PROXY_ALIAS = "proxy";

  private static final Logger logger = LoggerFactory.getLogger(ProxyServlet.class);

  private static final long serialVersionUID = -4716754591953017793L;
 
  protected HttpService httpService;
  protected ItemUIRegistry itemUIRegistry;
  protected ModelRepository modelRepository;
 
  protected void setItemUIRegistry(ItemUIRegistry itemUIRegistry) {
    this.itemUIRegistry = itemUIRegistry;
  }

  protected void unsetItemUIRegistry(ItemUIRegistry itemUIRegistry) {
    this.itemUIRegistry = null;
  }

  protected void setModelRepository(ModelRepository modelRepository) {
    this.modelRepository = modelRepository;
  }

  protected void unsetModelRepository(ModelRepository modelRepository) {
    this.modelRepository = null;
  }

  protected void setHttpService(HttpService httpService) {
    this.httpService = httpService;
  }

  protected void unsetHttpService(HttpService httpService) {
    this.httpService = null;
  }

  protected void activate() {
    try {
      logger.debug("Starting up proxy servlet at /" + PROXY_ALIAS);

      Hashtable<String, String> props = new Hashtable<String, String>();
      httpService.registerServlet("/" + PROXY_ALIAS, this, props, createHttpContext());
    } catch (NamespaceException e) {
      logger.error("Error during servlet startup: {}", e.getMessage());
    } catch (ServletException e) {
      logger.error("Error during servlet startup: {}", e.getMessage());
    }
  }

  protected void deactivate() {
    httpService.unregister("/" + PROXY_ALIAS);
  }

  /**
   * Creates a {@link SecureHttpContext} which handles the security for this servlet 
   * @return a {@link SecureHttpContext}
   */
  protected HttpContext createHttpContext() {
    HttpContext defaultHttpContext = httpService.createDefaultHttpContext();
    return new SecureHttpContext(defaultHttpContext, "openHAB.org");
  }
 
 
  @Override
  public String getServletInfo() {
    return "Image and Video Widget Proxy";
  }

  @Override
  protected void doGet(HttpServletRequest request,
      HttpServletResponse response) throws ServletException, IOException {
    String sitemapName = request.getParameter("sitemap");
    String widgetId = request.getParameter("widgetId");
    String baseUrl = request.getParameter("baseUrl");

    if(sitemapName == null) {
      throw new ServletException("Parameter 'sitemap' must be provided!");
    }
    if(widgetId == null) {
      throw new ServletException("Parameter 'widgetId' must be provided!");
    }
    if(baseUrl == null) {
      baseUrl = "";
    }
    String uriString = null;
   
    Sitemap sitemap = (Sitemap) modelRepository.getModel(sitemapName);
    if(sitemap!=null) {
      Widget widget = itemUIRegistry.getWidget(sitemap, widgetId);
      if(widget instanceof Image) {
        Image image = (Image) widget;
        uriString = baseUrl + image.getUrl();
      } else if(widget instanceof Video) {
        Video video = (Video) widget;
        uriString = baseUrl + video.getUrl();
      } else if(widget instanceof Webview) {
        Webview webview = (Webview) widget;
        uriString = baseUrl + webview.getUrl();
      } else {
        if(widget==null) {
          throw new ServletException("Widget '" + widgetId + "' could not be found!");
        } else {
          throw new ServletException("Widget type '" + widget.getClass().getName() + "' is not supported!");
        }
      }
    } else {
      throw new ServletException("Sitemap '" + sitemapName + "' could not be found!");
    }

    HttpClient httpClient = new HttpClient();

    try {
      // check if the uri uses credentials and configure the http client accordingly
      URI uri = URI.create(uriString);
     
      if(uri.getUserInfo()!=null) {
        String[] userInfo = uri.getUserInfo().split(":");
        httpClient.getParams().setAuthenticationPreemptive(true);
        Credentials creds = new UsernamePasswordCredentials(userInfo[0], userInfo[1]);
        httpClient.getState().setCredentials(new AuthScope(uri.getHost(), uri.getPort(), AuthScope.ANY_REALM), creds);
      }
    } catch(IllegalArgumentException e) {
      throw new ServletException("URI '" + uriString + "' is not valid: " + e.getMessage());
    }
   
    // do the client request
    GetMethod method = new GetMethod(uriString);
    httpClient.executeMethod(method);
   
    // copy all headers
    for(Header header : method.getResponseHeaders()) {
      response.setHeader(header.getName(), header.getValue());
    }
   
    // now copy/stream the body content
    IOUtils.copy(method.getResponseBodyAsStream(), response.getOutputStream());
    method.releaseConnection();
  }
}
TOP

Related Classes of org.openhab.ui.internal.proxy.ProxyServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.