| Index: sdk/lib/io/http_impl.dart
|
| diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
|
| index cc4166a9ed3661bbc6019dff0a395683b9c6a0c5..691e9488208e0279e08ddaace08f604ed3c80f01 100644
|
| --- a/sdk/lib/io/http_impl.dart
|
| +++ b/sdk/lib/io/http_impl.dart
|
| @@ -66,9 +66,15 @@ class _HttpIncoming extends StreamController<List<int>> {
|
|
|
| class _HttpInboundMessage extends Stream<List<int>> {
|
| final _HttpIncoming _incoming;
|
| + List<Cookie> _cookies;
|
|
|
| _HttpInboundMessage(_HttpIncoming this._incoming);
|
|
|
| + List<Cookie> get cookies {
|
| + if (_cookies != null) return _cookies;
|
| + return _cookies = headers._parseCookies();
|
| + }
|
| +
|
| HttpHeaders get headers => _incoming.headers;
|
| String get protocolVersion => headers.protocolVersion;
|
| int get contentLength => headers.contentLength;
|
| @@ -81,9 +87,30 @@ class _HttpRequest extends _HttpInboundMessage implements HttpRequest {
|
| // Lazy initialized parsed query parameters.
|
| Map<String, String> _queryParameters;
|
|
|
| - _HttpRequest(_HttpResponse this.response, _HttpIncoming _incoming)
|
| + final _HttpServer _httpServer;
|
| +
|
| + HttpSession _session;
|
| +
|
| + _HttpRequest(_HttpResponse this.response,
|
| + _HttpIncoming _incoming,
|
| + _HttpServer this._httpServer)
|
| : super(_incoming) {
|
| response.headers.persistentConnection = headers.persistentConnection;
|
| +
|
| + if (_httpServer._sessionManagerInstance != null) {
|
| + // Map to session if exists.
|
| + var sessionId = cookies.reduce(null, (last, cookie) {
|
| + if (last != null) return last;
|
| + return cookie.name.toUpperCase() == _DART_SESSION_ID ?
|
| + cookie.value : null;
|
| + });
|
| + if (sessionId != null) {
|
| + _session = _httpServer._sessionManager.getSession(sessionId);
|
| + if (_session != null) {
|
| + _session._markSeen();
|
| + }
|
| + }
|
| + }
|
| }
|
|
|
| StreamSubscription<T> listen(void onData(List<int> event),
|
| @@ -106,6 +133,15 @@ class _HttpRequest extends _HttpInboundMessage implements HttpRequest {
|
| Uri get uri => _incoming.uri;
|
|
|
| String get method => _incoming.method;
|
| +
|
| + HttpSession session([init(HttpSession session)]) {
|
| + if (_session != null) {
|
| + // It's already mapped, use it.
|
| + return _session;
|
| + }
|
| + // Create session, store it in connection, and return.
|
| + return _session = _httpServer._sessionManager.createSession(init);
|
| + }
|
| }
|
|
|
|
|
| @@ -119,6 +155,8 @@ class _HttpClientResponse
|
| // The HttpClientRequest of this response.
|
| final _HttpClientRequest _httpRequest;
|
|
|
| + List<Cookie> _cookies;
|
| +
|
| _HttpClientResponse(_HttpIncoming _incoming,
|
| _HttpClientRequest this._httpRequest,
|
| _HttpClient this._httpClient)
|
| @@ -127,6 +165,18 @@ class _HttpClientResponse
|
| int get statusCode => _incoming.statusCode;
|
| String get reasonPhrase => _incoming.reasonPhrase;
|
|
|
| + List<Cookie> get cookies {
|
| + if (_cookies != null) return _cookies;
|
| + _cookies = new List<Cookie>();
|
| + List<String> values = headers["set-cookie"];
|
| + if (values != null) {
|
| + values.forEach((value) {
|
| + _cookies.add(new Cookie.fromSetCookieValue(value));
|
| + });
|
| + }
|
| + return _cookies;
|
| + }
|
| +
|
| bool get isRedirect {
|
| if (_httpRequest.method == "GET" || _httpRequest.method == "HEAD") {
|
| return statusCode == HttpStatus.MOVED_PERMANENTLY ||
|
| @@ -316,13 +366,21 @@ class _HttpOutboundMessage<T>
|
|
|
| class _HttpResponse extends _HttpOutboundMessage<HttpResponse>
|
| implements HttpResponse {
|
| - _HttpResponse(String protocolVersion, _HttpOutgoing _outgoing)
|
| - : super(protocolVersion, _outgoing);
|
| -
|
| int statusCode = 200;
|
| -
|
| String reasonPhrase = "OK";
|
|
|
| + List<Cookie> _cookies;
|
| + _HttpRequest _httpRequest;
|
| +
|
| + _HttpResponse(String protocolVersion,
|
| + _HttpOutgoing _outgoing)
|
| + : super(protocolVersion, _outgoing);
|
| +
|
| + List<Cookie> get cookies {
|
| + if (_cookies == null) _cookies = new List<Cookie>();
|
| + return _cookies;
|
| + }
|
| +
|
| void _writeHeader() {
|
| writeSP() => add([_CharCode.SP]);
|
| writeCRLF() => add([_CharCode.CR, _CharCode.LF]);
|
| @@ -339,6 +397,29 @@ class _HttpResponse extends _HttpOutboundMessage<HttpResponse>
|
| addString(reasonPhrase);
|
| writeCRLF();
|
|
|
| + var session = _httpRequest._session;
|
| + if (session != null && !session._destroyed) {
|
| + // Make sure we only send the current session id.
|
| + bool found = false;
|
| + for (int i = 0; i < cookies.length; i++) {
|
| + if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) {
|
| + cookies[i].value = session.id;
|
| + cookies[i].httpOnly = true;
|
| + found = true;
|
| + break;
|
| + }
|
| + }
|
| + if (!found) {
|
| + cookies.add(new Cookie(_DART_SESSION_ID, session.id)..httpOnly = true);
|
| + }
|
| + }
|
| + // Add all the cookies set to the headers.
|
| + if (_cookies != null) {
|
| + _cookies.forEach((cookie) {
|
| + headers.add("set-cookie", cookie);
|
| + });
|
| + }
|
| +
|
| headers._finalize();
|
|
|
| // Write headers.
|
| @@ -850,7 +931,10 @@ class _HttpClient implements HttpClient {
|
|
|
|
|
| class _HttpConnection {
|
| - _HttpConnection(Socket this._socket, Function this._handleRequest) {
|
| + final Socket _socket;
|
| + final _HttpServer _httpServer;
|
| +
|
| + _HttpConnection(Socket this._socket, _HttpServer this._httpServer) {
|
| var parser = new _HttpParser.requestParser();
|
| _socket.pipe(parser);
|
| parser.listen(
|
| @@ -860,7 +944,8 @@ class _HttpConnection {
|
| var response = new _HttpResponse(
|
| incoming.headers.protocolVersion,
|
| outgoing);
|
| - var request = new _HttpRequest(response, incoming);
|
| + var request = new _HttpRequest(response, incoming, _httpServer);
|
| + response._httpRequest = request;
|
| outgoing.dataDone.then(() {
|
| if (response.headers.persistentConnection) {
|
| // Mark incoming as done, preparing for next HTTP request.
|
| @@ -870,7 +955,7 @@ class _HttpConnection {
|
| _socket.destroy();
|
| }
|
| });
|
| - _handleRequest(request);
|
| + _httpServer._handleRequest(request);
|
| },
|
| onDone: () {
|
| // TODO(ajohnsen): Remove connection from active connection queue.
|
| @@ -879,10 +964,6 @@ class _HttpConnection {
|
| // TODO(ajohnsen): Handle errors.
|
| });
|
| }
|
| -
|
| - final Function _handleRequest;
|
| -
|
| - final Socket _socket;
|
| }
|
|
|
|
|
| @@ -901,7 +982,7 @@ class _HttpServer extends Stream<HttpRequest> implements HttpServer {
|
| bool unsubscribeOnError}) {
|
| _serverSubscription = _serverSocket.listen((Socket socket) {
|
| // Accept the client connection.
|
| - _HttpConnection connection = new _HttpConnection(socket, _handleRequest);
|
| + _HttpConnection connection = new _HttpConnection(socket, this);
|
| _connections.add(connection);
|
| // TODO(ajohnsen): Listen to closed sockets.
|
| });
|
|
|