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
*.o
*.dylib
# *.dylib
*.a
*.so
# *.so
*.lib
*.obj

View file

@ -25,7 +25,7 @@ libangel_wings.dylib: lib/src/libangel_wings.dylib
lib/src/libangel_wings.dylib: $(objects)
%.dylib: $(objects)
$(CXX) -shared -undefined dynamic_lookup -o $@ $^
$(CXX) -shared -Wl,-undefined -Wl,dynamic_lookup -o $@ $^
%.so: $(objects)
$(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:file/local.dart';
import 'package:logging/logging.dart';
import 'pretty_log.dart';
main() async {
var app = Angel();
@ -10,17 +11,14 @@ main() async {
var fs = LocalFileSystem();
var vDir = CachingVirtualDirectory(app, fs,
source: fs.currentDirectory, allowDirectoryListing: true);
app.logger = Logger('wings')
..onRecord.listen((rec) {
print(rec);
if (rec.error != null) print(rec.error);
if (rec.stackTrace != null) print(rec.stackTrace);
});
app.logger = Logger('wings')..onRecord.listen(prettyLog);
app.mimeTypeResolver.addExtension('yaml', 'text/x-yaml');
app.get('/', (req, res) => 'WINGS!!!');
app.fallback(vDir.handleRequest);
app.fallback((req, res) => throw AngelHttpException.notFound());
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
Future<WingsRequestContext> createRequestContext(WingsClientSocket request, int response) {
Future<WingsRequestContext> createRequestContext(
WingsClientSocket request, int response) {
return WingsRequestContext.from(app, request);
}
@override
Future<WingsResponseContext> createResponseContext(WingsClientSocket request, int response,
Future<WingsResponseContext> createResponseContext(
WingsClientSocket request, int response,
[WingsRequestContext correspondingRequest]) {
return Future.value(WingsResponseContext(request.fileDescriptor, correspondingRequest));
return Future.value(WingsResponseContext(
app, request.fileDescriptor, correspondingRequest));
}
@override
@ -68,8 +71,9 @@ class AngelWings extends Driver<WingsClientSocket, int, WingsSocket,
}
@override
// TODO: implement uri
Uri get uri => null;
Uri get uri {
return Uri(scheme: 'http', host: server.address.address, port: server.port);
}
@override
void writeStringToResponse(int response, String value) {

View file

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

View file

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

View file

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

BIN
libangel_wings.dylib Normal file

Binary file not shown.

View file

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