HTTP Server response - wrong content type? - c#

I'm making a server that should be able to store some images and then send/stream them to a client upon request. I've managed to get the server to respond with an image when I request it from a web browser, but when I send the very same HTTP request to the server from my client application, I'm not sure what exactly happens (it's supposed to become a tile map server at some point, but I'm starting out easy with just a single image here).
If it's of any help, here's an output from my web browser request: http://i.imgur.com/tG04qvS.png
And here the other one is: http://i.imgur.com/GUqdawF.png
Fiddler is saying I'm returning Content-Type: text/html; charset=UTF-8 which in my head sounds horribly wrong when trying to return an image.
I've been digging around a little more and it seems the response is empty. It smells like my server isn't delivering the image properly to the client since I'm just using this piece of code to respond to the request:
if (p.http_url.Equals("/MapServer/tile/0/0/0"))
{
Stream fs = File.Open("../MapServer/tile/0,0,0.png", FileMode.Open);
p.writeSuccess("image/jpeg");
fs.CopyTo(p.outputStream.BaseStream);
p.outputStream.BaseStream.Flush();
fs.Close();
}
I'm using StreamWriter for my stream. Is that the one giving me the content_type problems?

HTTP servers map content type through other mechanisms. A Stream is too low-level to convey that kind of information; it doesn't distinguish between series of bytes for a text file or an image.
The Content-type Saga
Content Negotiation
Configuring MIME Types in IIS 7
Try building your service to return something from the System.Net.Http namespace like HttpResponseMessage. These classes have the ability to provide more information about the type of document being sent.

Related

WebSocket connection issues using c#

The response from the server is not a valid HTTP response. This problem occurs when the .NET Framework detects that the server response does not comply with HTTP 1.1 RFC. This problem may occur when the response contains incorrect headers or incorrect header delimiters.RFC 2616 defines HTTP 1.1 and the valid format for the response from the server. For more information, see RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1 at Internet Engineering Task Force (IETF) website.
Get a network trace of the transaction and examine the headers in the response.
If your application requires the server response without parsing (this could be a security issue), set useUnsafeHeaderParsing to true in the configuration file. See Element
It seems like you just forgentting to clear the buffer before you receive new message.
2 quick options for you:
-add '\0' in the end of each of your messages on your server side. This will prevent gliches like that from happening.
-use Array.Clear(buffer,0,buffer.length) to clear buffer before receiving on your client side.

How to extract binary attachment from a WCF SOAP response?

I'm writing a .Net 3.5 solution which is consuming a 3rd party WCF web service. The proxy client for the SOAP service was generated by VisualStudio as a service reference.
A SOAP response from the service includes attachments in the data, as I can see it in fiddler. The attachments have a href field which points to a CID reference. The proxy client that VS 2012 has created when returning the object which includes the attachments doesn't include any binary data, but it does include the href field with the CID reference in it.
As captured using fiddler, this is the SOAP response attachment data including the cid:xxxx ref:
<attachments>
<cmn:attachment href="cid:52b2d8a50035921e80bf1540" len="309" name="DOC1.rtf" type="application/rtf" xmime:contentType="application/rtf"/>
</attachments>
And in the raw output in fiddler, the attachment data can be seen with the matching cid:xxxx ref:
------=_Part_22_12445037.1389617382038
Content-Type: application/rtf
Content-Location: DOC1.rtf
Content-ID: <52b2d8a50035921e80bf1540>
Content-Transfer-Encoding: binary
{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
{\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\sa200\sl276\slmult1\lang9\f0\fs22 Doc 1\par
\par
Test information inside an attachment for KM retrieval.\par
\par
Here's something else I've written for use in testing.\par
}
Here is a screenshot of the available fields from the returned object:
How do I access that attachment data so I can actually download the file?
Normally with WCF and SOAP, your file binary is encoded as a base64 string somewhere in your response, however I don't see in what you've posted here the kind of long data string I'd be expecting.
If what you're showing here is just the header from the response, you might check the body of the response message,too, since the header has a size limit, but the body the message doesn't - it's therefore the likely place for your binary payload.
Wouldn't it be easier to return a byte[] in one of the entities you are returning, and then work from that on your client to reconstruct the file?
Are you using MTOM? Because WCF does not support SwA (Soap with attachments) out of the box.
Turns out that the issue was due to the way the 3rd party API was returning the response, the MTOM data was not correctly formatted so WCF was ignoring the binary data.
The way I got around this was by using a bespoke class which basically uses an HttpRequest to talk directly to the web service and extract/parse the binary data out of the response.

Getting a raw socket from an IIS request

I'm trying to get the raw data sent to IIS using a HttpHandler. However, because the request is an "GET"-request without the "Content-Length" header set it reports that there is no data to read (TotalBytes), and the inputstream is empty. Is there any way I can plug into the IIS-pipeline (maybe even before the request is parsed) and just kind of take control over the request and read it's raw data? I don't care if I need to parse headers and stuff like that myself, I just want to get my hands on the actual request and tell IIS to ignore this one. Is that at all possible? Cause right now it looks like I need to do the alternative, which is developing a custom standalone server, and I really don't want to do that.
Most web servers will ignore (and rarely give you access to) the body of a GET request, because the HTTP semantics imply that it is to be ignored anyway. You should consider another method (for example POST or PUT).
See this question and the link in this answer:
HTTP GET with request body

Icecast 2: protocol description, streaming to it using C#

I need to write an Icecast 2 client that will be able to stream audio from the computer (mp3-files, soundcard recording and so forth) to the server. I decided to write such a client on C#.
Two questions:
1) It will be very useful to know common guidelines (best practices, maybe tricks) I may/should/must use to seamlessly work with streamed audio (streamed over network, of course) in C#. Some general technical documentation about streaming over TCP/IP in common and ICY in particular, advices and notes on the overall architecture of the application will be very appreciated.
2) Is there any good documentation regarding the Icecast 2 streaming protocol? I couldn't find those docs on the official site of Icecast. I don't want to extract the protocol description directly from the source code of it. If the protocol is really simple and neat, could anybody provide a summary of it right here?
As far as I know, there is no protocol spec anywhere, outside of the Icecast source code. Here's what I've found from packet sniffing:
Audio Stream
The protocol is similar to HTTP. The source client will connect to the server make a request with the mountpoint, and pass some headers with information about the stream:
SOURCE /mp3test ICE/1.0
content-type: audio/mpeg
Authorization: Basic c291cmNlOmhhY2ttZQ==
ice-name: This is my server name
ice-url: http://www.google.com
ice-genre: Rock
ice-bitrate: 128
ice-private: 0
ice-public: 1
ice-description: This is my server description
ice-audio-info: ice-samplerate=44100;ice-bitrate=128;ice-channels=2
If all is good, the server responds with:
HTTP/1.0 200 OK
The source client then proceeds to send the binary stream data. Note that it seems some encoders don't even wait for the server to respond with 200 OK before they start sending stream data. Just headers, an empty line, and then stream data.
Meta Data
Meta data is sent using an out-of-band HTTP request. The source client sends:
GET /admin/metadata?pass=hackme&mode=updinfo&mount=/mp3test&song=Even%20more%20meta%21%21 HTTP/1.0
Authorization: Basic c291cmNlOmhhY2ttZQ==
User-Agent: (Mozilla Compatible)
The server responds with:
HTTP/1.0 200 OK
Content-Type: text/xml
Content-Length: 113
<?xml version="1.0"?>
<iceresponse><message>Metadata update successful</message><return>1</return></iceresponse>
Also note that both the audio stream and meta data requests are sent on the same port. Unlike SHOUTcast, this is the base port that the server is running on.
I'm going to comment here despite this question being quite old.
Icecast is HTTP compliant. This was always the case for the listener side (plain and simple HTTP1.0, RFC 1945), starting with 2.4.0 it's also true for the source client side.
To implement a source client it's a PUT request in compliance with HTTP 1.1 aka RFC2616. Some options can be set through HTTP headers, for details please refer to the current Icecast documentation.
If you send one of the supported container formats: Ogg or WebM (technically EBML), then this is all you need to know. To make it clear this covers at leastOpus, Vorbis, Theora and VP8 codecs.
Please note that while generally working fine, other formats are technically not supported. Icecast only passes through the stream without any processing in such a case.
If you need help or have further questions, then the official mailing lists and the IRC channel are the right place to go.
Looked at Icecast2 a good long while ago: best reference I could find was at http://forums.radiotoolbox.com/viewtopic.php?t=74 link (I should print that out, took me forever to figure out the proper Google spell to cast to surface that again). It appears to cover source to server and server to client.
Questions remain about just how accurate it is: I got about halfway through an Android implementation before other things consumed me, and I can't quite remember what was wrong with the communication between my implementation of that and VLC/Winamp, but honestly it was the closest thing I could find to a spec.
The best description I know is here: https://gist.github.com/ePirat/adc3b8ba00d85b7e3870
#ePirat is xpiph/icecast core committer.

getting content-length using sockets

Can anyone guide me in acquiring the POST content-length of a website by just using sockets. Thanks and Kudos!
(I'm avoiding using httpwebrequest for some reason)
If it's a proxy application you don't need to be parsing headers at all. You just need to mirror the data from one side to the other, as bytes. The only thing you need to parse is for example the initial HTTP CONNECTION request, or whatever your initial handshake with the client is that causes you to set up the upstream connection. The rest of it is just byte copying and EOS and error propagation.
In the Http protocol the header is seperated from the content by a double crlf.
So you could either parse the header and get the Content-Length header or you can figure out the length of the content (since you know where the header ends and content starts).
HTTP/1.1 message length rules are described in section 4.4 of the RFC 2616.

Categories