Almost done
This commit is contained in:
parent
18cb8749ee
commit
61fdef1df9
11 changed files with 82 additions and 36 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -21,9 +21,9 @@ doc/api/
|
|||
*.js.map
|
||||
|
||||
*.o
|
||||
*.dylib
|
||||
# *.dylib
|
||||
*.a
|
||||
*.so
|
||||
# *.so
|
||||
*.lib
|
||||
*.obj
|
||||
|
||||
|
|
2
Makefile
2
Makefile
|
@ -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 $@ $^
|
||||
|
|
|
@ -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
35
example/pretty_log.dart
Normal 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;
|
||||
}
|
BIN
lib/src/libangel_wings.dylib
Normal file
BIN
lib/src/libangel_wings.dylib
Normal file
Binary file not shown.
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
BIN
libangel_wings.dylib
Normal file
Binary file not shown.
|
@ -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
|
Loading…
Reference in a new issue