Added default logging
This commit is contained in:
parent
6d2be10536
commit
ff65e13c75
12 changed files with 85 additions and 144 deletions
|
@ -1,5 +1,17 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## 6.0.0
|
||||||
|
|
||||||
|
* Updated to min SDK 2.15.x
|
||||||
|
|
||||||
|
## 5.0.0
|
||||||
|
|
||||||
|
* Skipped release
|
||||||
|
|
||||||
|
## 4.0.0
|
||||||
|
|
||||||
|
* Skipped release
|
||||||
|
|
||||||
## 3.0.1
|
## 3.0.1
|
||||||
|
|
||||||
* Updated `package:angel3_container`
|
* Updated `package:angel3_container`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io' show stderr, Cookie;
|
import 'dart:io' show Cookie;
|
||||||
import 'package:angel3_http_exception/angel3_http_exception.dart';
|
import 'package:angel3_http_exception/angel3_http_exception.dart';
|
||||||
import 'package:angel3_route/angel3_route.dart';
|
import 'package:angel3_route/angel3_route.dart';
|
||||||
import 'package:belatuk_combinator/belatuk_combinator.dart';
|
import 'package:belatuk_combinator/belatuk_combinator.dart';
|
||||||
|
@ -20,10 +20,6 @@ abstract class Driver<
|
||||||
final Angel app;
|
final Angel app;
|
||||||
final bool useZone;
|
final bool useZone;
|
||||||
bool _closed = false;
|
bool _closed = false;
|
||||||
late Server _server;
|
|
||||||
|
|
||||||
// TODO: Ugly fix
|
|
||||||
bool isServerInitialised = false;
|
|
||||||
|
|
||||||
StreamSubscription<Request>? _sub;
|
StreamSubscription<Request>? _sub;
|
||||||
//final log = Logger('Driver');
|
//final log = Logger('Driver');
|
||||||
|
@ -37,14 +33,7 @@ abstract class Driver<
|
||||||
Uri get uri;
|
Uri get uri;
|
||||||
|
|
||||||
/// The native server running this instance.
|
/// The native server running this instance.
|
||||||
Server? get server {
|
Server? server;
|
||||||
// TODO: Ugly fix
|
|
||||||
if (isServerInitialised) {
|
|
||||||
return _server;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Server> generateServer(address, int port) =>
|
Future<Server> generateServer(address, int port) =>
|
||||||
serverGenerator(address, port);
|
serverGenerator(address, port);
|
||||||
|
@ -53,24 +42,21 @@ abstract class Driver<
|
||||||
Future<Server> startServer([address, int port = 0]) {
|
Future<Server> startServer([address, int port = 0]) {
|
||||||
var host = address ?? '127.0.0.1';
|
var host = address ?? '127.0.0.1';
|
||||||
return generateServer(host, port).then((server) {
|
return generateServer(host, port).then((server) {
|
||||||
_server = server;
|
this.server = server;
|
||||||
|
|
||||||
// TODO: Ugly fix
|
|
||||||
isServerInitialised = true;
|
|
||||||
|
|
||||||
return Future.wait(app.startupHooks.map(app.configure)).then((_) {
|
return Future.wait(app.startupHooks.map(app.configure)).then((_) {
|
||||||
app.optimizeForProduction();
|
app.optimizeForProduction();
|
||||||
_sub = server.listen((request) {
|
_sub = this.server?.listen((request) {
|
||||||
var stream = createResponseStreamFromRawRequest(request);
|
var stream = createResponseStreamFromRawRequest(request);
|
||||||
stream.listen((response) {
|
stream.listen((response) {
|
||||||
// TODO: To be revisited
|
// TODO: To be revisited
|
||||||
handleRawRequest(request, response);
|
handleRawRequest(request, response);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return Future.value(_server);
|
return Future.value(this.server!);
|
||||||
});
|
});
|
||||||
}).catchError((error) {
|
}).catchError((error) {
|
||||||
app.logger?.severe('Failed to create server', error);
|
app.logger.severe('Failed to create server', error);
|
||||||
throw ArgumentError('[Driver]Failed to create server');
|
throw ArgumentError('[Driver]Failed to create server');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -163,7 +149,7 @@ abstract class Driver<
|
||||||
..registerSingleton<ParseResult<RouteResult>?>(tuple.item3)
|
..registerSingleton<ParseResult<RouteResult>?>(tuple.item3)
|
||||||
..registerSingleton<ParseResult?>(tuple.item3);
|
..registerSingleton<ParseResult?>(tuple.item3);
|
||||||
|
|
||||||
if (!app.environment.isProduction && app.logger != null) {
|
if (!app.environment.isProduction) {
|
||||||
req.container?.registerSingleton<Stopwatch>(Stopwatch()..start());
|
req.container?.registerSingleton<Stopwatch>(Stopwatch()..start());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,22 +190,16 @@ abstract class Driver<
|
||||||
message: ee?.toString() ?? '500 Internal Server Error');
|
message: ee?.toString() ?? '500 Internal Server Error');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app.logger != null) {
|
var error = e.error ?? e;
|
||||||
var error = e.error ?? e;
|
var trace = Trace.from(StackTrace.current).terse;
|
||||||
var trace = Trace.from(StackTrace.current).terse;
|
app.logger.severe(e.message, error, trace);
|
||||||
app.logger?.severe(e.message, error, trace);
|
|
||||||
}
|
|
||||||
|
|
||||||
return handleAngelHttpException(e, st, req, res, request, response);
|
return handleAngelHttpException(e, st, req, res, request, response);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var zoneSpec = ZoneSpecification(
|
var zoneSpec = ZoneSpecification(
|
||||||
print: (self, parent, zone, line) {
|
print: (self, parent, zone, line) {
|
||||||
if (app.logger != null) {
|
app.logger.info(line);
|
||||||
app.logger?.info(line);
|
|
||||||
} else {
|
|
||||||
parent.print(zone, line);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
handleUncaughtError: (self, parent, zone, error, stackTrace) {
|
handleUncaughtError: (self, parent, zone, error, stackTrace) {
|
||||||
var trace = Trace.from(stackTrace).terse;
|
var trace = Trace.from(stackTrace).terse;
|
||||||
|
@ -237,9 +217,7 @@ abstract class Driver<
|
||||||
stackTrace: stackTrace, message: error.toString());
|
stackTrace: stackTrace, message: error.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app.logger != null) {
|
app.logger.severe(e.message, error, trace);
|
||||||
app.logger?.severe(e.message, error, trace);
|
|
||||||
}
|
|
||||||
|
|
||||||
return handleAngelHttpException(
|
return handleAngelHttpException(
|
||||||
e, trace, req, res, request, response);
|
e, trace, req, res, request, response);
|
||||||
|
@ -248,23 +226,15 @@ abstract class Driver<
|
||||||
closeResponse(response);
|
closeResponse(response);
|
||||||
// Ideally, we won't be in a position where an absolutely fatal error occurs,
|
// Ideally, we won't be in a position where an absolutely fatal error occurs,
|
||||||
// but if so, we'll need to log it.
|
// but if so, we'll need to log it.
|
||||||
if (app.logger != null) {
|
app.logger.severe(
|
||||||
app.logger!.severe(
|
'Fatal error occurred when processing $uri.', e, trace);
|
||||||
'Fatal error occurred when processing $uri.', e, trace);
|
|
||||||
} else {
|
|
||||||
stderr
|
|
||||||
..writeln('Fatal error occurred when processing '
|
|
||||||
'${req.uri}:')
|
|
||||||
..writeln(e)
|
|
||||||
..writeln(trace);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
var zone = Zone.current.fork(specification: zoneSpec);
|
var zone = Zone.current.fork(specification: zoneSpec);
|
||||||
req.container!.registerSingleton<Zone>(zone);
|
req.container?.registerSingleton<Zone>(zone);
|
||||||
req.container!.registerSingleton<ZoneSpecification>(zoneSpec);
|
req.container?.registerSingleton<ZoneSpecification>(zoneSpec);
|
||||||
|
|
||||||
// If a synchronous error is thrown, it's not caught by `zone.run`,
|
// If a synchronous error is thrown, it's not caught by `zone.run`,
|
||||||
// so use a try/catch, and recover when need be.
|
// so use a try/catch, and recover when need be.
|
||||||
|
@ -291,12 +261,12 @@ abstract class Driver<
|
||||||
{bool ignoreFinalizers = false}) {
|
{bool ignoreFinalizers = false}) {
|
||||||
if (req == null || res == null) {
|
if (req == null || res == null) {
|
||||||
try {
|
try {
|
||||||
app.logger?.severe('500 Internal Server Error', e, st);
|
app.logger.severe('500 Internal Server Error', e, st);
|
||||||
setStatusCode(response, 500);
|
setStatusCode(response, 500);
|
||||||
writeStringToResponse(response, '500 Internal Server Error');
|
writeStringToResponse(response, '500 Internal Server Error');
|
||||||
closeResponse(response);
|
closeResponse(response);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
app.logger?.severe('500 Internal Server Error', e);
|
app.logger.severe('500 Internal Server Error', e);
|
||||||
}
|
}
|
||||||
return Future.value();
|
return Future.value();
|
||||||
}
|
}
|
||||||
|
@ -322,11 +292,9 @@ abstract class Driver<
|
||||||
ResponseContext res,
|
ResponseContext res,
|
||||||
{bool ignoreFinalizers = false}) {
|
{bool ignoreFinalizers = false}) {
|
||||||
Future<void> _cleanup(_) {
|
Future<void> _cleanup(_) {
|
||||||
if (!app.environment.isProduction &&
|
if (!app.environment.isProduction && req.container!.has<Stopwatch>()) {
|
||||||
app.logger != null &&
|
|
||||||
req.container!.has<Stopwatch>()) {
|
|
||||||
var sw = req.container!.make<Stopwatch>();
|
var sw = req.container!.make<Stopwatch>();
|
||||||
app.logger?.info(
|
app.logger.info(
|
||||||
"${res.statusCode} ${req.method} ${req.uri} (${sw.elapsedMilliseconds} ms)");
|
"${res.statusCode} ${req.method} ${req.uri} (${sw.elapsedMilliseconds} ms)");
|
||||||
}
|
}
|
||||||
return req.close();
|
return req.close();
|
||||||
|
|
|
@ -9,7 +9,6 @@ import 'dart:typed_data';
|
||||||
import 'package:angel3_route/angel3_route.dart';
|
import 'package:angel3_route/angel3_route.dart';
|
||||||
import 'package:file/file.dart';
|
import 'package:file/file.dart';
|
||||||
import 'package:http_parser/http_parser.dart';
|
import 'package:http_parser/http_parser.dart';
|
||||||
import 'package:logging/logging.dart';
|
|
||||||
import 'package:mime/mime.dart';
|
import 'package:mime/mime.dart';
|
||||||
|
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
|
@ -25,7 +24,7 @@ abstract class ResponseContext<RawResponse>
|
||||||
final CaseInsensitiveMap<String> _headers = CaseInsensitiveMap<String>.from(
|
final CaseInsensitiveMap<String> _headers = CaseInsensitiveMap<String>.from(
|
||||||
{'content-type': 'text/plain', 'server': 'Angel3'});
|
{'content-type': 'text/plain', 'server': 'Angel3'});
|
||||||
|
|
||||||
final log = Logger('ResponseContext');
|
//final log = Logger('ResponseContext');
|
||||||
|
|
||||||
Completer? _done;
|
Completer? _done;
|
||||||
int _statusCode = 200;
|
int _statusCode = 200;
|
||||||
|
@ -351,7 +350,7 @@ abstract class ResponseContext<RawResponse>
|
||||||
if (stackTrace != null) {
|
if (stackTrace != null) {
|
||||||
Zone.current.handleUncaughtError(error, stackTrace);
|
Zone.current.handleUncaughtError(error, stackTrace);
|
||||||
} else {
|
} else {
|
||||||
log.warning('[ResponseContext] stackTrace is null');
|
app?.logger.warning('[ResponseContext] stackTrace is null');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,11 @@ RequestHandler chain(Iterable<RequestHandler> handlers) {
|
||||||
class Routable extends Router<RequestHandler> {
|
class Routable extends Router<RequestHandler> {
|
||||||
final Map<Pattern, Service> _services = {};
|
final Map<Pattern, Service> _services = {};
|
||||||
final Map<Pattern, Service?> _serviceLookups = {};
|
final Map<Pattern, Service?> _serviceLookups = {};
|
||||||
|
|
||||||
|
/// A [Map] of application-specific data that can be accessed.
|
||||||
|
///
|
||||||
|
/// Packages like `package:angel3_configuration` populate this map
|
||||||
|
/// for you.
|
||||||
final Map configuration = {};
|
final Map configuration = {};
|
||||||
|
|
||||||
final Container _container;
|
final Container _container;
|
||||||
|
|
|
@ -55,6 +55,18 @@ Future<bool> _defaultErrorHandler(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger _defaultLogger() {
|
||||||
|
Logger logger = Logger('SERVER')
|
||||||
|
//..level = Level.WARNING
|
||||||
|
..onRecord.listen((rec) {
|
||||||
|
print(rec);
|
||||||
|
if (rec.error != null) print(rec.error);
|
||||||
|
if (rec.stackTrace != null) print(rec.stackTrace);
|
||||||
|
});
|
||||||
|
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
/// A powerful real-time/REST/MVC server class.
|
/// A powerful real-time/REST/MVC server class.
|
||||||
class Angel extends Routable {
|
class Angel extends Routable {
|
||||||
static Future<String> _noViewEngineConfigured(String view, [Map? data]) =>
|
static Future<String> _noViewEngineConfigured(String view, [Map? data]) =>
|
||||||
|
@ -99,19 +111,6 @@ class Angel extends Routable {
|
||||||
/// A set of [Controller] objects that have been loaded into the application.
|
/// A set of [Controller] objects that have been loaded into the application.
|
||||||
Map<Pattern, Controller> get controllers => _controllers;
|
Map<Pattern, Controller> get controllers => _controllers;
|
||||||
|
|
||||||
/// Now *deprecated*, in favor of [AngelEnv] and [angelEnv]. Use `app.environment.isProduction`
|
|
||||||
/// instead.
|
|
||||||
///
|
|
||||||
/// Indicates whether the application is running in a production environment.
|
|
||||||
///
|
|
||||||
/// The criteria for this is the `ANGEL_ENV` environment variable being set to
|
|
||||||
/// `'production'`.
|
|
||||||
///
|
|
||||||
/// This value is memoized the first time you call it, so do not change environment
|
|
||||||
/// configuration at runtime!
|
|
||||||
//@deprecated
|
|
||||||
//bool get isProduction => environment.isProduction;
|
|
||||||
|
|
||||||
/// The [AngelEnvironment] in which the application is running.
|
/// The [AngelEnvironment] in which the application is running.
|
||||||
///
|
///
|
||||||
/// By default, it is automatically inferred.
|
/// By default, it is automatically inferred.
|
||||||
|
@ -121,7 +120,7 @@ class Angel extends Routable {
|
||||||
Angel? get parent => _parent;
|
Angel? get parent => _parent;
|
||||||
|
|
||||||
/// Outputs diagnostics and debug messages.
|
/// Outputs diagnostics and debug messages.
|
||||||
Logger? logger;
|
Logger logger = _defaultLogger();
|
||||||
|
|
||||||
/// Plug-ins to be called right before server startup.
|
/// Plug-ins to be called right before server startup.
|
||||||
///
|
///
|
||||||
|
@ -138,14 +137,6 @@ class Angel extends Routable {
|
||||||
/// These will only not run if a response's `willCloseItself` is set to `true`.
|
/// These will only not run if a response's `willCloseItself` is set to `true`.
|
||||||
final List<RequestHandler> responseFinalizers = [];
|
final List<RequestHandler> responseFinalizers = [];
|
||||||
|
|
||||||
/// A [Map] of application-specific data that can be accessed by any
|
|
||||||
/// piece of code that can see this [Angel] instance.
|
|
||||||
///
|
|
||||||
/// Packages like `package:angel3_configuration` populate this map
|
|
||||||
/// for you.
|
|
||||||
@override
|
|
||||||
final Map configuration = {};
|
|
||||||
|
|
||||||
/// A function that renders views.
|
/// A function that renders views.
|
||||||
///
|
///
|
||||||
/// Called by [ResponseContext]@`render`.
|
/// Called by [ResponseContext]@`render`.
|
||||||
|
@ -158,11 +149,10 @@ class Angel extends Routable {
|
||||||
Route<RequestHandler> addRoute(
|
Route<RequestHandler> addRoute(
|
||||||
String method, String path, RequestHandler handler,
|
String method, String path, RequestHandler handler,
|
||||||
{Iterable<RequestHandler> middleware = const []}) {
|
{Iterable<RequestHandler> middleware = const []}) {
|
||||||
//middleware ??= [];
|
|
||||||
if (_flattened != null) {
|
if (_flattened != null) {
|
||||||
logger?.warning(
|
logger.warning(
|
||||||
'WARNING: You added a route ($method $path) to the router, after it had been optimized.');
|
'WARNING: You added a route ($method $path) to the router, after it had been optimized.');
|
||||||
logger?.warning(
|
logger.warning(
|
||||||
'This route will be ignored, and no requests will ever reach it.');
|
'This route will be ignored, and no requests will ever reach it.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,9 +163,9 @@ class Angel extends Routable {
|
||||||
SymlinkRoute<RequestHandler> mount(
|
SymlinkRoute<RequestHandler> mount(
|
||||||
String path, Router<RequestHandler> router) {
|
String path, Router<RequestHandler> router) {
|
||||||
if (_flattened != null) {
|
if (_flattened != null) {
|
||||||
logger?.warning(
|
logger.warning(
|
||||||
'WARNING: You added mounted a child router ($path) on the router, after it had been optimized.');
|
'WARNING: You added mounted a child router ($path) on the router, after it had been optimized.');
|
||||||
logger?.warning(
|
logger.warning(
|
||||||
'This route will be ignored, and no requests will ever reach it.');
|
'This route will be ignored, and no requests will ever reach it.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +192,7 @@ class Angel extends Routable {
|
||||||
///
|
///
|
||||||
/// The server will be **COMPLETELY DEFUNCT** after this operation!
|
/// The server will be **COMPLETELY DEFUNCT** after this operation!
|
||||||
@override
|
@override
|
||||||
Future close() {
|
Future<void> close() {
|
||||||
Future.forEach(services.values, (Service service) {
|
Future.forEach(services.values, (Service service) {
|
||||||
service.close();
|
service.close();
|
||||||
});
|
});
|
||||||
|
@ -212,14 +202,13 @@ class Angel extends Routable {
|
||||||
_preContained.clear();
|
_preContained.clear();
|
||||||
handlerCache.clear();
|
handlerCache.clear();
|
||||||
encoders.clear();
|
encoders.clear();
|
||||||
//_serializer = json.encode;
|
|
||||||
_children.clear();
|
_children.clear();
|
||||||
_parent = null;
|
//_parent = null;
|
||||||
logger = null;
|
//logger = null;
|
||||||
|
//_flattened = null;
|
||||||
startupHooks.clear();
|
startupHooks.clear();
|
||||||
shutdownHooks.clear();
|
shutdownHooks.clear();
|
||||||
responseFinalizers.clear();
|
responseFinalizers.clear();
|
||||||
_flattened = null;
|
|
||||||
return Future.value();
|
return Future.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +301,7 @@ class Angel extends Routable {
|
||||||
void optimizeForProduction({bool force = false}) {
|
void optimizeForProduction({bool force = false}) {
|
||||||
if (environment.isProduction || force == true) {
|
if (environment.isProduction || force == true) {
|
||||||
_flattened ??= flatten(this);
|
_flattened ??= flatten(this);
|
||||||
logger?.info('Angel is running in production mode.');
|
logger.info('Angel is running in production mode.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,16 +380,21 @@ class Angel extends Routable {
|
||||||
{Reflector reflector =
|
{Reflector reflector =
|
||||||
const ThrowingReflector(errorMessage: _reflectionErrorMessage),
|
const ThrowingReflector(errorMessage: _reflectionErrorMessage),
|
||||||
this.environment = angelEnv,
|
this.environment = angelEnv,
|
||||||
this.logger,
|
Logger? logger,
|
||||||
this.allowMethodOverrides = true,
|
this.allowMethodOverrides = true,
|
||||||
this.serializer,
|
this.serializer,
|
||||||
this.viewGenerator})
|
this.viewGenerator})
|
||||||
: super(reflector) {
|
: super(reflector) {
|
||||||
|
// Override default logger
|
||||||
|
if (logger != null) {
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
if (reflector is EmptyReflector || reflector is ThrowingReflector) {
|
if (reflector is EmptyReflector || reflector is ThrowingReflector) {
|
||||||
var msg =
|
var msg =
|
||||||
'No `reflector` was passed to the Angel constructor, so reflection will not be available.\n' +
|
'No `reflector` was passed to the Angel constructor, so reflection will not be available.\n' +
|
||||||
_reflectionInfo;
|
_reflectionInfo;
|
||||||
logger?.warning(msg);
|
this.logger.warning(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrapContainer();
|
bootstrapContainer();
|
||||||
|
|
|
@ -103,15 +103,10 @@ class AngelHttp extends Driver<HttpRequest, HttpResponse, HttpServer,
|
||||||
Future<HttpResponseContext> createResponseContext(
|
Future<HttpResponseContext> createResponseContext(
|
||||||
HttpRequest request, HttpResponse response,
|
HttpRequest request, HttpResponse response,
|
||||||
[HttpRequestContext? correspondingRequest]) {
|
[HttpRequestContext? correspondingRequest]) {
|
||||||
// TODO: Refactored to overcome NNBD migration error
|
|
||||||
var context = HttpResponseContext(response, app, correspondingRequest);
|
var context = HttpResponseContext(response, app, correspondingRequest);
|
||||||
context.serializer = (app.serializer ?? json.encode);
|
context.serializer = (app.serializer ?? json.encode);
|
||||||
context.encoders.addAll(app.encoders);
|
context.encoders.addAll(app.encoders);
|
||||||
return Future<HttpResponseContext>.value(context);
|
return Future<HttpResponseContext>.value(context);
|
||||||
// return Future<HttpResponseContext>.value(
|
|
||||||
// HttpResponseContext(response, app, correspondingRequest)
|
|
||||||
// ..serializer = (app.serializer ?? json.encode)
|
|
||||||
// ..encoders.addAll(app.encoders ?? {}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -24,7 +24,7 @@ class HttpRequestContext extends RequestContext<HttpRequest?> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Cookie> get cookies {
|
List<Cookie> get cookies {
|
||||||
return rawRequest!.cookies;
|
return rawRequest?.cookies ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -51,7 +51,7 @@ class HttpRequestContext extends RequestContext<HttpRequest?> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get originalMethod {
|
String get originalMethod {
|
||||||
return rawRequest!.method;
|
return rawRequest?.method ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -61,17 +61,18 @@ class HttpRequestContext extends RequestContext<HttpRequest?> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
InternetAddress get remoteAddress {
|
InternetAddress get remoteAddress {
|
||||||
return rawRequest!.connectionInfo!.remoteAddress;
|
return rawRequest?.connectionInfo?.remoteAddress ??
|
||||||
|
InternetAddress("127.0.0.1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
HttpSession get session {
|
HttpSession? get session {
|
||||||
return rawRequest!.session;
|
return rawRequest?.session;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Uri get uri {
|
Uri get uri {
|
||||||
return rawRequest!.uri;
|
return rawRequest?.uri ?? Uri();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Magically transforms an [HttpRequest] into a [RequestContext].
|
/// Magically transforms an [HttpRequest] into a [RequestContext].
|
||||||
|
@ -92,35 +93,6 @@ class HttpRequestContext extends RequestContext<HttpRequest?> {
|
||||||
? MediaType('text', 'plain')
|
? MediaType('text', 'plain')
|
||||||
: MediaType.parse(request.headers.contentType.toString());
|
: MediaType.parse(request.headers.contentType.toString());
|
||||||
ctx._override = override;
|
ctx._override = override;
|
||||||
|
|
||||||
/*
|
|
||||||
// Faster way to get path
|
|
||||||
List<int> _path = [];
|
|
||||||
|
|
||||||
// Go up until we reach a ?
|
|
||||||
for (int ch in request.uri.toString().codeUnits) {
|
|
||||||
if (ch != $question)
|
|
||||||
_path.add(ch);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove trailing slashes
|
|
||||||
int lastSlash = -1;
|
|
||||||
|
|
||||||
for (int i = _path.length - 1; i >= 0; i--) {
|
|
||||||
if (_path[i] == $slash)
|
|
||||||
lastSlash = i;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastSlash > -1)
|
|
||||||
ctx._path = String.fromCharCodes(_path.take(lastSlash));
|
|
||||||
else
|
|
||||||
ctx._path = String.fromCharCodes(_path);
|
|
||||||
*/
|
|
||||||
|
|
||||||
ctx._path = path;
|
ctx._path = path;
|
||||||
ctx._io = request;
|
ctx._io = request;
|
||||||
|
|
||||||
|
|
|
@ -13,15 +13,15 @@ class HttpResponseContext extends ResponseContext<HttpResponse> {
|
||||||
@override
|
@override
|
||||||
final HttpResponse rawResponse;
|
final HttpResponse rawResponse;
|
||||||
|
|
||||||
@override
|
|
||||||
Angel? app;
|
|
||||||
|
|
||||||
LockableBytesBuilder? _buffer;
|
LockableBytesBuilder? _buffer;
|
||||||
|
|
||||||
final HttpRequestContext? _correspondingRequest;
|
final HttpRequestContext? _correspondingRequest;
|
||||||
bool _isDetached = false, _isClosed = false, _streamInitialized = false;
|
bool _isDetached = false, _isClosed = false, _streamInitialized = false;
|
||||||
|
|
||||||
HttpResponseContext(this.rawResponse, this.app, [this._correspondingRequest]);
|
HttpResponseContext(this.rawResponse, Angel? app,
|
||||||
|
[this._correspondingRequest]) {
|
||||||
|
this.app = app;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
HttpResponse detach() {
|
HttpResponse detach() {
|
||||||
|
|
|
@ -80,7 +80,7 @@ class AngelHttp2 extends Driver<Socket, ServerTransportStream,
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
await _artificial!.close();
|
await _artificial?.close();
|
||||||
await _http.close();
|
await _http.close();
|
||||||
return await super.close();
|
return await super.close();
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ class _AngelHttp2ServerSocket extends Stream<SecureSocket>
|
||||||
},
|
},
|
||||||
onDone: _ctrl.close,
|
onDone: _ctrl.close,
|
||||||
onError: (e, st) {
|
onError: (e, st) {
|
||||||
driver.app.logger!.warning(
|
driver.app.logger.warning(
|
||||||
'HTTP/2 incoming connection failure: ', e, st as StackTrace);
|
'HTTP/2 incoming connection failure: ', e, st as StackTrace);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,9 +6,6 @@ import 'package:http2/transport.dart';
|
||||||
import 'http2_request_context.dart';
|
import 'http2_request_context.dart';
|
||||||
|
|
||||||
class Http2ResponseContext extends ResponseContext<ServerTransportStream> {
|
class Http2ResponseContext extends ResponseContext<ServerTransportStream> {
|
||||||
@override
|
|
||||||
final Angel? app;
|
|
||||||
|
|
||||||
final ServerTransportStream stream;
|
final ServerTransportStream stream;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -25,8 +22,9 @@ class Http2ResponseContext extends ResponseContext<ServerTransportStream> {
|
||||||
|
|
||||||
Uri? _targetUri;
|
Uri? _targetUri;
|
||||||
|
|
||||||
Http2ResponseContext(this.app, this.stream, this._req) {
|
Http2ResponseContext(Angel? app, this.stream, this._req) {
|
||||||
_targetUri = _req!.uri;
|
this.app = app;
|
||||||
|
_targetUri = _req?.uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Http2ResponseContext> _pushes = [];
|
final List<Http2ResponseContext> _pushes = [];
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io' show BytesBuilder;
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:angel3_container/mirrors.dart';
|
import 'package:angel3_container/mirrors.dart';
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io' show stderr;
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:angel3_container/mirrors.dart';
|
import 'package:angel3_container/mirrors.dart';
|
||||||
|
@ -92,7 +91,7 @@ void main() {
|
||||||
test('cannot write after close', () async {
|
test('cannot write after close', () async {
|
||||||
try {
|
try {
|
||||||
var rq = MockHttpRequest('GET', Uri.parse('/overwrite'));
|
var rq = MockHttpRequest('GET', Uri.parse('/overwrite'));
|
||||||
await (rq.close());
|
await rq.close();
|
||||||
await http.handleRequest(rq);
|
await http.handleRequest(rq);
|
||||||
var body = await rq.response.transform(utf8.decoder).join();
|
var body = await rq.response.transform(utf8.decoder).join();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue