Index: pkg/appengine/lib/src/api_impl/remote_api_impl.dart |
diff --git a/pkg/appengine/lib/src/api_impl/remote_api_impl.dart b/pkg/appengine/lib/src/api_impl/remote_api_impl.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cea978cff7ec404fa7f328509e7c71d147ae9051 |
--- /dev/null |
+++ b/pkg/appengine/lib/src/api_impl/remote_api_impl.dart |
@@ -0,0 +1,86 @@ |
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+library remote_api_impl; |
+ |
+import 'dart:async'; |
+import 'dart:io'; |
+import 'dart:convert' show UTF8, JSON; |
+ |
+import '../../api/errors.dart' as errors; |
+import '../../api/remote_api.dart' as remote_api; |
+import '../appengine_context.dart'; |
+ |
+import '../protobuf_api/rpc/rpc_service.dart'; |
+import '../protobuf_api/internal/remote_api.pb.dart' |
+ as pb; |
+ |
+class RemoteApiImpl extends remote_api.RemoteApi { |
+ static final TEXT_CONTENT_TYPE = |
+ new ContentType('text', 'plain', charset: 'utf-8'); |
+ static final JSON_CONTENT_TYPE = |
+ new ContentType('application', 'json', charset: 'utf-8'); |
+ static final BINARY_CONTENT_TYPE = |
+ new ContentType('application', 'octet-stream'); |
+ |
+ final RPCService _rpcService; |
+ final String _ticket; |
+ final AppengineContext _context; |
+ |
+ RemoteApiImpl(this._rpcService, this._context, this._ticket); |
+ |
+ Future handleRemoteApiRequest(HttpRequest httpRequest) { |
+ if (httpRequest.method == 'GET') { |
+ var rtok = httpRequest.uri.queryParameters['rtok']; |
+ if (rtok == null) rtok = '0'; |
+ var json = { |
+ 'app_id' : _context.fullQualifiedApplicationId, |
+ 'rtok' : rtok, |
+ }; |
+ return httpRequest.drain().then((_) { |
+ var data = UTF8.encode(JSON.encode(json)); |
+ return _sendData( |
+ httpRequest.response, HttpStatus.OK, JSON_CONTENT_TYPE, data); |
+ }); |
+ } else if (httpRequest.method == 'POST') { |
+ return httpRequest |
+ .fold(new BytesBuilder(), (buffer, data) => buffer..add(data)) |
+ .then((BytesBuilder result) { |
+ var request = new pb.Request.fromBuffer(result.takeBytes()); |
+ var response = new pb.Response(); |
+ return _rpcService.call(request.serviceName, request.method, |
+ request.request, ticket: _ticket) |
+ .then((result) { |
+ response.response = result; |
+ |
+ var data = response.writeToBuffer(); |
+ return _sendData( |
+ httpRequest.response, HttpStatus.OK, BINARY_CONTENT_TYPE, data); |
+ }).catchError((error) { |
+ response.applicationError = new pb.ApplicationError(); |
+ response.applicationError.code = error.code; |
+ response.applicationError.detail = error.message; |
+ |
+ var data = response.writeToBuffer(); |
+ return _sendData( |
+ httpRequest.response, HttpStatus.OK, BINARY_CONTENT_TYPE, data); |
+ }, test: (error) => error is RpcApplicationError) |
+ .then((_) => null); |
+ }); |
+ } else { |
+ return new Future.sync(() { |
+ throw new errors.ApplicationError( |
+ 'RemoteApi will only handle GET and POST requests.'); |
+ }); |
+ } |
+ } |
+ |
+ Future _sendData(response, statusCode, contentType, data) { |
+ response.statusCode = statusCode; |
+ response.headers.contentType = contentType; |
+ response.headers.contentLength = data.length; |
+ response.add(data); |
+ return response.close(); |
+ } |
+} |