4.0.0.187
Enhancements
#102 Add Route
(s) to Router.RoutingTable
at Specified Index
Currently, routes are added to the routing table in the order that they are registered, and there is no mechanism to circumvent this. Hence, methods have been added to Router
to:
- Splice a route in at specific index
- Splice a range of routes in at a given index
- Splice a route either before or after a given Route object
- Splice a range of routes either before or after a given Route object
- Add a route or range of routes to top of routing table
#108 Provide Generic Delegate for WebExceptionStatus.Timeout
Currently if the RestClient.Execute()
gets a WebException
with a status of WebExceptionStatus.Timeout
when attempting to send the request, the exception is just re-thrown.
This adds the ability to provide a generic delegate on the RestClient
that would execute when the timeout occurs. This will simplify the end user implementation so that the code to handle this situation only needs to get written once; e.g. in situations where you might want to try again.
#122 Formatting Logic for PublicFolder.Prefix
Rather than always pre-pending a leading slash ('/') to the Prefix
property of the PublicFolder
class - which would be problematic if it already starts with a slash - logic was added to the setter to trim white space from the string and remove any leading and trailing slashes before adding a leading slash to the resulting value.
#123 Propagate Logger Assignment
When the Logger
property is set on the RestServer
class, it should set the value on the Router
as well. Similarly, when the Logger
property is set on the Router
class (including in the previous scenario), it should set the value on the RouteScanner
.
As the inverse of this is not true, in order to set different loggers for each class, they should be set in this order:
RestServer
Router
RouteScanner
#133 Add Missing ContentType Values
Some additional values have been added to the ContentType
enum to support Google Protocol Buffers and additional multipart formats.
Value | Type | Header Value |
---|---|---|
GoogleProtoBuf | Binary | application/vnd.google.protobuf |
MultipartAlternative | Text | multipart/alternative |
MultipartEncrypted | Text | multipart/encrypted |
MultipartMixed | Text | multipart/mixed |
MultipartRelated | Text | multipart/related |
MultipartSigned | Text | multipart/signed |
XProtoBuf | Binary | application/x-protobuf |
Important This changes does not add support for Google Protocol Buffers, it just adds the content types for those who want to use them.
#134 ContentType Parsing Performance Enhancements
After a round of testing various approaches, we discovered that the implementation of ContentType.FromString()
was embarrassingly slow. So, we changed it to the (verifiably) fastest algorithm submitted by our open source community. If you know how to speed this up even more, let us know!
We went ahead and applied this same change to the
HttpMethod.FromString()
method.
#136 Parsing Multiple Values or Malformed Content Type Http Headers
According to the specification, it's completely valid to send multiple values - as well as parameters - in the content type HTTP header. And if the first value doesn't match with anything in the ContentType
enum, we should still check the other values provided. So, now we are. This incidentally also happens to resolve an issue that might occur if a poorly implemented client sends a malformed value, as long as somewhere in that value there is a string that matches tree/subtree
.
So as not to kill our performance gains, we also added caching, so values we've seen before don't have to be parsed all over again.
Bug Fixes
#129 ContentType
Detection Failures Resolved
In scenarios where multiple values were provided in the Content-type HTTP header or where the value included parameters, a matching type would not be found in the ContentType
enum, and the default value would be used.
Example:
Content-type: text/html; charset=UTF-8,text/html; charset=windows-1251
With this fix, parameters are ignored and the first MIME type value provided is used to find a matching enum. In conjunction with this, the order of ContentType.HTML
and ContentType.HTM
were swapped such that text/html
would return ContentType.HTML
.
See: