Home | History | Annotate | Download | only in util
      1 /*
      2  *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 package org.appspot.apprtc.util;
     12 
     13 import java.io.IOException;
     14 import java.io.InputStream;
     15 import java.io.OutputStream;
     16 import java.net.HttpURLConnection;
     17 import java.net.SocketTimeoutException;
     18 import java.net.URL;
     19 import java.util.Scanner;
     20 
     21 /**
     22  * Asynchronous http requests implementation.
     23  */
     24 public class AsyncHttpURLConnection {
     25   private static final int HTTP_TIMEOUT_MS = 8000;
     26   private static final String HTTP_ORIGIN = "https://apprtc.appspot.com";
     27   private final String method;
     28   private final String url;
     29   private final String message;
     30   private final AsyncHttpEvents events;
     31   private String contentType;
     32 
     33   /**
     34    * Http requests callbacks.
     35    */
     36   public interface AsyncHttpEvents {
     37     public void onHttpError(String errorMessage);
     38     public void onHttpComplete(String response);
     39   }
     40 
     41   public AsyncHttpURLConnection(String method, String url, String message,
     42       AsyncHttpEvents events) {
     43     this.method = method;
     44     this.url = url;
     45     this.message = message;
     46     this.events = events;
     47   }
     48 
     49   public void setContentType(String contentType) {
     50     this.contentType = contentType;
     51   }
     52 
     53   public void send() {
     54     Runnable runHttp = new Runnable() {
     55       public void run() {
     56         sendHttpMessage();
     57       }
     58     };
     59     new Thread(runHttp).start();
     60   }
     61 
     62   private void sendHttpMessage() {
     63     try {
     64       HttpURLConnection connection =
     65         (HttpURLConnection) new URL(url).openConnection();
     66       byte[] postData = new byte[0];
     67       if (message != null) {
     68         postData = message.getBytes("UTF-8");
     69       }
     70       connection.setRequestMethod(method);
     71       connection.setUseCaches(false);
     72       connection.setDoInput(true);
     73       connection.setConnectTimeout(HTTP_TIMEOUT_MS);
     74       connection.setReadTimeout(HTTP_TIMEOUT_MS);
     75       // TODO(glaznev) - query request origin from pref_room_server_url_key preferences.
     76       connection.addRequestProperty("origin", HTTP_ORIGIN);
     77       boolean doOutput = false;
     78       if (method.equals("POST")) {
     79         doOutput = true;
     80         connection.setDoOutput(true);
     81         connection.setFixedLengthStreamingMode(postData.length);
     82       }
     83       if (contentType == null) {
     84         connection.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
     85       } else {
     86         connection.setRequestProperty("Content-Type", contentType);
     87       }
     88 
     89       // Send POST request.
     90       if (doOutput && postData.length > 0) {
     91         OutputStream outStream = connection.getOutputStream();
     92         outStream.write(postData);
     93         outStream.close();
     94       }
     95 
     96       // Get response.
     97       int responseCode = connection.getResponseCode();
     98       if (responseCode != 200) {
     99         events.onHttpError("Non-200 response to " + method + " to URL: "
    100             + url + " : " + connection.getHeaderField(null));
    101         connection.disconnect();
    102         return;
    103       }
    104       InputStream responseStream = connection.getInputStream();
    105       String response = drainStream(responseStream);
    106       responseStream.close();
    107       connection.disconnect();
    108       events.onHttpComplete(response);
    109     } catch (SocketTimeoutException e) {
    110       events.onHttpError("HTTP " + method + " to " + url + " timeout");
    111     } catch (IOException e) {
    112       events.onHttpError("HTTP " + method + " to " + url + " error: "
    113           + e.getMessage());
    114     }
    115   }
    116 
    117   // Return the contents of an InputStream as a String.
    118   private static String drainStream(InputStream in) {
    119     Scanner s = new Scanner(in).useDelimiter("\\A");
    120     return s.hasNext() ? s.next() : "";
    121   }
    122 }
    123