2

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.

dovholuk
  • 969
  • 1
  • 11
  • 23
  • `Alternatively I need a way to use HttpClient to send bytes down the socket I give the class.` Do you mean sending bytes as part of an HTTP request? Or do you mean you want to send non-HTTP data? – Stephen Cleary Jun 11 '19 at 20:49
  • I want a decent abstraction around the http protocol (such as webrequest or the newer HttpClient) such that I can use the abstraction which then produces http into the stream I give it. For example, imagine I was writing http requests to a file. Each request is a new file. Then another process reads the file, parses it and responds in the same file. Not sure if the example is helpful or not... – dovholuk Jun 11 '19 at 22:33
  • Another way to think about it is that I want to serialize/deserialize an http request or response into and out of the stream I choose. – dovholuk Jun 11 '19 at 22:51
  • Ah. I don't know of any type like that. The reason is likely historical: until recently, I believe `HttpClient` and friends would call higher-level Win32 APIs that handled the actual HTTP protocol in unmanaged code. So they never actually wrote to a `Stream`. – Stephen Cleary Jun 12 '19 at 00:32
  • For some reason I didn't find these previous SO questions before asking. If any mod sees this question/comment I think it's possibly a duplicate of the following: * https://stackoverflow.com/questions/318506/converting-raw-http-request-into-httpwebrequest-object * https://stackoverflow.com/questions/975308/c-sharp-http-request-parser * https://stackoverflow.com/questions/743794/net-http-parser This is the sort of answer I was hoping for: https://stackoverflow.com/a/54075677/44714 but it's still not quite what I was after – dovholuk Jun 12 '19 at 11:31
  • 1
    This thread https://github.com/dotnet/core/issues/2312 seems to be covering exactly what I want. Introduce Http over arbitrary streams #2312 Summary This issue is about contributing back support for HTTP over arbitrary streams (named pipe, unix socket, ...) that we use internally for Docker Desktop to .net core libraries. This is precisely what this question is asking about. Adding a comment here for any future generations that might want to track this – dovholuk Jun 21 '19 at 19:00

1 Answers1

0

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.

Kevingy
  • 198
  • 12
  • I don't want to parse html. I want an http wrapper so that if I tell it to "get" Google.com it writes into the stream of my choice something like: ```> GET / HTTP/1.1 > Host: Google.com > User-Agent: curl/7.45.0 > Accept: */* >``` – dovholuk Jun 11 '19 at 22:36
  • @dovholuk SimpleBrowser will do that. It will navigate to the URL and give you back whatever you need from the result of the navigation, including all of the headers you have listed. You probably already have another solution by now, though. – Kevingy Oct 18 '19 at 15:44
  • I realize my comment was not clear. I also didn't notice you were the author of that lib. I specifically need to own the socket. I need to feed the HTTP engine a stream or a Pipe etc. I can't have the socket constructed by the library. I can't have certificate processing done by the lib etc. Looking through the code - I don't see a way for me to accomplish that with SimpleBrowser but maybe as the author you point out how I could do that? – dovholuk Oct 21 '19 at 12:39
  • @dovholuk You are correct. SimpleBrowser doesn't expose the socket upon which the HTTP transport takes place. SimpleBrowser is written on top of .NET. .NET doesn't give access to the raw underlying socket. It only gives access to the response stream. If you need socket-level access, I think you have a lot of custom coding ahead. – Kevingy Oct 21 '19 at 13:57