I have a raw socket I want to make HTTP requests over. I would like to get back nicely-parsed-for-me http responses. Ideally I could feed this raw socket to HttpClient - something in a standard library. "TheWrapperClass" around the socket would allow me to use higher level instructions like again - the ones from HttpClient/HttpClientHandler like : clientHandler.ClientCertificates or clientHandler.Credentials etc.
Something like this maybe?:
HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.SocketFactory = mySocket/FactoryGoesHere???
HttpClient client = new HttpClient(new CustomMessageHandler());
var resp = await client.GetAsync("http://whatever");
I'm thinking of something like SSLSocketFactory from Java - is there an equivalent of this in .NET that I just haven't found yet?
At the end of the day - I really only want to have a library to invoke that writes HTTP to the wire easily and reads HTTP from the wire easily. If I had that I don't need HttpClient. Alternatively I need a way to use HttpClient to send bytes down the socket I give the class.
Edit:
I tried using a HttpMessageHandler but the HttpRespons is one that I hand craft. I need something that reads a stream and parses the http for me.
If you don't have a need for executing JavaScript, SimpleBrowser might fit for you:
https://github.com/SimpleBrowserDotNet/SimpleBrowser
It will not expose a raw socket for you to use as a bi-directional stream, but it will allow you to navigate via HTTP and receive an HTTP response. The HTTP response can either be the raw text response from the web server, or an parsed XML (XHTML) document.
Related
I have a REST API implemented in microsoft Web API.
In my client i use HttpRequestMessage and HttpResponseMessage.
When i am sending a small class, I serialize it to JSON and then send it.
Soon, my class becomes bigger, and I need to JSON the class, zip it (in memory) and send to server. I can no longer use the same technique, I need to send the zip in chunks.
What is the proper way to achieve it ? I have read this post Posting a File and Associated Data to a RESTful WebService preferably as JSON
Need some good articles, I dont know where to start.
On the client side this should work pretty much out of the box...
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.TransferEncodingChunked = true;
var content = new CompressedContent(new StreamContent(new FileStream("c:\\big-json-file.json",FileMode.Open)),"UTF8");
var response = httpClient.PostAsync("http://example.org/", content).Result;
You can find an implementation of CompressedContent in WebApiContrib. If you are using earlier than .net 4.5 the request will be buffered client side before sending. Unfortunately the underlying HttpWebRequest doesn't support buffered streaming until .net 4.5
I have Managed to Setup II7 with Gzip Compression .
I can check via web sniffer that my asmx web service encoding is Gzip but how to i enable
gzip Compression on my C# Client , i am using the Web Service is Service reference in my application.
Actually i am trying to send large amount of data , 10k objects of array so Compression with be great effect on bw.
but how do I enable Compression on my C# Client.
i am trying to see that many people sees same problem but there nothing clear answer some says use third party tools or some says about custom headers etc etc .
is not there any proper way , built in to consume Compressed web service
As #Igby Largeman pointed out, you can use your IIS7 to enable the compression on the server, but this is not enough.
The main idea is to set the headers on the client side and server side:
Client:
Accept-Encoding = "gzip, deflate";
You can achieve this by code:
var request = HttpWebRequest.Create("http://foofoo");
request.Headers["Accept"] = "application/json";
request.Headers["Accept-Encoding"] = "gzip, deflate";
or
var request = HttpWebRequest.Create("http://foofoo");
request.AutomaticDecompression = DecompressionMethods.GZip |
DecompressionMethods.Deflate;
If you use some WCF client, and not the HttpWebRequest, you should use custom inspector and dispatcher, like in this article:
So I used a message inspector implementing IClientMessageInspector and IDispatchMessageInspector to automatically set the AcceptEncoding and ContentEncoding http headers.
This was working perfectly but I could not achieve to decompress the response on the server by first detecting the ContentEncoding header thus I used the work around to first try to decompress it and if it fails just try to process the request as normal.
I also did this in the client pipeline and this also works.
Server:
// This is the nearly same thing after all
Content-Encoding = "gzip" OR Content-Encoding = "deflate"
To do this on the Server side, you should enable httpCompression in the IIS.
I think you should check the original article to get this work
There is a web service that can only be consumed via http and a client that can only consume https web services. Therefore I need some intermediary that forwards on requests received in https and returns responses in http.
Supposing that the intermediary is completely dumb save for the fact that it knows where the web service endpoint is (i.e. it doesn't know what the signature of the service is, it just knows that it can communicate with it via an http web request, and it listens on some https uri, forwarding on anything it receives), what is the most simple way of achieving this?
I've been playing around with this all day and am not sure how to achieve the "dumb" bit, i.e. not knowing the signature for passing back the verbatim response.
A dumb intermediary is essentially a proxy. Your best bet might to be just use standard asp.net pages (instead of shoehorning into service functionality like ASMX or WCF which are just going to fight you) so you can receive the request exactly as-is and process it in a simple way using standard request/response. You can make use of HttpWebRequest class to forward the request on to the other endpoint.
Client requests https://myserver.com/forwarder.aspx?forwardUrl=http://3rdparty.com/api/login
myserver.com (your proxy) reads querystring forwardUrl and any POST or GET request included.
myserver.com requests to http://3rdparty.com/api/login and passes along GET or POST data sent from the client.
myserver.com takes response and sends back as response to other endpoint (essentially just Response.Write contents out to the response)
You would need to write forwarder.aspx to process the requests. Code for forwarder.aspx would be something like this (untested):
protected void Page_Load(object sender, EventArgs e)
{
var forwardUrl = Request.QueryString["forwardUrl"];
var post = new StreamReader(Request.InputStream).ReadToEnd();
var req = (HttpWebRequest) HttpWebRequest.Create(forwardUrl);
new StreamWriter(req.GetRequestStream()).Write(post);
var resp = (HttpWebResponse)req.GetResponse();
var result = new StreamReader(resp.GetResponseStream).ReadToEnd();
Response.Write(result); // send result back to caller
}
As part of learning node.js, I just created a very basic chat server with node.js and socket.io. The server basically adds everyone who visits the chat.html wep page into a real time chat and everything seems to be working!
Now, I'd like to have a C# desktop application take part in the chat (without using a web browser control :)).
What's the best way to go about this?
I created a socket server in nodejs, and connected to it using TcpClient.
using (var client = new TcpClient())
{
client.Connect(serverIp, port));
using (var w = new StreamWriter(client.GetStream()))
w.Write("Here comes the message");
}
Try using the HttpWebRequest class. It is pretty easy to use and doesn't have any dependencies on things like System.Web or any specific web browser. I use it simulating browser requests and analyzing responses in testing applications. It is flexible enough to allow you to set your own per request headers (in case you are working with a restful service, or some other service with expectations of specific headers). Additionally, it will follow redirects for you by default, but this behavior easy to turn off.
Creating a new request is simple:
HttpWebRequest my_request = (HttpWebRequest)WebRequest.Create("http://some.url/and/resource");
To submit the request:
HttpWebResponse my_response = my_request.GetResponse();
Now you can make sure you got the right status code, look at response headers, and you have access to the response body through a stream object. In order to do things like add post data (like HTML form data) to the request, you just write a UTF8 encoded string to the request object's stream.
This library should be pretty easy to include into any WinForms or WPF application. The docs on MSDN are pretty good.
One gotcha though, if the response isn't in the 200-402 range, HttpWebRequest throws an exception that you have to catch. Fortunately you can still access the response object, but it is kind of annoying that you have to handle it as an exception (especially since the exception is on the server side and not in your client code).
I need a C# HTTP library that doesn't depend on HttpWebRequest, as I can't access this from the environment I need to run my code (Unity's WebPlayer).
Ideally this would be light weight, but any suggestions are welcome!
I just need to be able to do simple HTTP GET and POST requests, but better REST support would be good.
Thanks!
Edit: As people have pointed out, HttpWebRequest isn't in System.Web, but the fact remains - I can't use it. I've updated my post above.
This post
http://forum.unity3d.com/threads/24445-NotSupportedException-System.Net.WebRequest.GetCreator shows the same error I'm getting.
Implementing your own simple HTTP client using Socket is not all that difficult.
Just use TcpClient().
For the protocol itself, drop down to a connection-per-request paradigm. A typical GET request would look as follows:
GET /url HTTP/1.1
Host: <hostname-of-server>
Connection: close
For the code itself (from memory)
TcpClient client = new TcpClient();
IPEndPoint target = ... // get an endpoint for the target using DNS class
client.Connect(target);
using(NetworkStream stream = client.GetStream())
{
// send the request.
string request = "GET /url HTTP/1.1\r\nConnection: close\r\n\r\n";
stream.Write(Encoding.ASCII.GetBytes(request));
// then drain the stream to get the server response
}
Note that you will need to wrap this code with a simple class that provides HTTPWebRequest like semantics.
Look at System.Net.HttpWebRequest.
It is in System.dll.
Documentation: http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx
HttpRequest is located in System.Web, which is probably what you were thinking of.
HttpWebRequest is in the System assembly, not in System.Web (perhaps you're confusing with HttpRequest which is used in ASP.NET). It is available in all .NET Framework versions (including Silverlight, WP7, and Client Profile)