Giter VIP home page Giter VIP logo

openrasta-core's People

Contributors

antonjefcoate avatar bchavez avatar dependabot[bot] avatar dstockhammer avatar eugendueck avatar goughlee avatar gshackles avatar hanksjosholo avatar hcanber avatar holytshirt avatar iancooper avatar iblis avatar jackmott avatar jchannon avatar jonnyollifflee avatar knocte avatar markkharitonov avatar nmosafi avatar powelli13 avatar serialseb avatar stewabel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openrasta-core's Issues

Response Content-Type header incorrectly contains the quality qualifier.

Hi, here is a response I get from OpenRasta:

HTTP/1.1 200 OK
Content-Length: 189
Content-Type: application/xml; q="0,9"
Server: Microsoft-HTTPAPI/2.0
Date: Mon, 01 Aug 2011 08:43:37 GMT

<?xml version="1.0" encoding="utf-8"?>
<Home xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Title>Welcome home.</Title>
</Home>

Notice the Content-Type header. It should only have application/xml, without the quality part, having which there makes it more difficult to match deserializer based on the Content-Type.

The funny thing is that I am sure I have seent someone reporting this issue and Seb answering him that it is a bug and it was fixed. Well, it is not fixed in openrasta-core.

Incorrect HTTP status code returned when POST returns OperationResult.Created with a relative URI.

OperationResult.Execute treats RedirectLocation as an absolute URI. If the URI is relative an exception is thrown. The correct HTTP status code in this case should be 500. However, 201 is returned, as though nothing wrong has happened.

Ideally, if the URI is relative OR should know to convert it to absolute. This was the symmetry is preserved - the developer has to know the base URL neither when the resource is configured nor when its location is returned within the same web service address space.

Required HTTP headers are not generate by the InMemoryHost

Required fields, usually generate by http clients and hosting servers, are not present in InMemoryRequest and InMemoryResponse.

On InMemoryRequest:

  • Host which should default to whatever the base URI is for the memory host, which I think is http://localhost. Bonus points for making it overridable

On InMemoryResponse, but only after processing has been done in case someone already wrote a value

  • Date in proper rfc822 format

Allow overrides for binding names in the key/values subsystem

Per Seb's request,

Suppose I have a www form url encoded value:

serial-number=foobar

How do you represent 'serial-number' as a parameter to a method in C# in OpenRasta? "serial-number" is an illegal parameter name in C#; so the following does not work:

public class Checkout{
public OperationResult PostSerialNumber(string serial-number){
//do something with serial-number variable...
}
}
There is no way the above method to execute because WwwFormUrlencodedKeyValueCodec isn't aware of C#'s variable naming restrictions... so the code can never be executed.

I don't have control over the posted form key since these are coming from a remote server that I do not have control of.

Details & work-around here:

http://groups.google.com/group/openrasta/browse_thread/thread/227acc3934de0b33

Thanks,
Brian

CodecRepository calculates wrong score for optional parameters

In CodecRepository.FindMediaTypeReader we have these pieces of code:

            if (requiredMembers.Any())
            {
                totalDistanceToRequiredParameters = CalculateScoreFor(requiredMembers, codec);
                if (totalDistanceToRequiredParameters == -1)
                    continue; // the codec cannot resolve the required parameters
            }

            ...

            foreach (var optionalType in optionalMembers)
            {
                int typeScore = CalculateDistance(optionalType, codec);
                if (typeScore > -1)
                {
                    totalDistanceToOptionalParameters += typeScore;
                    totalOptionalParametersCompatibleWithCodec++;
                }
            }

At last we add the two distances to get the total score:

float averageScore = totalDistanceToRequiredParameters + totalDistanceToOptionalParameters;

Unfortunately "totalDistanceToRequiredParameters" is a score not a distance - bigger scores are better whereas smaller distances are better. This "averageScore" is a bit like adding apples and oranges - it does not make sense.

Later on there is a sorting to grab the codec with the best (biggest score):

        codecMatches.Sort();
        codecMatches.Reverse();
        return codecMatches[0];

This is not exactly the most efficient way to find the best entry.

But the main issue is: fix totalDistanceToOptionalParameters to be calculated as a score (not a distance) and then rename both "totalDistanceToOptionalParameters" and "totalDistanceToRequiredParameters" to something with "score" in the name instead of "distance".

Authentication via pipeline contributors - I think the pattern is broken?

I've duplicated the approach taken in the DigestAuthorizerContributor to implement BasicAuthorizerContributor, but I think the pattern used in the Digest implementation is broken. Specifically, I'm now getting prompted for credentials even when accessing resources that are not decorated with the RequiresAuthentication attribute.

Specifically - I don't think the authorization contributor should EVER be returning OperationResult.NotAuthorized - because authorization for the resource is controlled by the RequiresAuthentication attribute on the handler. I think the AuthorizerContributor should just check the headers and (if possible) set Context.User.Identity, but should ALWAYS return PipelineContinuation.Continue - because at this point, the authorizer doesn't know whether the request is for a secure resource or not... and then the RequiresAuthentication attribute should return the HTTP Unauthorized response and end the pipeline.

Make sense? Is it worth updating the authorizers to reflect this pattern, or have I missed something?

Issue with parsing json data into a GET method {}'s removed

Ported over from openrasta/archived-openrasta-legacy#30

It appears when passing in json data into a method the leading and trailing {}'s are removed and the data is still left url encoded. However if you insert a space before the passed in json data the {}'s are kept, but still url encoded.

using..

http://localhost:8002/Example?callback=updateCallback&url=http%3A%2F%2Flocalhost%3A8001%2FExample%2F12345&method=PUT&data=%7B+%22Name%22+%3A+%22pete%22+%7D&_=1330595296341

to something like...

[HttpOperation(HttpMethod.GET)]
public OperationResult Example(string callback, string method, string url, string data, string id)
{
}

the data param wil be...

+"Name"+,"pete"+

where the httpcontext querystring would correctly return { "Name" , "pete" }

Malformed Accept Header creates infinite loop

I accidentally left a comma at the end of the list of media types in my accept header:
text/plain, application/vnd.gideon.list+json,

This resulted in a (seemingly) infinite loop:

Exception:
System.ArgumentException: The parameter 'contentType' cannot be an empty string.
Parameter name: contentType
at System.Net.Mime.ContentType..ctor(String contentType)
at OpenRasta.Web.MediaType..ctor(String contentType)
at OpenRasta.Web.MediaType.b__1(String mediaTypeComponent)
at System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext() at System.Linq.Buffer1..ctor(IEnumerable1 source) at System.Linq.OrderedEnumerable1.d__0.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at System.Linq.Buffer1..ctor(IEnumerable1 source) at System.Linq.OrderedEnumerable1.d__0.MoveNext()
at System.Linq.Lookup2.Create[TSource](IEnumerable1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer) at System.Linq.GroupedEnumerable3.GetEnumerator()
at System.Linq.Enumerable.Aggregate[TSource,TAccumulate](IEnumerable1 source, TAccumulate seed, Func3 func)
at OpenRasta.Codecs.CodecRepository.FindMediaTypeWriter(IMember resourceType, IEnumerable1 requestedMediaTypes) at OpenRasta.Pipeline.Contributors.ResponseEntityCodecResolverContributor.FindResponseCodec(ICommunicationContext context) at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call) Exception: System.ArgumentException: The parameter 'contentType' cannot be an empty string. Parameter name: contentType at System.Net.Mime.ContentType..ctor(String contentType) at OpenRasta.Web.MediaType..ctor(String contentType) at OpenRasta.Web.MediaType.<Parse>b__1(String mediaTypeComponent) at System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext()
at System.Linq.Buffer1..ctor(IEnumerable1 source)
at System.Linq.OrderedEnumerable1.<GetEnumerator>d__0.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
at System.Linq.Buffer1..ctor(IEnumerable1 source)
at System.Linq.OrderedEnumerable1.<GetEnumerator>d__0.MoveNext() at System.Linq.Lookup2.Create[TSource](IEnumerable1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer)
at System.Linq.GroupedEnumerable3.GetEnumerator() at System.Linq.Enumerable.Aggregate[TSource,TAccumulate](IEnumerable1 source, TAccumulate seed, Func3 func) at OpenRasta.Codecs.CodecRepository.FindMediaTypeWriter(IMember resourceType, IEnumerable1 requestedMediaTypes)
at OpenRasta.Pipeline.Contributors.ResponseEntityCodecResolverContributor.FindResponseCodec(ICommunicationContext context)
at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call)
Exception:
System.ArgumentException: The parameter 'contentType' cannot be an empty string.
Parameter name: contentType
at System.Net.Mime.ContentType..ctor(String contentType)
at OpenRasta.Web.MediaType..ctor(String contentType)
at OpenRasta.Web.MediaType.b__1(String mediaTypeComponent)
at System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext() at System.Linq.Buffer1..ctor(IEnumerable1 source) at System.Linq.OrderedEnumerable1.d__0.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at System.Linq.Buffer1..ctor(IEnumerable1 source) at System.Linq.OrderedEnumerable1.d__0.MoveNext()
at System.Linq.Lookup2.Create[TSource](IEnumerable1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer) at System.Linq.GroupedEnumerable3.GetEnumerator()
at System.Linq.Enumerable.Aggregate[TSource,TAccumulate](IEnumerable1 source, TAccumulate seed, Func3 func)
at OpenRasta.Codecs.CodecRepository.FindMediaTypeWriter(IMember resourceType, IEnumerable`1 requestedMediaTypes)
at OpenRasta.Pipeline.Contributors.ResponseEntityCodecResolverContributor.FindResponseCodec(ICommunicationContext context)
at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call)

Of course, this can be worked around by not having a trailing comma.

Codecs don't assign parameters when handler has optional param

Hi, consider the following trivial code:

public class Kuku
{
}

public class KukuHandler
{
  public OperationResult Put(int id, [Optional, DefaultParameterValue(false)] bool a, Kuku dto)
  {
    Debug.WriteLine("{2} ---> Id = {0}, a = {1}{2}", id, a, Environment.NewLine);
    return new OperationResult.MovedPermanently();
  }
}

public class Configuration : IConfigurationSource
{
  public void Configure()
  {
    using (OpenRastaConfiguration.Manual)
    {
      ResourceSpace.Uses.UriDecorator<ContentTypeExtensionUriDecorator>();
      ResourceSpace.Uses.UriDecorator<HttpMethodOverrideUriDecorator>();

      ResourceSpace.Has.ResourcesOfType<Kuku>()
        .AtUri("Kuku/{id}?a={a}")
        .HandledBy<KukuHandler>()
        .AsJsonDataContract();
    }
  }
}

class Program
{
  static void Main()
  {
    var stream = new MemoryStream(Encoding.ASCII.GetBytes("{}"));
    var request = new InMemoryRequest
    {
      HttpMethod = "PUT",
      Uri = new Uri("http://localhost/Kuku/123"),
      Entity = new HttpEntity(new HttpHeaderDictionary(), stream)
      {
        ContentLength = stream.Length,
        ContentType = MediaType.Json,
      },
    };
    using (var host = new InMemoryHost(new Configuration()))
    {
      var response = host.ProcessRequest(request);
      Debug.Assert(response.StatusCode == (int)HttpStatusCode.MovedPermanently);
    }
  }
}

Running this program fails the assertion. Here is the debug output:

9-[2011-11-11 17:16:51Z] Information(0) Registering host of type OpenRasta.Hosting.InMemory.InMemoryHost
9-[2011-11-11 17:16:52Z] Verbose(0) Using dependency resolver of type OpenRasta.DI.InternalDependencyResolver
9-[2011-11-11 17:16:52Z] Verbose(0) Registering host's root dependencies.
9-[2011-11-11 17:16:52Z] Information(0) Using dependency registrar of type OpenRasta.Configuration.DefaultDependencyRegistrar.
9-[2011-11-11 17:16:52Z] Verbose(0) Ignoring constructor, following dependencies didn't have a registration:OpenRasta.TypeSystem.Surrogates.ISurrogateBuilder[]
9-[2011-11-11 17:16:52Z] Verbose(0) Registering host's leaf dependencies.
9-[2011-11-11 17:16:52Z] Verbose(0) Using configuration source A.Configuration
9-[2011-11-11 17:16:52Z] Verbose(0) Ignoring constructor, following dependencies didn't have a registration:System.Func`1[System.Collections.Generic.IEnumerable`1[OpenRasta.Configuration.MetaModel.Handlers.IMetaModelHandler]]
9-[2011-11-11 17:16:52Z] Verbose(0) Ignoring constructor, following dependencies didn't have a registration:System.Diagnostics.TraceSource
9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing the pipeline.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor ResponseEntityCodecResolverContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor ResponseEntityWriterContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor BootstrapperContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor HttpMethodOverriderContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor UriDecoratorsContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor ResourceTypeResolverContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor HandlerResolverContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor AuthenticationContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor AuthenticationChallengerContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Ignoring constructor, following dependencies didn't have a registration:OpenRasta.OperationModel.MethodBased.IMethodFilter[]
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor OperationCreatorContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor OperationFilterContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor OperationHydratorContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor OperationCodecSelectorContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor OperationInvokerContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor OperationResultInvokerContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor OperationInterceptorContributor.
    9-[2011-11-11 17:16:52Z] Verbose(0) Initialized contributor EndContributor.
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor ResponseEntityCodecResolverContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor ResponseEntityWriterContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor HttpMethodOverriderContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor UriDecoratorsContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor ResourceTypeResolverContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor HandlerResolverContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor AuthenticationContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor AuthenticationChallengerContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor OperationCreatorContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor OperationFilterContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor OperationHydratorContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor OperationCodecSelectorContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor OperationInvokerContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor OperationResultInvokerContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor OperationInterceptorContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Start(1) Entering PipelineRunner: Initializing contributor EndContributor.
    9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
    9-[2011-11-11 17:16:52Z] Information(0) Contributor call chain has been processed and results in the following pipeline:
    9-[2011-11-11 17:16:52Z] Information(0) 0 BootstrapperContributor
    9-[2011-11-11 17:16:52Z] Information(0) 1 HttpMethodOverriderContributor
    9-[2011-11-11 17:16:52Z] Information(0) 2 AuthenticationContributor
    9-[2011-11-11 17:16:52Z] Information(0) 3 UriDecoratorsContributor
    9-[2011-11-11 17:16:52Z] Information(0) 4 ResourceTypeResolverContributor
    9-[2011-11-11 17:16:52Z] Information(0) 5 HandlerResolverContributor
    9-[2011-11-11 17:16:52Z] Information(0) 6 OperationCreatorContributor
    9-[2011-11-11 17:16:52Z] Information(0) 7 OperationFilterContributor
    9-[2011-11-11 17:16:52Z] Information(0) 8 OperationCodecSelectorContributor
    9-[2011-11-11 17:16:52Z] Information(0) 9 OperationHydratorContributor
    9-[2011-11-11 17:16:52Z] Information(0) 10 OperationInterceptorContributor
    9-[2011-11-11 17:16:52Z] Information(0) 11 OperationInvokerContributor
    9-[2011-11-11 17:16:52Z] Information(0) 12 OperationResultInvokerContributor
    9-[2011-11-11 17:16:52Z] Information(0) 13 ResponseEntityCodecResolverContributor
    9-[2011-11-11 17:16:52Z] Information(0) 14 AuthenticationChallengerContributor
    9-[2011-11-11 17:16:52Z] Information(0) 15 ResponseEntityWriterContributor
    9-[2011-11-11 17:16:52Z] Information(0) 16 EndContributor
9-[2011-11-11 17:16:52Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:16:52Z] Information(0) Pipeline has been successfully initialized.
9-[2011-11-11 17:16:58Z] Verbose(0) Incoming host request for http://localhost/Kuku/123
9-[2011-11-11 17:16:58Z] Verbose(0) Adding communication context data
9-[2011-11-11 17:16:58Z] Warning(0) Contributor call for BootstrapperContributor had a null Action.
9-[2011-11-11 17:16:58Z] Start(1) Entering PipelineRunner: Executing contributor HttpMethodOverriderContributor.OverrideHttpVerb
9-[2011-11-11 17:16:58Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:16:58Z] Start(1) Entering PipelineRunner: Executing contributor AuthenticationContributor.AuthoriseRequest
9-[2011-11-11 17:16:58Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:16:58Z] Start(1) Entering PipelineRunner: Executing contributor UriDecoratorsContributor.ProcessDecorators
9-[2011-11-11 17:16:58Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:16:58Z] Start(1) Entering PipelineRunner: Executing contributor ResourceTypeResolverContributor.ResolveResource
9-[2011-11-11 17:16:58Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:16:58Z] Start(1) Entering PipelineRunner: Executing contributor HandlerResolverContributor.ResolveHandler
9-[2011-11-11 17:16:58Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:16:58Z] Start(1) Entering PipelineRunner: Executing contributor OperationCreatorContributor.CreateOperations
    9-[2011-11-11 17:16:58Z] Verbose(0) Created operation named Put with signature KukuHandler::Put(Int32 id, Boolean a, Kuku dto)
9-[2011-11-11 17:16:58Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:16:58Z] Start(1) Entering PipelineRunner: Executing contributor OperationFilterContributor.ProcessOperations
    9-[2011-11-11 17:16:58Z] Verbose(0) Found 1 operation(s) with a matching name.
    9-[2011-11-11 17:16:58Z] Verbose(0) Found 0 operation(s) with matching [HttpOperation] attribute.
    9-[2011-11-11 17:16:58Z] Verbose(0) No resource or no uri name. Not filtering.
9-[2011-11-11 17:17:00Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:17:00Z] Start(1) Entering PipelineRunner: Executing contributor OperationCodecSelectorContributor.ProcessOperations
    9-[2011-11-11 17:17:00Z] Information(0) Operation KukuHandler::Put(Int32 id, Boolean a, Kuku dto) selected with 2 required members and 1 optional members, with codec JsonDataContractCodec with score 1.
9-[2011-11-11 17:17:00Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:17:00Z] Start(1) Entering PipelineRunner: Executing contributor OperationHydratorContributor.ProcessOperations
    9-[2011-11-11 17:17:00Z] Information(0) Operation KukuHandler::Put(Int32 id, Boolean a, Kuku dto) was selected with a codec score of 1
    9-[2011-11-11 17:17:00Z] Information(0) Loaded codec OpenRasta.Codecs.JsonDataContractCodec
    9-[2011-11-11 17:17:00Z] Verbose(0) Switching to full object media type reading.
A first chance exception of type 'System.FormatException' occurred in System.Xml.dll
A first chance exception of type 'System.Xml.XmlException' occurred in System.Runtime.Serialization.dll
A first chance exception of type 'System.Runtime.Serialization.SerializationException' occurred in System.Runtime.Serialization.dll
9-[2011-11-11 17:17:00Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:17:00Z] Verbose(0) Pipeline is in RenderNow mode.
9-[2011-11-11 17:17:00Z] Start(1) Entering PipelineRunner: Executing contributor OperationResultInvokerContributor.RunOperationResult
    9-[2011-11-11 17:17:00Z] Information(0) Executing OperationResult OperationResult: type=MethodNotAllowed, statusCode=405.
9-[2011-11-11 17:17:00Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:17:00Z] Start(1) Entering PipelineRunner: Executing contributor ResponseEntityCodecResolverContributor.FindResponseCodec
    9-[2011-11-11 17:17:00Z] Information(0) No response codec was searched for. The response entity is null or a response codec is already set.
9-[2011-11-11 17:17:00Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:17:00Z] Start(1) Entering PipelineRunner: Executing contributor AuthenticationChallengerContributor.ChallengeIfUnauthorized
9-[2011-11-11 17:17:00Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:17:00Z] Start(1) Entering PipelineRunner: Executing contributor ResponseEntityWriterContributor.WriteResponse
    9-[2011-11-11 17:17:00Z] Verbose(0) There was no response entity, not rendering.
    9-[2011-11-11 17:17:00Z] Verbose(0) Writing http headers.
9-[2011-11-11 17:17:00Z] Stop(1) Exiting PipelineRunner
9-[2011-11-11 17:17:00Z] Information(0) Pipeline finished.
9-[2011-11-11 17:17:00Z] Verbose(0) Request finished.

Note, that passing the parameter explicitly works OK, so the presented code is valid.
Thanks.

Race condition (concurrency issue) in SurrogateBuilderProvider

The code here has a race condition problem:

        T Cached<T>(Dictionary<T, T> cache, T value, Func<T, T> createCached)
        {
            T cachedValue;
            if (cache.TryGetValue(value, out cachedValue))
                return cachedValue;
            lock (cache)
            {
                cachedValue = createCached(value);
                cache.Add(value, cachedValue);
                return cachedValue;
            }
        }

The TryGetValue should be inside the lock(...) statement - otherwise two different threads may see that the same item is missing and then try to insert one after another leading to a "System.ArgumentException: An item with the same key has already been added.".

The stacktrace here is from two identical requests executed simultaneous:

DEBUG 2015-08-11 13:53:44,161 1968ms [48] Log4NetTraceListener WriteLine - Incoming host request for http://jw-pc261.cbrain.net/f2-restservices-5.0/distributed-requisitions/747/accept
DEBUG 2015-08-11 13:53:44,165 1972ms [48] Log4NetTraceListener WriteLine - Entering OpenRastaRewriterHandler: Rewriting to original path
DEBUG 2015-08-11 13:53:44,167 1974ms [48] Log4NetTraceListener WriteLine - Entering OpenRastaIntegratedHandler: Request for http://jw-pc261.cbrain.net/f2-restservices-5.0/distributed-requisitions/747/accept
DEBUG 2015-08-11 13:53:44,169 1976ms [48] Log4NetTraceListener WriteLine - Incoming host request for http://jw-pc261.cbrain.net/f2-restservices-5.0/distributed-requisitions/747/accept
DEBUG 2015-08-11 13:53:44,170 1977ms [57] Log4NetTraceListener WriteLine - Incoming host request for http://jw-pc261.cbrain.net/f2-restservices-5.0/distributed-requisitions/747/accept
DEBUG 2015-08-11 13:53:44,173 1980ms [57] Log4NetTraceListener WriteLine - Entering OpenRastaRewriterHandler: Rewriting to original path
DEBUG 2015-08-11 13:53:44,174 1981ms [57] Log4NetTraceListener WriteLine - Entering OpenRastaIntegratedHandler: Request for http://jw-pc261.cbrain.net/f2-restservices-5.0/distributed-requisitions/747/accept
DEBUG 2015-08-11 13:53:44,175 1982ms [57] Log4NetTraceListener WriteLine - Incoming host request for http://jw-pc261.cbrain.net/f2-restservices-5.0/distributed-requisitions/747/accept
DEBUG 2015-08-11 13:53:44,189 1996ms [48] Log4NetTraceListener WriteLine - Operation AcceptRequisitionHandler::Post(Int64 id, AcceptRequisitionArgs args) selected with 2 required members and 0 optional members, with codec ApplicationXWwwFormUrlencodedKeyedValuesCodec with score 2.5.
DEBUG 2015-08-11 13:53:44,191 1998ms [57] Log4NetTraceListener WriteLine - Operation AcceptRequisitionHandler::Post(Int64 id, AcceptRequisitionArgs args) selected with 2 required members and 0 optional members, with codec ApplicationXWwwFormUrlencodedKeyedValuesCodec with score 2.5.
DEBUG 2015-08-11 13:53:44,224 2031ms [57] enAuthorizationHandler IsAuthorized - Check Bearer authorization
DEBUG 2015-08-11 13:53:44,227 2034ms [57] enAuthorizationHandler IsAuthorized - Got authorization header.
DEBUG 2015-08-11 13:53:44,229 2036ms [57] icAuthorizationHandler IsAuthorized - Check Basic authorization
DEBUG 2015-08-11 13:53:44,231 2038ms [57] icAuthorizationHandler GetUsernamePassword - Got authorization header.
DEBUG 2015-08-11 13:53:44,230 2037ms [48] Log4NetTraceListener Write - openrasta Error: 0 :
DEBUG 2015-08-11 13:53:44,236 2043ms [48] Log4NetTraceListener WriteLine - An error has occurred and the processing of the request has stopped.

Exception:
System.ArgumentException: An item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add) at OpenRasta.TypeSystem.Surrogated.SurrogateBuilderProvider.Cached[T](Dictionary2 cache, T value, Func2 createCached) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\TypeSystem\Surrogated\SurrogateBuilderProvider.cs:line 67 at OpenRasta.TypeSystem.Surrogated.SurrogateBuilderProvider.FindPropertySurrogate(IProperty property) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\TypeSystem\Surrogated\SurrogateBuilderProvider.cs:line 39 at OpenRasta.TypeSystem.Surrogated.SurrogateBuilderProvider.FindSurrogate[T](T member) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\TypeSystem\Surrogated\SurrogateBuilderProvider.cs:line 32 at OpenRasta.TypeSystem.PropertyExtensions.FindPropertyByPath(IMember source, String propertyName) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\TypeSystem\PropertyExtensions.cs:line 21 at OpenRasta.TypeSystem.MemberBuilder.GetProperty(String propertyPath) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\TypeSystem\MemberBuilder.cs:line 38 at OpenRasta.Binding.KeyedValuesBinder.SetPropertyValue[TValue](String key, String property, IEnumerable1 values, ValueConverter1 converter) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Binding\KeyedValuesBinder.cs:line 96 at OpenRasta.Binding.KeyedValuesBinder.SetProperty[TValue](String key, IEnumerable1 values, ValueConverter1 converter) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Binding\KeyedValuesBinder.cs:line 80 at OpenRasta.Binding.KeyedValues1.SetProperty(IObjectBinder binder) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Binding\KeyedValues1.cs:line 37 at OpenRasta.Codecs.CodecExtensions.<>c__DisplayClass8.<TryAssignKeyValues>b__7(KeyedValues kv) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Codecs\CodecExtensions.cs:line 38 at System.Linq.Enumerable.WhereEnumerableIterator1.MoveNext()
at OpenRasta.Collections.ObservableIterator1.<GetEnumerator>d__0.MoveNext() in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Collections\ObservableIterator.cs:line 42 at System.Linq.Enumerable.Count[TSource](IEnumerable1 source)
at OpenRasta.Codecs.CodecExtensions.TryAssignKeyValues(ICodec codec, IHttpEntity entity, IObjectBinder binder, Action1 assigned, Action1 failed) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Codecs\CodecExtensions.cs:line 36
at OpenRasta.Codecs.CodecExtensions.<>c__DisplayClassb.b__a(Boolean result, IObjectBinder binder) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Codecs\CodecExtensions.cs:line 52
at System.Linq.Enumerable.Aggregate[TSource,TAccumulate](IEnumerable1 source, TAccumulate seed, Func3 func)
at OpenRasta.Codecs.CodecExtensions.TryAssignKeyValues(ICodec codec, IHttpEntity entity, IEnumerable1 binders, Action1 assigned, Action1 failed) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Codecs\CodecExtensions.cs:line 52 at OpenRasta.OperationModel.Hydrators.RequestEntityReaderHydrator.TryAssignKeyedValues(IHttpEntity requestEntity, ICodec codec, Type codecType, IOperation operation) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\OperationModel\Hydrators\RequestEntityReaderHydrator.cs:line 88 at OpenRasta.OperationModel.Hydrators.RequestEntityReaderHydrator.<Process>d__8.MoveNext() in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\OperationModel\Hydrators\RequestEntityReaderHydrator.cs:line 53 at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)
at OpenRasta.Pipeline.Contributors.AbstractOperationProcessing`2.ProcessOperations(ICommunicationContext context) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Pipeline\Contributors\AbstractOperationProcessing.cs:line 24
at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Pipeline\PipelineRunner.cs:line 187

The WrapperStream should expose the underlying stream to enable efficient compression pipeline contributor implementation.

A compression code is likely to be more efficient if context.Response.Entity exposed the actual underlying stream in addition to the WrapperStream instance.

This is because the underlying stream in most of the cases is a MemoryStream instance. This way, if the raw data buffer is needed, one will not have to copy bytes from the stream to a new buffer, but utilize the MemoryStream.GetBuffer() method to get the original buffer directly.

NullRferenceException in HttpListenerHost.Dispose() if uninitialized

When an HttpListenerHost is finalized/disposed without calling Initialize() first it throws a NullReferenceException:

System.NullReferenceException: Object reference not set to an instance of an object.
at OpenRasta.Hosting.HttpListener.HttpListenerHost.Dispose(Boolean fromDisposeMethod) in HttpListenerHost.cs: line 144
at OpenRasta.Hosting.HttpListener.HttpListenerHost.Finalize() in HttpListenerHost.cs: line 18 

Happens because it's trying to Abort() the underlying System.Net.HttpListener which is null. Here's a test case:

using NUnit.Framework;
using OpenRasta.Hosting.HttpListener;

namespace HttpListenerHost_Specification
{
    public class when_disposing
    {
        [Test]
        public void should_not_raise_any_exception_when_not_initialized()
        {
            using (new HttpListenerHost());
        }
    }
}

@huboard:{"order":13.5}

ObjectBinder Parameters Not Working

Details here:
http://groups.google.com/group/openrasta/browse_thread/thread/14ff56268ffd685

Essentially, given the following handler:

public class CustomerHandler {
public OperationResult PostSomething([MyBinder] Foo otherThanCustomer ) {}
}

MyBinder is never detected and never calls GetBinder().

I believe this is a problem with the DefaultObjectBinderLocator on line 31:

31: var abstractObjectBinderAttribute = member.FindAttribute() ?? member.Type.FindAttribute();

33: if (abstractObjectBinderAttribute != null)
return abstractObjectBinderAttribute.GetBinder(member);

Notice, member.FindAttribute<> only works on member itself, and the type, but not use the ParameterInfo.GetCustomAttribute() call.

Race condition (concurrency issue) in dependency resolver

In DependencyManager.cs we have this little "test and set" code:

    public static object GetService(Type dependencyType)
    {
      ...
        if (AutoRegisterDependencies && !dependencyType.IsAbstract)
        {
            if (!_resolver.HasDependency(dependencyType))
                _resolver.AddDependency(dependencyType, DependencyLifetime.Transient);
        }
    }

If two threads does the HasDependency() check simultaneous and both of them get "false" then both will try to AddDependency - and one of them fails (depending on the chosen DI container). The Castle container throws an exception when inserting something that exists already.

Here is a stack trace "proof":

DEBUG 2013-02-22 09:50:36,481 5943ms [22] Log4NetTraceListener WriteLine - Incoming host request for http://localhost/f2-restservices-main/parties/645585
DEBUG 2013-02-22 09:50:36,482 5944ms [35] Log4NetTraceListener WriteLine - Incoming host request for http://localhost/f2-restservices-main/parties/645585
DEBUG 2013-02-22 09:50:36,484 5946ms [19] Log4NetTraceListener WriteLine - Incoming host request for http://localhost/f2-restservices-main/parties/645585
DEBUG 2013-02-22 09:50:36,485 5947ms [30] Log4NetTraceListener Write - openrasta Error: 0 :
DEBUG 2013-02-22 09:50:36,486 5948ms [30] Log4NetTraceListener WriteLine - An error has occurred and the processing of the request has stopped.

Exception:
Castle.MicroKernel.ComponentRegistrationException: Component CBrain.F2.Rest.Server.Modules.Parties.Codecs.RestPartyCodec could not be registered. There is already a component with that name. Did you want to modify the existing component instead? If not, make sure you specify a unique name.
at Castle.MicroKernel.SubSystems.Naming.DefaultNamingSubSystem.Register(IHandler handler) in c:\BuildAgent\work\9834359f44c23fee\src\Castle.Windsor\MicroKernel\SubSystems\Naming\DefaultNamingSubSystem.cs:line 237
at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.RegisterHandler(String name, IHandler handler, Boolean skipRegistration) in c:\BuildAgent\work\9834359f44c23fee\src\Castle.Windsor\MicroKernel\DefaultKernel.cs:line 718
at Castle.MicroKernel.Handlers.DefaultHandlerFactory.Create(ComponentModel model, Boolean isMetaHandler) in c:\BuildAgent\work\9834359f44c23fee\src\Castle.Windsor\MicroKernel\Handlers\DefaultHandlerFactory.cs:line 41
at Castle.MicroKernel.DefaultKernel.AddCustomComponent(ComponentModel model, Boolean isMetaHandler) in c:\BuildAgent\work\9834359f44c23fee\src\Castle.Windsor\MicroKernel\DefaultKernel.cs:line 265
at Castle.MicroKernel.DefaultKernel.AddCustomComponent(ComponentModel model) in c:\BuildAgent\work\9834359f44c23fee\src\Castle.Windsor\MicroKernel\DefaultKernel.cs:line 272
at Castle.MicroKernel.Registration.ComponentRegistration`1.Castle.MicroKernel.Registration.IRegistration.Register(IKernelInternal kernel) in c:\BuildAgent\work\9834359f44c23fee\src\Castle.Windsor\MicroKernel\Registration\ComponentRegistration.cs:line 1067
at Castle.MicroKernel.DefaultKernel.Register(IRegistration[] registrations) in c:\BuildAgent\work\9834359f44c23fee\src\Castle.Windsor\MicroKernel\DefaultKernel.cs:line 519
at Castle.Windsor.WindsorContainer.Register(IRegistration[] registrations) in c:\BuildAgent\work\9834359f44c23fee\src\Castle.Windsor\Windsor\WindsorContainer.cs:line 483
at OpenRasta.DI.Windsor.WindsorDependencyResolver.AddDependencyCore(Type dependent, Type concrete, DependencyLifetime lifetime) in C:\Projects\F2-main\src\CBrain.OpenRasta\CBrain.OpenRasta\OpenRasta-Windsor-3\src\OpenRasta.DI.Windsor\WindsorDependencyResolver.cs:line 91
at OpenRasta.DI.Windsor.WindsorDependencyResolver.AddDependencyCore(Type handlerType, DependencyLifetime lifetime) in C:\Projects\F2-main\src\CBrain.OpenRasta\CBrain.OpenRasta\OpenRasta-Windsor-3\src\OpenRasta.DI.Windsor\WindsorDependencyResolver.cs:line 143
at OpenRasta.DI.DependencyResolverCore.AddDependency(Type concreteType, DependencyLifetime lifetime) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\DI\DependencyResolverCore.cs:line 31
at OpenRasta.DI.DependencyManager.GetService(Type dependencyType) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\DI\DependencyManager.cs:line 87
at OpenRasta.Pipeline.Contributors.ResponseEntityWriterContributor.WriteResponse(ICommunicationContext context) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Pipeline\Contributors\ResponseEntityWriterContributor.cs:line 48
at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Pipeline\PipelineRunner.cs:line 187

Question: 415 error with Post and no Content-type header

Is it possible to force OpenRasta to route response when Content-type: application/x-www-form-urlencoded is not specified in post? When this header is included, request is router to handler, but without it returns 415 error. Developer made error in client app witch can't be updated fast, but we need to get the requests now, so looking for hack. Any suggestion?

OpenRasta.IO.HistoryStream breaks XmlSerializer by having CanSeek as true, but the Length property throwing an exception.

It blows XmlSerializerCodec on reading POST payload in XML, because the underlying System.Xml.XmlReader attempts to access the stream Length, if the stream is seekable.

The problem is that LengthTrackingStream forwards the Length request to the underlying stream, because of CanSeek being true. But even if LengthTrackingStream knew not to forward the request, the length known to it at that point is 0.

I do not know the correct fix to it - setting CanSeek to false seems to be dangerous, since I am unaware of all the implications.
So, I return the buffer size as the stream Length property value. It works, because XmlReader only needs it to calculate the buffer size. I will wait for the "official" fix.

OpenID Connect with openrasta?

Is some of the projects I still use OpenRasta with Basic Authentication. I would like to move to OAuth2 with OpenID connect (eg. using identityserver4) but can't find many oAuth examples with newest openrasta-core. Any reference where to start are welcome.

Using a content type extension does not force the codec when an error happens

Hi, here is my scenario:

  • I have registered one xml codec for object (making it the default xml codec) and yet another xml codec for IList<Error> making it the xml codec for exception responses returned on HTTP error 500.
  • There is a request, which returns HTTP error 500.
  • The URL used in the request includes the xml media type extension in order to specifically ask for an XML response.

The net result is that the error response is not returned as XML. Why? Because of two things:

  • the AbortPipeline method nullifies the context.PipelineData.ResponseCodec property set by ContentTypeExtensionUriDecorator
  • ResponseEntityCodecResolverContributor ignores the context.Response.Entity.ContentType property, again set by ContentTypeExtensionUriDecorator

I have no claims towards the AbortPipeline method - the resource has changed, hence the decisions made until now as to the response codec may be wrong. But, context.Response.Entity.ContentType is correct and there is no reason for ResponseEntityCodecResolverContributor to ignore it.

So, I fixed it by replacing this code (inside ResponseEntityCodecResolverContributor):

string acceptHeader = context.Request.Headers[HEADER_ACCEPT];

with the following:

string acceptHeader =
     context.Response.Entity.ContentType == null ?
     context.Request.Headers[HEADER_ACCEPT] :
     context.Response.Entity.ContentType.MediaType;

And everything started working as expected.

BTW, there is a TODO comment in ContentTypeExtensionUriDecorator.Apply:

// TODO: Check if this still works.
entity.ContentType = _selectedCodec.MediaType;

The results of the check - no, it does not work until this bug is fixed.

IUriDecorator.Parse to be renamed in 3.0

From the old group:

We have a project that uses openRasta and we started using Gendarme to do static analysis on it.

One of the defects (or rather in this case, broken conventions) that Gendarme brought up was this:

http://www.mono-project.com/Gendarme.Rules.Design#AvoidRefAndOutParametersRule

The rule is self-explanatory. We couldn't patch our code because it's a class that implements an interface from OpenRasta. So openRasta should be patched instead.

I know it's an API breaking change, but can this be pushed to master? (I mean, not to a stable branch)

Thanks.

High-performance dependency injection

Over the years, we've had many reports of issues with various IoC containers, including the included one, underperforming, breaking between versions, or falling out of maintenance.

As part of moving OpenRasta forward, I suggest a multi-step approach with this lightweight (I hope) design document.

TL;DR
Why:

  • Allow two-way integration between MVC core and OpenRasta for dual stack uses
  • Have faster internal IoC with less contention problems
  • Get integration with all existing containers and get rid of the unmaintained existing implementations

Tasks:

  • Remove dependency on IDependencyResolver from core
  • Integrate with asp.net core dependency injection
  • Benchmarking

Design proposal

Requirements

  • Existing implementations of IDependencyResolver must still work if present
  • OpenRasta must still work without one defined at all, which should be the default
  • Resolving user code should be separate from resolving library code
  • OpenRasta services must still be available in user code, both without or with IoC integration
  • User code must be able to register custom dependencies as part of registration like it used to, as this is used by various customers
  • Preserve IDependencyResolverAccessor semantics for system.web integration

Step 1: Remove dependency on IDependencyResolver from core

This steps is necessary for two reasons: because the code bleeds service location in quite a few places, making it hard to be IoC transparent; and because it will highlight the clear boundary between OpenRasta's services, and user code.

This will be achieved by keeping factories in code, as a user-overridable set of Funcs.

Once the core doesn't depend on IDependencyResolver, we'll mark that interface as obsolete, and provide a utility method to rewire the various factories to that implementation. This will be the default for System.Web integration, and will be available for custom configuration in non-asp.net scenarios.

At that point, there should be 0 functional change after that first major refactoring.

Step 2: Integrate with asp.net core dependency injection

OpenRasta's normative container approach was a bad idea, as it is both a support time sink and only allow a baseline of features, killing ioc container competition.

For better or worse however, Microsoft went down that path for asp.net mvc core.

Integrating MS' depenency injection code as an optional component, using features above, allows two features that will be useful for many: it allows two way integration between OpenRasta and other web frameworks, and it gets integration with all containers for free, allowing us to kill all custom ioc integration packages still lingering on github.

This will be achieved by integrating, as a separate package, the MS implementation, using the same extracted factories implemented in Step 1.

Step 3: Benchmarking

Once this is all done, it would be essential to do some benchmarking, showing before and after performance, and making sure code paths don't regress. It'd be useful as well to create a load test environment to measure load on some core scenarios customers currently use.

AspNet.OpenRastaModule always defaults to IIS6, even for IIS7

OpenRasta.Hosting.AspNet.OpenRastaModule.VerifyIisDetected ()ignores ServerVariable and defaults to IIS6, even for IIS7.
The problem is this line:

internal const string SERVER_SOFTWARE_KEY = "SERVER_SOFTWARE_KEY";

Should be:

internal const string SERVER_SOFTWARE_KEY = "SERVER_SOFTWARE";

The invalid line causes VerifyIisDetected() to skip the entire if-slashpos-then-parse-server-software-branch so iisversion is not set which causes Iis to default to new IIS6()

Headers are written after Body

I'm attempting to make a Owin self hosting using Owin MIddleware, I have come across a problem where the codec is called and writes to the stream, however this happens before the headers are written. The symptom of this problem is an attempt to add a "content-length" header but one already exists in the OwinContext with a value of -1, amending it fires an error as the stream has already been written.

Owin response (In Owin self hosting)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Owin;
using OpenRasta.DI;
using OpenRasta.Web;

namespace OpenRasta.Owin
{
    public class OwinResponse : IResponse
    {
        public OwinResponse(IOwinContext context )
        {
            var response = context.Response;

            NativeContext = response;
            Headers = new HttpHeaderDictionary();
            Entity = new HttpEntity(Headers, response.Body);
        }

        private IOwinResponse NativeContext { get; set; }
        public IHttpEntity Entity { get; private set; }
        public HttpHeaderDictionary Headers { get; private set; }
        public bool HeadersSent { get; private set; }
        public int StatusCode { get; set; }

        public void WriteHeaders()
        {
            if (HeadersSent)
                throw new InvalidOperationException("The headers have already been sent.");
            foreach (var header in Headers.Where(h => h.Key != "Content-Type"))
            {
                try
                {
                    NativeContext.Headers.Remove(header.Key);
                    NativeContext.Headers.Append(header.Key, header.Value);
                }
                catch (Exception ex)
                {
                    var commcontext = DependencyManager.GetService<ICommunicationContext>();
                    if (commcontext != null)
                    {
                        commcontext.ServerErrors.Add(new Error {Message = ex.ToString()});
                    }
                }
            }
            HeadersSent = true;
            if (Headers.ContentType != null)
            {
                NativeContext.Headers.Add(new KeyValuePair<string, string[]>("Content-Type", new[] {Headers.ContentType.MediaType}));
            }
        }
    }
}

Codec

 public void WriteTo(object entity, IHttpEntity response, string[] codecParameters)
    {
        if (entity == null)
        {
            return;
        }

        var output = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(entity));
        response.Stream.Write(output, 0, output.Length);


        response.ContentType = new MediaType("application/json") {CharSet = "utf-8"};
    }

Potential Problem Code (ResponseEntityWriterContributor)

                Log.WriteDebug("Codec {0} selected.", codecInstance.GetType().Name);
                if (context.PipelineData.ResponseCodec != null &&
                    context.PipelineData.ResponseCodec.Configuration != null)
                    codecInstance.Configuration = context.PipelineData.ResponseCodec.Configuration;

                using (Log.Operation(this, "Generating response entity."))
                {
                    codecInstance.WriteTo(
                        context.Response.Entity.Instance,
                        context.Response.Entity,
                        context.Request.CodecParameters.ToArray());
                    PadErrorMessageForIE(context);

                    Log.WriteDebug("Setting Content-Length to {0}", context.Response.Entity.Stream.Length);
                    context.Response.Entity.ContentLength = context.Response.Entity.Stream.Length;
                }
            }
        }
        SendResponseHeaders(context);
        return PipelineContinuation.Finished;

I tried this change

        Log.WriteDebug("Codec {0} selected.", codecInstance.GetType().Name);
                if (context.PipelineData.ResponseCodec != null &&
                    context.PipelineData.ResponseCodec.Configuration != null)
                    codecInstance.Configuration = context.PipelineData.ResponseCodec.Configuration;

                SendResponseHeaders(context);//<<<<<<<<
                using (Log.Operation(this, "Generating response entity."))
                {
                    codecInstance.WriteTo(
                        context.Response.Entity.Instance,
                        context.Response.Entity,
                        context.Request.CodecParameters.ToArray());
                    PadErrorMessageForIE(context);

                    Log.WriteDebug("Setting Content-Length to {0}", context.Response.Entity.Stream.Length);
                    context.Response.Entity.ContentLength = context.Response.Entity.Stream.Length;
                }
            }
        }
        return PipelineContinuation.Finished;

which works for all headers but the "Content-Length" is done after the codec runs.

Suggested solution

Ideally the write that was done in the codec would just be put in a holder stream (Memory) and appended after we write the headers

   var tempResponseEntity = new HttpEntity(context.Response.Headers, new MemoryStream());
                    codecInstance.WriteTo(
                        context.Response.Entity.Instance,
                        tempResponseEntity,
                        context.Request.CodecParameters.ToArray());
                    PadErrorMessageForIE(context);

                    Log.WriteDebug("Setting Content-Length to {0}", context.Response.Entity.Stream.Length);
                    context.Response.Entity.ContentLength = context.Response.Entity.Stream.Length;
......Write headers and then write this memory stream.

Failure in multipart shoudl trigger 400, not 500

Hi,

currently when the multipart request is wrong (boundary messed up) openrasta returns 500

System.InvalidOperationException: The operation is not ready for invocation.
at OpenRasta.OperationModel.MethodBased.MethodBasedOperation.Invoke() in d:\dev\git-repos\openrasta-stable\src\core\OpenRasta\OperationModel\MethodBased\MethodBasedOperation.cs:line 58
at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.b__0() in d:\dev\git-repos\openrasta-stable\src\core\OpenRasta\OperationModel\Interceptors\OperationWithInterceptors.cs:line 47
at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.Invoke() in d:\dev\git-repos\openrasta-stable\src\core\OpenRasta\OperationModel\Interceptors\OperationWithInterceptors.cs:line 52
at OpenRasta.OperationModel.OperationExecutor.Execute(IEnumerable`1 operations) in d:\dev\git-repos\openrasta-stable\src\core\OpenRasta\OperationModel\OperationExecutor.cs:line 14
at OpenRasta.Pipeline.Contributors.OperationInvokerContributor.ExecuteOperations(ICommunicationContext context) in d:\dev\git-repos\openrasta-stable\src\core\OpenRasta\Pipeline\Contributors\OperationInvokerContributor.cs:line 29
at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call) in d:\dev\git-repos\openrasta-stable\src\core\OpenRasta\Pipeline\PipelineRunner.cs:line 192

Is it possible to have back a 400 bad request ?

tnx

Domenico

Provide a better HttpListenerServer implementation

The current hosting environment enforces inheritance and was not really built to be used without the AppDomain separation. A new class ought to be built that makes that hosting easier and allow for setting certain properties on the actual HttpListener instance.

Multipart request validation

Hi,

currently when the multipart request is wrong (boundary messed up) openrasta returns 500

System.InvalidOperationException: The operation is not ready for invocation.
at OpenRasta.OperationModel.MethodBased.MethodBasedOperation.Invoke() in d:\dev\git-repos\openrasta-stable\src\core\OpenRasta\OperationModel\MethodBased\MethodBasedOperation.cs:line 58
at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.<Invoke>b__0() in d:\dev\git-repos\openrasta-stable\src\core\OpenRasta\OperationModel\Interceptors\OperationWithInterceptors.cs:line 47
at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.Invoke() in d:\dev\git-repos\openrasta-stable\src\core\OpenRasta\OperationModel\Interceptors\OperationWithInterceptors.cs:line 52
at OpenRasta.OperationModel.OperationExecutor.Execute(IEnumerable`1 operations) in d:\dev\git-repos\openrasta-stable\src\core\OpenRasta\OperationModel\OperationExecutor.cs:line 14
at OpenRasta.Pipeline.Contributors.OperationInvokerContributor.ExecuteOperations(ICommunicationContext context) in d:\dev\git-repos\openrasta-stable\src\core\OpenRasta\Pipeline\Contributors\OperationInvokerContributor.cs:line 29
at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call) in d:\dev\git-repos\openrasta-stable\src\core\OpenRasta\Pipeline\PipelineRunner.cs:line 192

Is it possible to have back a 400 bad request ?

tnx

Domenico

Incorrect HTTP status code when a Codec's ReadFrom() throws

When an exception is thrown from a Codec's ReadFrom() method, OpenRasta currently returns to the client an Http 405 Method Not Allowed status code.

I think this is the incorrect status code, perhaps it should be 406 Not Acceptable to indicate there's something wrong with the payload.

Malformed Accept header causes loop and 100%CPU

Ported over from legacy github openrasta/archived-openrasta-legacy#31

A malformed Accept header can cause an error loop which brought our sever down. The issue resides in
/web/mediatype.cs, MediaType.Parse
passing it a delimited list of types where one is not a valid type or is malformed will cause the issue.
We modified our copy with a try catch around an idividual List.Add call but doubtless there is a more elegant solution.

POST method with parameter gets selected without the uri having it

From openrasta/archived-openrasta-legacy#29

Hi, It seems to choose the wrong method for posting in this situation:
it chooses the override with the Int/account_id with a higher score than the one without, even though the url I'm posting to is the simpler one. Is this something I'm missing at configuration level?

Configuration:

            ResourceSpace.Has.ResourcesOfType<DomainResourceNew>()
                .AtUri("/domain/new")
                .And.AtUri("/account/{account_id}/domain/new")
                .HandledBy<DomainHandlerNew>()
                .RenderedByAspx("~/Views/domain/DomainViewNew.aspx")
                .And.AsJsonDataContract()
                .And.AsXmlDataContract();

5-[2011-12-20 11:58:54Z] Verbose(0) Starts pre-executing the request.
5-[2011-12-20 11:58:54Z] Verbose(0) Incoming host request for http://localhost:61073/domain/new
5-[2011-12-20 11:58:54Z] Verbose(0) Adding communication context data
5-[2011-12-20 11:58:54Z] Warning(0) Contributor call for BootstrapperContributor had a null Action.
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor HttpMethodOverriderContributor.OverrideHttpVerb
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor DigestAuthorizerContributor.ReadCredentials
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor UriDecoratorsContributor.ProcessDecorators
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor ResourceTypeResolverContributor.ResolveResource
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Verbose(0) Rewrote path.
5-[2011-12-20 11:58:54Z] Start(1) Entering OpenRastaRewriterHandler: Rewriting to original path
5-[2011-12-20 11:58:54Z] Start(1) Entering OpenRastaIntegratedHandler: Request for http://localhost:61073/domain/new
5-[2011-12-20 11:58:54Z] Verbose(0) Incoming host request for http://localhost:61073/domain/new
5-[2011-12-20 11:58:54Z] Verbose(0) Adding communication context data
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor HandlerResolverContributor.ResolveHandler
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor OperationCreatorContributor.CreateOperations
5-[2011-12-20 11:58:54Z] Verbose(0) Created operation named Get wth signature DomainHandlerNew::Get()
5-[2011-12-20 11:58:54Z] Verbose(0) Created operation named Get wth signature DomainHandlerNew::Get(Int32 account_id)
5-[2011-12-20 11:58:54Z] Verbose(0) Created operation named Post wth signature DomainHandlerNew::Post(DomainResourceNew post)
5-[2011-12-20 11:58:54Z] Verbose(0) Created operation named Post wth signature DomainHandlerNew::Post(Int32 account_id, DomainResourceNew post)
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor OperationFilterContributor.ProcessOperations
5-[2011-12-20 11:58:54Z] Verbose(0) Found 2 operation(s) with a matching name.
5-[2011-12-20 11:58:54Z] Verbose(0) Found 0 operation(s) with matching [HttpOperation] attribute.
5-[2011-12-20 11:58:54Z] Verbose(0) No resource or no uri name. Not filtering.
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor OperationCodecSelectorContributor.ProcessOperations
5-[2011-12-20 11:58:54Z] Information(0) Operation DomainHandlerNew::Post(Int32 account_id, DomainResourceNew post) selected with 2 required members and 0 optional members, with codec ApplicationXWwwFormUrlencodedKeyedValuesCodec with score 0.8333334.
5-[2011-12-20 11:58:54Z] Information(0) Operation DomainHandlerNew::Post(DomainResourceNew post) selected with 1 required members and 0 optional members, with codec ApplicationXWwwFormUrlencodedKeyedValuesCodec with score 0.5.
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor OperationHydratorContributor.ProcessOperations
5-[2011-12-20 11:58:54Z] Information(0) Operation DomainHandlerNew::Post(Int32 account_id, DomainResourceNew post) was selected with a codec score of 0.8333334
5-[2011-12-20 11:58:54Z] Information(0) Loaded codec OpenRasta.Codecs.ApplicationXWwwFormUrlencodedKeyedValuesCodec
5-[2011-12-20 11:58:54Z] Information(0) Codec supports IKeyedValuesMediaTypeReader. Processing parameters.
5-[2011-12-20 11:58:54Z] Verbose(0) Key domain_name was not successfully assigned.
5-[2011-12-20 11:58:54Z] Verbose(0) Key submit was not successfully assigned.
5-[2011-12-20 11:58:54Z] Verbose(0) Key domain_name was successfully assigned.
5-[2011-12-20 11:58:54Z] Verbose(0) Key submit was not successfully assigned.
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor OperationInterceptorContributor.WrapOperations
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor OperationInvokerContributor.ExecuteOperations
5-[2011-12-20 11:58:54Z] Verbose(0) Ignoring constructor, following dependencies didn't have a registration:OpenRasta.OperationModel.Interceptors.IOperationInterceptor[]
A first chance exception of type 'System.InvalidOperationException' occurred in OpenRasta.DLL
5-[2011-12-20 11:58:54Z] Error(0) An error of type System.InvalidOperationException has been thrown
5-[2011-12-20 11:58:54Z] Error(0) System.InvalidOperationException: The operation is not ready for invocation.
5-[2011-12-20 11:58:54Z] Error(0) at OpenRasta.OperationModel.MethodBased.MethodBasedOperation.Invoke() in c:_Projects\SteveDunn-openrasta-stable-0acdf3b\SteveDunn-openrasta-stable-0acdf3b\src\core\OpenRasta\OperationModel\MethodBased\MethodBasedOperation.cs:line 56
5-[2011-12-20 11:58:54Z] Error(0) at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.b__0() in c:_Projects\SteveDunn-openrasta-stable-0acdf3b\SteveDunn-openrasta-stable-0acdf3b\src\core\OpenRasta\OperationModel\Interceptors\OperationWithInterceptors.cs:line 47
5-[2011-12-20 11:58:54Z] Error(0) at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.Invoke() in c:_Projects\SteveDunn-openrasta-stable-0acdf3b\SteveDunn-openrasta-stable-0acdf3b\src\core\OpenRasta\OperationModel\Interceptors\OperationWithInterceptors.cs:line 52
5-[2011-12-20 11:58:54Z] Error(0) at OpenRasta.OperationModel.OperationExecutor.Execute(IEnumerable`1 operations) in c:_Projects\SteveDunn-openrasta-stable-0acdf3b\SteveDunn-openrasta-stable-0acdf3b\src\core\OpenRasta\OperationModel\OperationExecutor.cs:line 14
5-[2011-12-20 11:58:54Z] Error(0) at OpenRasta.Pipeline.Contributors.OperationInvokerContributor.ExecuteOperations(ICommunicationContext context) in c:_Projects\SteveDunn-openrasta-stable-0acdf3b\SteveDunn-openrasta-stable-0acdf3b\src\core\OpenRasta\Pipeline\Contributors\OperationInvokerContributor.cs:line 29
5-[2011-12-20 11:58:54Z] Error(0) at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call) in c:_Projects\SteveDunn-openrasta-stable-0acdf3b\SteveDunn-openrasta-stable-0acdf3b\src\core\OpenRasta\Pipeline\PipelineRunner.cs:line 172
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Error(0) Aborting the pipeline and rendering the errors.
5-[2011-12-20 11:58:54Z] Error(0) An error has occurred and the processing of the request has stopped.

Exception:
System.InvalidOperationException: The operation is not ready for invocation.
at OpenRasta.OperationModel.MethodBased.MethodBasedOperation.Invoke() in c:_Projects\SteveDunn-openrasta-stable-0acdf3b\SteveDunn-openrasta-stable-0acdf3b\src\core\OpenRasta\OperationModel\MethodBased\MethodBasedOperation.cs:line 56
at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.b__0() in c:_Projects\SteveDunn-openrasta-stable-0acdf3b\SteveDunn-openrasta-stable-0acdf3b\src\core\OpenRasta\OperationModel\Interceptors\OperationWithInterceptors.cs:line 47
at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.Invoke() in c:_Projects\SteveDunn-openrasta-stable-0acdf3b\SteveDunn-openrasta-stable-0acdf3b\src\core\OpenRasta\OperationModel\Interceptors\OperationWithInterceptors.cs:line 52
at OpenRasta.OperationModel.OperationExecutor.Execute(IEnumerable`1 operations) in c:_Projects\SteveDunn-openrasta-stable-0acdf3b\SteveDunn-openrasta-stable-0acdf3b\src\core\OpenRasta\OperationModel\OperationExecutor.cs:line 14
at OpenRasta.Pipeline.Contributors.OperationInvokerContributor.ExecuteOperations(ICommunicationContext context) in c:_Projects\SteveDunn-openrasta-stable-0acdf3b\SteveDunn-openrasta-stable-0acdf3b\src\core\OpenRasta\Pipeline\Contributors\OperationInvokerContributor.cs:line 29
at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call) in c:_Projects\SteveDunn-openrasta-stable-0acdf3b\SteveDunn-openrasta-stable-0acdf3b\src\core\OpenRasta\Pipeline\PipelineRunner.cs:line 172
5-[2011-12-20 11:58:54Z] Verbose(0) Pipeline is in RenderNow mode.
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor OperationResultInvokerContributor.RunOperationResult
5-[2011-12-20 11:58:54Z] Information(0) Executing OperationResult OperationResult: type=InternalServerError, statusCode=500.
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor ResponseEntityCodecResolverContributor.FindResponseCodec
5-[2011-12-20 11:58:54Z] Information(0) Selected codec HtmlErrorCodec out of 4 codecs for entity of type ServerErrorList and negotiated media type text/html.
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor DigestAuthorizerContributor.WriteCredentialRequest
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Start(1) Entering PipelineRunner: Executing contributor ResponseEntityWriterContributor.WriteResponse
5-[2011-12-20 11:58:54Z] Verbose(0) Codec HtmlErrorCodec selected.
5-[2011-12-20 11:58:54Z] Start(1) Entering ResponseEntityWriterContributor: Generating response entity.
5-[2011-12-20 11:58:54Z] Verbose(0) Setting Content-Length to 512
5-[2011-12-20 11:58:54Z] Stop(1) Exiting ResponseEntityWriterContributor
5-[2011-12-20 11:58:54Z] Verbose(0) Writing http headers.
5-[2011-12-20 11:58:54Z] Verbose(0) Writing http header Content-Length:512
5-[2011-12-20 11:58:54Z] Verbose(0) Writing http header Content-Type:text/html
5-[2011-12-20 11:58:54Z] Stop(1) Exiting PipelineRunner
5-[2011-12-20 11:58:54Z] Information(0) Pipeline finished.
5-[2011-12-20 11:58:54Z] Stop(1) Exiting OpenRastaIntegratedHandler
5-[2011-12-20 11:58:54Z] Stop(1) Exiting OpenRastaRewriterHandler
5-[2011-12-20 11:58:54Z] Verbose(0) Request finished.
The thread '' (0x24a4) has exited with code 0 (0x0).

null returned from handlers to return different response codes

Today, a GET handler must explicitly return an OperationResult.NotFound instance, because null is not automatically treated as 404. This makes handler signatures less type safe.

For instance, instead of the strongly typed:

public MyResource Get(int id) { ... }

one has to declare the following weakly typed method:

public OperationResult Get(int id) { ... }

Furthermore, in some cases, 415 is returned (when the pipeline resumes in an error condition) and that needs fixing too.

UriTemplate & encoded URIs

Currently the UriTemplate class does not do any kind of URI encoding when doing BindingByName.

Here is a test that will fail

BindingUriByName("/{value}", new { value = "?query" }).ShouldAllBe("http://localhost/foo/%3Fquery");

Are the consumers of the class, such as when using object.CreateUri(), expected to supply Uri Escaped Values?

Building openrasta-core

I am having trouble building openrasta-core for .Net 3.5, I have downloaded the latest package and have tried following:

  1. Ran make.bat as suggested on "Downloading and Compiling OpenRasta" but get OpenWrap.tasks not found message. (I have tried running OpenWrap but it doesn't find the site)
  2. On trying to open and compile the OpenRasta.csproj in VS2008 I get compilation issues (this seems like a .Net 4.0 project)

Kindly help.
Arun

Compiling OpenRasta

Hi,
What are the current steps for compiling openrasta-core on a clean machine?

I have tried to follow the wiki but make.bat does not exist in the master or 2.1 branches.

The only reference I can find to make.bat is a commit from Jan 2012 but it has since been deleted.

I'm completely new to OpenRasta but would really like to try using it for our new webservice,

Thanks

POST using application/x-www-form-urlencoded correct parameters mapped for handler

When POSTing to an endpoint using content-type: application/x-www-form-urlencoded and a request body that does not map to a handler results in a 500 response.

In this example we do not have a method mapped that accepts foo as a parameter.

Request Header

Content-Length: 7
content-type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate, compress

Request Body

foo=bar

Actual Result

Response Header

HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Length: 786
Content-Type: application/xml
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET

Response Body

<?xml version="1.0" encoding="utf-8"?>
<errorResult xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <error>Sorry, an internal error has occurred

DEBUG ONLY
System.InvalidOperationException: The operation is not ready for invocation.
   at OpenRasta.OperationModel.MethodBased.MethodBasedOperation.Invoke()
   at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.Invoke()
   at OpenRasta.OperationModel.OperationExecutor.Execute(IEnumerable`1 operations)
   at OpenRasta.Pipeline.Contributors.OperationInvokerContributor.ExecuteOperations(ICommunicationContext context)
   at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call)</error>
</errorResult>

Expected Result

Response Header

HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Type: application/xml
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET

Pipeline Contributors cannot always determine the selected handler

We have created a logging contributor in our OpenRasta (OR) pipeline.

We have tried adding this at various stages in the pipeline. None seem able to identify the single Handler that was invocated.

It seems that under certain conditions, the value of ICommunicationContext.PipelineData.SelectedHandlers.Count > 1. This is despite the fact that only 1 handler is invoked (without error).

I'm sure our particular conditions aren't typical, but nonetheless OR internally copes, even if the pipeline doesn't look quite right.

We have the following config:

ResourceSpace.Has.ResourcesOfType<MyView>()
        .AtUri("/user/{userId}/received")
        .HandledBy<ReceivedController>()
        .AsDefaultJsonXmlAtomTranscodersAndExtensions();

ResourceSpace.Has.ResourcesOfType<NotificationsReceivedView>()
        .AtUri("/user/{userId}/received/last")
        .HandledBy<ReceivedLastController>()
        .AsDefaultJsonXmlAtomTranscodersAndExtensions();

When I issue a GET to "/user/{userId}/received" the pipeline always shows 2 SelectedHandlers through the pipeline.

I could be missing something but I'm fairly sure it's an issue with OR. Please do correct me if I'm wrong!

And yes, the routes etc aren't optimal!

Transfer-Encoding: chunked returns unsupported media type

Transfer-Encoding: chunked returns unsupported media type

I have a handler that I'm sending a PUT request to with some data.

curl -i http://example.com/ -X PUT -d "Some text" --header "Content-Type: text/plain"
> HTTP/1.1 200 OK

If I add a Transfer-Encoding: chunked header I get a 415

curl -i http://example.com/ -X PUT -d "Some text" --header "Content-Type: text/plain" --header "Transfer-Encoding: chunked"
> HTTP/1.1 415 Unsupported Media Type

I've tracked it down to this line: https://github.com/openrasta/openrasta-core/blob/master/src/OpenRasta/OperationModel/CodecSelectors/RequestCodecSelector.cs#L31

In the chunked instance the ContentLength is null

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.