LCOV - code coverage report
Current view: top level - lib/src/httpAdapters - wilt_server_http_adapter.dart (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 106 125 84.8 %
Date: 2017-07-19 Functions: 0 0 -

          Line data    Source code
       1             : /*
       2             :  * Packge : Wilt
       3             :  * Author : S. Hamblett <steve.hamblett@linux.com>
       4             :  * Date   : 04/06/2013
       5             :  * Copyright :  S.Hamblett@OSCF
       6             :  *
       7             :  * Browser(dart:html) CouchDB HTTP adapter for Wilt.
       8             :  *  
       9             :  * This always returns a JSON Object the format of which is documented in
      10             :  * the Result Interface document
      11             :  *                      
      12             :  */
      13             : 
      14             : part of wilt_server_client;
      15             : 
      16             : class WiltServerHTTPAdapter implements WiltHTTPAdapter {
      17             :   /// User for change notification authorization
      18             :   String _user;
      19             : 
      20             :   /// Password for change notification authorization
      21             :   String _password;
      22             : 
      23             :   /// Auth Type for change notification authorization
      24             :   String _authType;
      25             : 
      26             :   /// HTTP client
      27             :   http.Client _client;
      28             : 
      29             :   /// Construction
      30           1 :   WiltServerHTTPAdapter() {
      31           2 :     _client = new http.Client();
      32             :   }
      33             : 
      34             :   /// Processes the HTTP request, returning the server's response
      35             :   /// as a future
      36             :   Future<jsonobject.JsonObject> httpRequest(String method, String url,
      37             :       [String data = null, Map headers = null]) {
      38             :     /**
      39             :      *  Initialise
      40             :      */
      41           1 :     final Completer completer = new Completer();
      42             : 
      43             :     /// Successful completion
      44             :     void onSuccess(http.Response response) {
      45             :       /**
      46             :        *  Process the success response, note that an error response from CouchDB is
      47             :        *  treated as an error, not as a success with an 'error' field in it.
      48             :        */
      49           1 :       final jsonobject.JsonObject jsonResponse = new jsonobject.JsonObject();
      50           1 :       jsonResponse.error = false;
      51           1 :       jsonResponse.errorCode = 0;
      52           1 :       jsonResponse.successText = null;
      53           1 :       jsonResponse.errorText = null;
      54           1 :       jsonResponse.allResponseHeader = null;
      55           1 :       jsonResponse.method = method;
      56           2 :       jsonResponse.responseText = response.body;
      57             : 
      58             :       /**
      59             :        * Check the header, if application/json try and decode it,
      60             :        * otherwise its just raw data, ie an attachment.
      61             :        */
      62           2 :       if (response.headers.containsValue('application/json')) {
      63             :         var couchResp;
      64             :         try {
      65           2 :           couchResp = JSON.decode(response.body);
      66             :         } catch (e) {
      67           1 :           jsonResponse.error = true;
      68           1 :           final jsonobject.JsonObject errorAsJson = new jsonobject.JsonObject();
      69           1 :           errorAsJson.error = "JSON Decode Error";
      70           1 :           errorAsJson.reason = "None";
      71           1 :           jsonResponse.jsonCouchResponse = errorAsJson;
      72             :           /* Set the response headers */
      73           2 :           jsonResponse.allResponseHeaders = response.headers;
      74             :           /**
      75             :             * Complete the request
      76             :             */
      77           2 :           if (!completer.isCompleted) completer.complete(jsonResponse);
      78             :         }
      79             : 
      80           2 :         if ((couchResp is Map) && (couchResp.containsKey('error'))) {
      81           1 :           jsonResponse.error = true;
      82           1 :           final jsonobject.JsonObject errorAsJson = new jsonobject.JsonObject();
      83           1 :           errorAsJson.error = "CouchDb Error";
      84           2 :           errorAsJson.reason = couchResp['reason'];
      85           1 :           jsonResponse.jsonCouchResponse = errorAsJson;
      86             :           /* Set the response headers */
      87           2 :           jsonResponse.allResponseHeaders = response.headers;
      88             :           /**
      89             :            * Complete the request
      90             :            */
      91           2 :           if (!completer.isCompleted) completer.complete(jsonResponse);
      92             :         }
      93             : 
      94             :         /**
      95             :          * Success response
      96             :          */
      97           1 :         if (method != Wilt.headd) {
      98             :           final jsonobject.JsonObject successAsJson =
      99           2 :               new jsonobject.JsonObject.fromJsonString(response.body);
     100           1 :           jsonResponse.jsonCouchResponse = successAsJson;
     101             :         }
     102             :       } else {
     103           1 :         final jsonobject.JsonObject successAsJson = new jsonobject.JsonObject();
     104           1 :         successAsJson.ok = true;
     105           3 :         successAsJson.contentType = response.headers['content-type'];
     106           1 :         jsonResponse.jsonCouchResponse = successAsJson;
     107             :       }
     108             : 
     109             :       /* Set the response headers */
     110           2 :       jsonResponse.allResponseHeaders = response.headers;
     111             :       /**
     112             :        * Complete the request
     113             :        */
     114           2 :       if (!completer.isCompleted) completer.complete(jsonResponse);
     115             :     }
     116             : 
     117             :     /// Successful completion for Copy
     118             :     void onCopySuccess(http.StreamedResponse response) {
     119             :       /**
     120             :        *  Process the success response, note that an error response from CouchDB is
     121             :        *  treated as an error, not as a success with an 'error' field in it.
     122             :        */
     123           1 :       final jsonobject.JsonObject jsonResponse = new jsonobject.JsonObject();
     124           1 :       jsonResponse.error = false;
     125           1 :       jsonResponse.errorCode = 0;
     126           1 :       jsonResponse.successText = null;
     127           1 :       jsonResponse.errorText = null;
     128           1 :       jsonResponse.allResponseHeader = null;
     129           1 :       jsonResponse.method = method;
     130           3 :       response.stream.bytesToString(UTF8).then((String text) {
     131           1 :         jsonResponse.responseText = text;
     132             : 
     133             :         /**
     134             :            * Check the header, if application/json try and decode it,
     135             :            * otherwise its just raw data, ie an attachment.
     136             :            */
     137           2 :         if (response.headers.containsValue('application/json')) {
     138             :           var couchResp;
     139             :           try {
     140           1 :             couchResp = JSON.decode(text);
     141             :           } catch (e) {
     142           0 :             jsonResponse.error = true;
     143             :             final jsonobject.JsonObject errorAsJson =
     144           0 :                 new jsonobject.JsonObject();
     145           0 :             errorAsJson.error = "JSON Decode Error";
     146           0 :             errorAsJson.reason = "None";
     147           0 :             jsonResponse.jsonCouchResponse = errorAsJson;
     148             :             /* Set the response headers */
     149           0 :             jsonResponse.allResponseHeaders = response.headers;
     150             :             /**
     151             :                 * Complete the request
     152             :                 */
     153           0 :             if (!completer.isCompleted) completer.complete(jsonResponse);
     154             :           }
     155             : 
     156           2 :           if ((couchResp is Map) && (couchResp.containsKey('error'))) {
     157           0 :             jsonResponse.error = true;
     158             :             final jsonobject.JsonObject errorAsJson =
     159           0 :                 new jsonobject.JsonObject();
     160           0 :             errorAsJson.error = "CouchDb Error";
     161           0 :             errorAsJson.reason = couchResp['reason'];
     162           0 :             jsonResponse.jsonCouchResponse = errorAsJson;
     163             :             /* Set the response headers */
     164           0 :             jsonResponse.allResponseHeaders = response.headers;
     165             :             /**
     166             :                * Complete the reequest
     167             :                */
     168           0 :             if (!completer.isCompleted) completer.complete(jsonResponse);
     169             :           }
     170             : 
     171             :           /**
     172             :              * Success response
     173             :              */
     174           1 :           if (method != Wilt.headd) {
     175             :             final jsonobject.JsonObject successAsJson =
     176           1 :                 new jsonobject.JsonObject.fromJsonString(text);
     177           1 :             jsonResponse.jsonCouchResponse = successAsJson;
     178             :           }
     179             :         } else {
     180             :           final jsonobject.JsonObject successAsJson =
     181           0 :               new jsonobject.JsonObject();
     182           0 :           successAsJson.ok = true;
     183           0 :           successAsJson.contentType = response.headers['content-type'];
     184           0 :           jsonResponse.jsonCouchResponse = successAsJson;
     185             :         }
     186             : 
     187             :         /* Set the response headers */
     188           2 :         jsonResponse.allResponseHeaders = response.headers;
     189             : 
     190             :         /**
     191             :          * Complete the request
     192             :         */
     193           2 :         if (!completer.isCompleted) completer.complete(jsonResponse);
     194             :       });
     195             :     }
     196             : 
     197             :     /// Error completion
     198             :     void onError(http.ClientException response) {
     199             :       /* Process the error response */
     200           1 :       final jsonobject.JsonObject jsonResponse = new jsonobject.JsonObject();
     201           1 :       jsonResponse.method = method;
     202           1 :       jsonResponse.error = true;
     203           1 :       jsonResponse.successText = null;
     204           1 :       jsonResponse.errorCode = 0;
     205           1 :       final jsonobject.JsonObject errorAsJson = new jsonobject.JsonObject();
     206           1 :       errorAsJson.error = "Invalid HTTP response";
     207           2 :       errorAsJson.reason = response.message;
     208           1 :       jsonResponse.jsonCouchResponse = errorAsJson;
     209             : 
     210             :       /**
     211             :        * Complete the request
     212             :        */
     213           2 :       if (!completer.isCompleted) completer.complete(jsonResponse);
     214             :     }
     215             : 
     216             :     /**
     217             :      * Condition the input method string to get the HTTP method
     218             :      */
     219           1 :     final List temp = method.split('_');
     220           1 :     final String httpMethod = temp[0];
     221             : 
     222             :     /**
     223             :      * Set the content type header correctly
     224             :      */
     225           1 :     if (headers.containsKey('Content-Type')) {
     226           1 :       final String contentType = headers['Content-Type'];
     227           1 :       headers.remove('Content-Type');
     228           1 :       headers['content-type'] = contentType;
     229             :     }
     230             :     /**
     231             :      *  Query CouchDB over HTTP
     232             :      */
     233           1 :     if (httpMethod == "GET") {
     234           3 :       _client.get(url, headers: headers).then(onSuccess, onError: onError);
     235           1 :     } else if (httpMethod == "PUT") {
     236           1 :       _client
     237           1 :           .put(url, headers: headers, body: data)
     238           1 :           .then(onSuccess, onError: onError);
     239           1 :     } else if (httpMethod == "POST") {
     240           1 :       _client
     241           1 :           .post(url, headers: headers, body: data)
     242           1 :           .then(onSuccess, onError: onError);
     243           1 :     } else if (httpMethod == "HEAD") {
     244           3 :       _client.head(url, headers: headers).then(onSuccess, onError: onError);
     245           1 :     } else if (httpMethod == "DELETE") {
     246           3 :       _client.delete(url, headers: headers).then(onSuccess, onError: onError);
     247           1 :     } else if (httpMethod == "COPY") {
     248           1 :       final Uri encodedUrl = Uri.parse(url);
     249           1 :       final request = new http.Request("COPY", encodedUrl);
     250           2 :       request.headers.addAll(headers);
     251           3 :       _client.send(request).then(onCopySuccess, onError: onError);
     252             :     }
     253             : 
     254           1 :     return completer.future;
     255             :   }
     256             : 
     257             :   /// Specialised 'get' for change notifications
     258             :   Future<String> getString(String url) {
     259           1 :     final Completer completer = new Completer<String>();
     260             : 
     261             :     /* Must have authentication */
     262           1 :     final Map wiltHeaders = new Map<String, String>();
     263           1 :     wiltHeaders["Accept"] = "application/json";
     264           1 :     if (_user != null) {
     265           1 :       switch (_authType) {
     266           1 :         case Wilt.authBasic:
     267           3 :           final String authStringToEncode = "$_user:$_password";
     268             :           final String encodedAuthString =
     269           2 :               CryptoUtils.bytesToBase64(authStringToEncode.codeUnits);
     270           1 :           final String authString = "Basic $encodedAuthString";
     271           1 :           wiltHeaders['Authorization'] = authString;
     272             :           break;
     273             : 
     274           0 :         case Wilt.authNone:
     275             :           break;
     276             :       }
     277             :     }
     278             : 
     279           3 :     _client.get(url, headers: wiltHeaders).then((response) {
     280           2 :       completer.complete(response.body);
     281             :     });
     282             : 
     283           1 :     return completer.future;
     284             :   }
     285             : 
     286             :   /// Authentication parameters for change notification
     287             :   void notificationAuthParams(String user, String password, String authType) {
     288           1 :     _user = user;
     289           1 :     _password = password;
     290           1 :     _authType = authType;
     291             :   }
     292             : }

Generated by: LCOV version 1.10