Package ch.ethz.inf.vs.californium.resources.proxy

Source Code of ch.ethz.inf.vs.californium.resources.proxy.ProxyHttpClientResource

package ch.ethz.inf.vs.californium.resources.proxy;


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;

import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.protocol.RequestAcceptEncoding;
import org.apache.http.client.protocol.ResponseContentEncoding;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.RequestConnControl;
import org.apache.http.protocol.RequestDate;
import org.apache.http.protocol.RequestExpectContinue;
import org.apache.http.protocol.RequestTargetHost;
import org.apache.http.protocol.RequestUserAgent;

import ch.ethz.inf.vs.californium.coap.CoAP.ResponseCode;
import ch.ethz.inf.vs.californium.coap.Request;
import ch.ethz.inf.vs.californium.coap.Response;

/**
* // test with http://httpbin.org/
*
* @author Francesco Corazza
*
*/
public class ProxyHttpClientResource extends ForwardingResource {
 
  private static final int KEEP_ALIVE = 5000;
  // TODO: Properties.std.getInt("HTTP_CLIENT_KEEP_ALIVE");
 
  /**
   * DefaultHttpClient is thread safe. It is recommended that the same
   * instance of this class is reused for multiple request executions.
   */
  private static final AbstractHttpClient HTTP_CLIENT = new DefaultHttpClient();

  // http client static configuration
  static {
    // request interceptors
    HTTP_CLIENT.addRequestInterceptor(new RequestAcceptEncoding());
    HTTP_CLIENT.addRequestInterceptor(new RequestConnControl());
    // HTTP_CLIENT.addRequestInterceptor(new RequestContent());
    HTTP_CLIENT.addRequestInterceptor(new RequestDate());
    HTTP_CLIENT.addRequestInterceptor(new RequestExpectContinue());
    HTTP_CLIENT.addRequestInterceptor(new RequestTargetHost());
    HTTP_CLIENT.addRequestInterceptor(new RequestUserAgent());

    // response intercptors
    HTTP_CLIENT.addResponseInterceptor(new ResponseContentEncoding());

    HTTP_CLIENT.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy() {
      @Override
      public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
        long keepAlive = super.getKeepAliveDuration(response, context);
        if (keepAlive == -1) {
          // Keep connections alive if a keep-alive value
          // has not be explicitly set by the server
          keepAlive = KEEP_ALIVE;
        }
        return keepAlive;
      }

    });
  }

  public ProxyHttpClientResource() {
    // set the resource hidden
//    this("proxy/httpClient");
    this("httpClient");
  }

  public ProxyHttpClientResource(String name) {
    // set the resource hidden
    super(name, true);
    getAttributes().setTitle("Forward the requests to a HTTP client.");
  }

  @Override
  public Response forwardRequest(Request request) {
    final Request incomingCoapRequest = request;
   
    // check the invariant: the request must have the proxy-uri set
    if (!incomingCoapRequest.getOptions().hasProxyURI()) {
      LOGGER.warning("Proxy-uri option not set.");
      return new Response(ResponseCode.BAD_OPTION);
    }

    // remove the fake uri-path // TODO: why? still necessary in new Cf?
    incomingCoapRequest.getOptions().clearURIPaths();; // HACK

    // get the proxy-uri set in the incoming coap request
    URI proxyUri;
    try {
      String proxyUriString = URLDecoder.decode(
          incomingCoapRequest.getOptions().getProxyURI(), "UTF-8");
      proxyUri = new URI(proxyUriString);
    } catch (UnsupportedEncodingException e) {
      LOGGER.warning("Proxy-uri option malformed: " + e.getMessage());
      return new Response(CoapTranslator.STATUS_FIELD_MALFORMED);
    } catch (URISyntaxException e) {
      LOGGER.warning("Proxy-uri option malformed: " + e.getMessage());
      return new Response(CoapTranslator.STATUS_FIELD_MALFORMED);
    }

    // get the requested host, if the port is not specified, the constructor
    // sets it to -1
    HttpHost httpHost = new HttpHost(proxyUri.getHost(), proxyUri.getPort(), proxyUri.getScheme());

    HttpRequest httpRequest = null;
    try {
      // get the mapping to http for the incoming coap request
      httpRequest = HttpTranslator.getHttpRequest(incomingCoapRequest);
      LOGGER.finer("Outgoing http request: " + httpRequest.getRequestLine());
    } catch (InvalidFieldException e) {
      LOGGER.warning("Problems during the http/coap translation: " + e.getMessage());
      return new Response(CoapTranslator.STATUS_FIELD_MALFORMED);
    } catch (TranslationException e) {
      LOGGER.warning("Problems during the http/coap translation: " + e.getMessage());
      return new Response(CoapTranslator.STATUS_TRANSLATION_ERROR);
    }

    ResponseHandler<Response> httpResponseHandler = new ResponseHandler<Response>() {
      @Override
      public Response handleResponse(HttpResponse httpResponse) throws ClientProtocolException, IOException {
        long timestamp = System.nanoTime();
        LOGGER.finer("Incoming http response: " + httpResponse.getStatusLine());
        // the entity of the response, if non repeatable, could be
        // consumed only one time, so do not debug it!
        // System.out.println(EntityUtils.toString(httpResponse.getEntity()));

        // translate the received http response in a coap response
        try {
          Response coapResponse = HttpTranslator.getCoapResponse(httpResponse, incomingCoapRequest);
          coapResponse.setTimestamp(timestamp);
          return coapResponse;
        } catch (InvalidFieldException e) {
          LOGGER.warning("Problems during the http/coap translation: " + e.getMessage());
          return new Response(CoapTranslator.STATUS_FIELD_MALFORMED);
        } catch (TranslationException e) {
          LOGGER.warning("Problems during the http/coap translation: " + e.getMessage());
          return new Response(CoapTranslator.STATUS_TRANSLATION_ERROR);
        }
      }
    };

    // accept the request sending a separate response to avoid the timeout
    // in the requesting client
    LOGGER.finer("Acknowledge message sent");

    Response coapResponse = null;
    try {
      // execute the request
      coapResponse = HTTP_CLIENT.execute(httpHost, httpRequest, httpResponseHandler, null);
    } catch (IOException e) {
      LOGGER.warning("Failed to get the http response: " + e.getMessage());
      return new Response(ResponseCode.INTERNAL_SERVER_ERROR);
    }

    return coapResponse;
  }
}
TOP

Related Classes of ch.ethz.inf.vs.californium.resources.proxy.ProxyHttpClientResource

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.