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
|
*.js.map
|
||||||
|
|
||||||
*.o
|
*.o
|
||||||
*.dylib
|
# *.dylib
|
||||||
*.a
|
*.a
|
||||||
*.so
|
# *.so
|
||||||
*.lib
|
*.lib
|
||||||
*.obj
|
*.obj
|
||||||
|
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -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 $@ $^
|
||||||
|
|
|
@ -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
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
|
@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) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
BIN
libangel_wings.dylib
Normal file
Binary file not shown.
|
@ -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
|
Loading…
Reference in a new issue