Fredrick Lackey - 478 - Feb 24, 2014

Need some help with an odd scenario.  A 404 error is detected after pushing approx 50 files to the server (synchronous / blocking) using WebRequest.  After disposing of the current requested, all future responses are returned as XML… despite the previous 50 (approx) requests returning JSON.  Any ideas how to troubleshoot this?  The 404 itself is killing me since all previous & subsequent calls are successful… except they return XML.

Fredrick Lackey:

There have been two additional edits to the ServiceStack post.  The last edit, from 12:20 PM shows the headers from session 560.  This has a 404 from IIS as well as the friendly message in HTML format.

FYI I’ve left a comment wanting to see the raw HTTP Request / Responses at the time the service starts to return XML. You can use Fiddler to get these.

Fredrick Lackey:

Sorry it took so long to respond.  I think I understand why the JSON request is being ignored… because an XML file was sent in the stream.  Not a great find, but it makes sense.  I’m still puzzled why a 404 is being detected for sporadic requests.  Anyway, the info is on ServiceStack. 

Can you post the HTTP for the 404 Requests? hard to see what’s happening without it.

Fredrick Lackey:

Done.  The only consistent fact about the files is they are all text-based.  However, a large number of other text-based files were submitted without issue… both before and after the failures.

Right, but where’s the HTTP Request that generated that HTTP Response? Please include the actual request that generated the 404 response.

But something telling from the Response is that it looks like IIS is returning the 404 before the request reaches ServiceStack.

ahh ok I see it, I thought that was a C# class source file, I now see that it’s apart of a HTTP Request. Great what’s the Route definition? Does it end with a {PathInfo*}? also if you upload that file on its own does it succeed?

Fredrick Lackey:

Three routes…

[Route("/Files/Put", “POST”)]
[Route("/Files/Put/{Token}/{Checksum}/{SizeBytesText}", “POST”)]
[Route("/Files/Put/{Token}/{Checksum}/{SizeBytesText}/{FileNameOrExtension}", “POST”)]

And does the request work when its run on its own? If it does I might need to repro this locally to investigate what the issue is, can you post the C# DTO’s used.

Also can you try if this makes a difference:
client.KeepAlive = false;

Fredrick Lackey:

I’ve added to the post and included both the DTO and a test console app.  The file CAN be read successfully, using a FileStream, which shows the file is intact.  However it will ALWAYS cause a 404.  

I had originally thought this had something to do with tacking on the file name.  Possibly the extension was causing a problem.  However, countless other files, with the same exact extension, go through just fine.

On a side note, I’ve also noticed that SS sends back an HTML response if the file sent to the server is an HTML file… regardless of the Accept header.  This renders the entire response useless.

Fredrick Lackey:

Sorry.  Just noticed your comment from 2:40 PM.  As requested, I set the KeepAlive flag to false.  No change.

Fredrick Lackey:

I’ve posted my findings and workaround to the question.  Long story short, if the path appears to have a file name, ServiceStack responds with a response matching the content type in the ResponseStream.  If the path is formatted in such a way that the a logical file name cannot be assumed (ie “…/ReadMe.HTML” becomes “…/ReadMe/HTML”) the result is always the type requested in the Accept header.  Most importantly, no 404 errors.

Ahh yes, the extension is going to override the response format if its one of the registered formats in your ServiceStack service. and .xml / .html are enabled by default. Also instead of converting to use slashes and maintaining multiple routes, you could just make use of the querystring.

As for the 404 issue, if it’s one of these formats ServiceStack will strip the extension from the PathInfo as it assumes that it’s superflous and just used to specify the response type and your Service might not be finding the file so is throwing a not found.

The other culprit (more likely because I don’t see ServiceStack in the response headers) is IIS hijacking the request before it reaches ServiceStack because it assumes its a static file that doesn’t exist, e.g:

Glad its resolved!