lvivski / start

Sinatra inspired web development framework for Dart

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Request.cookies crashes (if non valid cookies are set)

nkratzke opened this issue · comments

If non valid cookies are set for example like that:

req.response.cookie("name", "for example something with a whitespace");

a call on

req.cookies

will fail like that.

Uncaught Error: HttpException: Failed to parse header value [name=nane; first name=test; last name=nane]
Unhandled exception:
HttpException: Failed to parse header value [name=nane; first name=test; last name=nane]
#0      _rootHandleUncaughtError.<anonymous closure>.<anonymous closure> (dart:async/zone.dart:677)
#1      _asyncRunCallback (dart:async/schedule_microtask.dart:18)
#2      _asyncRunCallback (dart:async/schedule_microtask.dart:21)
#3      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:119)
Stack Trace: 
#0      _HttpHeaders._parseCookies.parseCookieString.expect (http_headers.dart:470)
#1      _HttpHeaders._parseCookies.parseCookieString (http_headers.dart:480)
#2      _HttpHeaders._parseCookies.<anonymous closure> (http_headers.dart:491)
#3      List.forEach (dart:core-patch/growable_array.dart:240)
#4      _HttpHeaders._parseCookies (http_headers.dart:491)
#5      _HttpInboundMessage.cookies (http_impl.dart:74)
#6      Request.cookies (package:start/src/request.dart:22:40)
#7      main.<anonymous closure>.<anonymous closure> (file:///Users/nane/dart/httpserver/bin/start_cookie_handling.dart:13:15)
#8      _rootRunUnary (dart:async/zone.dart:695)
#9      _RootZone.runUnary (dart:async/zone.dart:834)
#10     _BaseZone.runUnaryGuarded (dart:async/zone.dart:546)
#11     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:333)
#12     _DelayedData.perform (dart:async/stream_impl.dart:585)
#13     _StreamImplEvents.handleNext (dart:async/stream_impl.dart:701)
#14     _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:661)
#15     _asyncRunCallback (dart:async/schedule_microtask.dart:18)
#16     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:119)

I propose to provide a Uri.encodeQueryComponent in the following method of class Response:

Response cookie(String name, String val, [Map options]) {
    var cookie = new Cookie(
             Uri.encodeQueryComponent(name),
             Uri.encodeQueryComponent(value),
     );

     final cookieMirror = reflect(cookie);

    if (options != null) {
      options.forEach((option, value) {
        cookieMirror.setField(new Symbol(option), value);
      });
    }

    _response.cookies.add(cookie);
    return this;
  }

Also a Uri.decodeQueryComponent should be made in the cookies getter of HttpRequest.

For example like this:

  List<Cookie> get cookies {
      return _request.cookies.map((Cookie c) {
        c.name = Uri.decodeQueryComponent(c.name);
        c.value = Uri.decodeQueryComponent(c.value);
        return c;
     });
  }

The problem with decodeQueryComponent is that it throws an exception in case of wrong symbols, so we'll have to wrap this calls to try {} catch {} calls, to keep server alive