Almost done

This commit is contained in:
Tobe O 2019-04-30 13:40:11 -04:00
parent 18cb8749ee
commit 61fdef1df9
11 changed files with 82 additions and 36 deletions

4
.gitignore vendored
View file

@ -21,9 +21,9 @@ doc/api/
*.js.map *.js.map
*.o *.o
*.dylib # *.dylib
*.a *.a
*.so # *.so
*.lib *.lib
*.obj *.obj

View file

@ -25,7 +25,7 @@ libangel_wings.dylib: lib/src/libangel_wings.dylib
lib/src/libangel_wings.dylib: $(objects) lib/src/libangel_wings.dylib: $(objects)
%.dylib: $(objects) %.dylib: $(objects)
$(CXX) -shared -undefined dynamic_lookup -o $@ $^ $(CXX) -shared -Wl,-undefined -Wl,dynamic_lookup -o $@ $^
%.so: $(objects) %.so: $(objects)
$(CXX) -shared -o $@ $^ $(CXX) -shared -o $@ $^

View file

@ -3,6 +3,7 @@ import 'package:angel_static/angel_static.dart';
import 'package:angel_wings/angel_wings.dart'; import 'package:angel_wings/angel_wings.dart';
import 'package:file/local.dart'; import 'package:file/local.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'pretty_log.dart';
main() async { main() async {
var app = Angel(); var app = Angel();
@ -10,17 +11,14 @@ main() async {
var fs = LocalFileSystem(); var fs = LocalFileSystem();
var vDir = CachingVirtualDirectory(app, fs, var vDir = CachingVirtualDirectory(app, fs,
source: fs.currentDirectory, allowDirectoryListing: true); source: fs.currentDirectory, allowDirectoryListing: true);
app.logger = Logger('wings')
..onRecord.listen((rec) { app.logger = Logger('wings')..onRecord.listen(prettyLog);
print(rec); app.mimeTypeResolver.addExtension('yaml', 'text/x-yaml');
if (rec.error != null) print(rec.error);
if (rec.stackTrace != null) print(rec.stackTrace);
});
app.get('/', (req, res) => 'WINGS!!!'); app.get('/', (req, res) => 'WINGS!!!');
app.fallback(vDir.handleRequest); app.fallback(vDir.handleRequest);
app.fallback((req, res) => throw AngelHttpException.notFound()); app.fallback((req, res) => throw AngelHttpException.notFound());
await wings.startServer('127.0.0.1', 3000); await wings.startServer('127.0.0.1', 3000);
print('Listening at http://localhost:3000'); print('Listening at ${wings.uri}');
} }

35
example/pretty_log.dart Normal file
View file

@ -0,0 +1,35 @@
import 'package:angel_http_exception/angel_http_exception.dart';
import 'package:logging/logging.dart';
import 'package:io/ansi.dart';
/// Prints the contents of a [LogRecord] with pretty colors.
void prettyLog(LogRecord record) {
var code = chooseLogColor(record.level);
if (record.error == null) print(code.wrap(record.toString()));
if (record.error != null) {
var err = record.error;
if (err is AngelHttpException && err.statusCode != 500) return;
print(code.wrap(record.toString() + '\n'));
print(code.wrap(err.toString()));
if (record.stackTrace != null) {
print(code.wrap(record.stackTrace.toString()));
}
}
}
/// Chooses a color based on the logger [level].
AnsiCode chooseLogColor(Level level) {
if (level == Level.SHOUT)
return backgroundRed;
else if (level == Level.SEVERE)
return red;
else if (level == Level.WARNING)
return yellow;
else if (level == Level.INFO)
return cyan;
else if (level == Level.FINER || level == Level.FINEST) return lightGray;
return resetAll;
}

Binary file not shown.

View file

@ -31,14 +31,17 @@ class AngelWings extends Driver<WingsClientSocket, int, WingsSocket,
} }
@override @override
Future<WingsRequestContext> createRequestContext(WingsClientSocket request, int response) { Future<WingsRequestContext> createRequestContext(
WingsClientSocket request, int response) {
return WingsRequestContext.from(app, request); return WingsRequestContext.from(app, request);
} }
@override @override
Future<WingsResponseContext> createResponseContext(WingsClientSocket request, int response, Future<WingsResponseContext> createResponseContext(
WingsClientSocket request, int response,
[WingsRequestContext correspondingRequest]) { [WingsRequestContext correspondingRequest]) {
return Future.value(WingsResponseContext(request.fileDescriptor, correspondingRequest)); return Future.value(WingsResponseContext(
app, request.fileDescriptor, correspondingRequest));
} }
@override @override
@ -68,8 +71,9 @@ class AngelWings extends Driver<WingsClientSocket, int, WingsSocket,
} }
@override @override
// TODO: implement uri Uri get uri {
Uri get uri => null; return Uri(scheme: 'http', host: server.address.address, port: server.port);
}
@override @override
void writeStringToResponse(int response, String value) { void writeStringToResponse(int response, String value) {

View file

@ -28,6 +28,11 @@ class WingsRequestContext extends RequestContext<WingsClientSocket> {
WingsRequestContext._(this.app, this.rawRequest, this._recv) WingsRequestContext._(this.app, this.rawRequest, this._recv)
: container = app.container.createChild(); : container = app.container.createChild();
Future<void> close() async {
await _body.close();
_recv.close();
}
static const int DELETE = 0, static const int DELETE = 0,
GET = 1, GET = 1,
HEAD = 2, HEAD = 2,
@ -106,18 +111,19 @@ class WingsRequestContext extends RequestContext<WingsClientSocket> {
if (e == 0) { if (e == 0) {
state = _ParseState.method; state = _ParseState.method;
} else { } else {
lastHeader = e as String; lastHeader = e as String; //Uri.decodeFull(e as String);
state = _ParseState.headerValue; state = _ParseState.headerValue;
} }
} else if (state == _ParseState.headerValue) { } else if (state == _ParseState.headerValue) {
if (e == 0) { if (e == 0) {
state = _ParseState.method; state = _ParseState.method;
} else { } else {
var value = e as String; //Uri.decodeFull(e as String);
if (lastHeader != null) { if (lastHeader != null) {
if (lastHeader == 'cookie') { if (lastHeader == 'cookie') {
rq.__cookies.add(Cookie.fromSetCookieValue(e as String)); rq.__cookies.add(Cookie.fromSetCookieValue(value));
} else { } else {
rq._headers.add(lastHeader, e as String); rq._headers.add(lastHeader, value);
} }
lastHeader = null; lastHeader = null;
} }

View file

@ -8,6 +8,9 @@ import 'wings_request.dart';
import 'wings_socket.dart'; import 'wings_socket.dart';
class WingsResponseContext extends ResponseContext<int> { class WingsResponseContext extends ResponseContext<int> {
@override
final Angel app;
@override @override
final WingsRequestContext correspondingRequest; final WingsRequestContext correspondingRequest;
@ -18,7 +21,7 @@ class WingsResponseContext extends ResponseContext<int> {
bool _isDetached = false, _isClosed = false, _streamInitialized = false; bool _isDetached = false, _isClosed = false, _streamInitialized = false;
WingsResponseContext(this.rawResponse, [this.correspondingRequest]); WingsResponseContext(this.app, this.rawResponse, [this.correspondingRequest]);
Iterable<String> __allowedEncodings; Iterable<String> __allowedEncodings;
@ -78,8 +81,9 @@ class WingsResponseContext extends ResponseContext<int> {
} }
void _wh(String k, String v) { void _wh(String k, String v) {
var headerLine = // var vv =Uri.encodeComponent(v);
utf8.encode('$k: ${Uri.encodeComponent(v)}').followedBy([$cr, $lf]); var vv = v;
var headerLine = utf8.encode('$k: $vv').followedBy([$cr, $lf]);
writeToNativeSocket( writeToNativeSocket(
rawResponse, Uint8List.fromList(headerLine.toList())); rawResponse, Uint8List.fromList(headerLine.toList()));
} }
@ -127,6 +131,7 @@ class WingsResponseContext extends ResponseContext<int> {
} }
return output.forEach((buf) { return output.forEach((buf) {
if (!_isClosed)
writeToNativeSocket( writeToNativeSocket(
rawResponse, buf is Uint8List ? buf : Uint8List.fromList(buf)); rawResponse, buf is Uint8List ? buf : Uint8List.fromList(buf));
}); });
@ -168,27 +173,21 @@ class WingsResponseContext extends ResponseContext<int> {
} }
@override @override
Future close() { Future close() async {
if (!_isDetached) { if (!_isDetached) {
if (!_isClosed) { if (!_isClosed) {
_isClosed = true;
if (!isBuffered) { if (!isBuffered) {
try {
_openStream(); _openStream();
closeNativeSocketDescriptor(rawResponse); closeNativeSocketDescriptor(rawResponse);
} catch (_) {
// This only seems to occur on `MockHttpRequest`, but
// this try/catch prevents a crash.
}
} else { } else {
_buffer.lock(); _buffer.lock();
} }
_isClosed = true;
} }
super.close(); await correspondingRequest?.close();
await super.close();
} }
return new Future.value();
} }
@override @override

View file

@ -44,6 +44,7 @@ class WingsClientSocket {
class WingsSocket extends Stream<WingsClientSocket> { class WingsSocket extends Stream<WingsClientSocket> {
final StreamController<WingsClientSocket> _ctrl = StreamController(); final StreamController<WingsClientSocket> _ctrl = StreamController();
SendPort _acceptor; SendPort _acceptor;
InternetAddress _address;
final int _pointer; final int _pointer;
final RawReceivePort _recv; final RawReceivePort _recv;
bool _open = true; bool _open = true;
@ -91,13 +92,15 @@ class WingsSocket extends Stream<WingsClientSocket> {
addr.address, port, shared, backlog, v6Only, recv.sendPort); addr.address, port, shared, backlog, v6Only, recv.sendPort);
} }
return WingsSocket._(ptr, recv); return WingsSocket._(ptr, recv).._address = addr;
} catch (e) { } catch (e) {
recv.close(); recv.close();
rethrow; rethrow;
} }
} }
InternetAddress get address => _address;
int get port => _port ??= getWingsServerSocketPort(_pointer); int get port => _port ??= getWingsServerSocketPort(_pointer);
@override @override

BIN
libangel_wings.dylib Normal file

Binary file not shown.

View file

@ -8,4 +8,5 @@ dependencies:
dev_dependencies: dev_dependencies:
angel_static: ^2.0.0 angel_static: ^2.0.0
build_runner: ^1.0.0 build_runner: ^1.0.0
io: ^0.3.2
pedantic: ^1.0.0 pedantic: ^1.0.0