TcpClient Send Http Request and get response - c#

i just started with networking, learning how http worls and all that.
so my question is:
i have TcpClient connecting to an ip where website is located, but problem is that there is so many websites hosted on that server (goDaddy.com), I want to get contents of index.html,
of a website i want.
my code looks like that atm:
connector = new TcpClient("******", 80);
if(connector.Connected) Console.WriteLine("Connected\n");
so what kind of headers i need to send to apache so it gets the index.html for me,also would like to know the right way of sending it, without closing connection
Purpose for this:
-> I want to see headers that have been sent, and learn how to send my own headers.
big thanks in advance!

For HTTP data exchange it is simplier to use HttpClient, not TcpClient.
Try to read MSDN for HttpClient.

You can also use WebClient:
WebClient client = new WebClient();
string content = client.DownloadString("http://website.com/index.html");
TcpClient is a very low level object; it is not recommended to start with that one.

Related

How to consume a socket.io WebSocket API in C#

I need to consume a third-party WebSocket API in .NET Core and C#; the WebSocket server is implemented using socket.io (using protocol version 0.9), and I am having a hard time understanding how socket.io works... besides that the API requires SSL.
I found out that the HTTP handshake must be initiated via a certain path, which is...
socket.io/1/?t=...
...whereby the value of the parameter t is a Unix-timestamp (in seconds). The service replies with a session-key, timeout information, and a list of supported transport protocols. Due to simplicity, this first request is made via HttpClient and does not involve any additional headers.
Next, another HTTP request is required, which should result in an HTTP 101 Switching Protocol response. I specified the following headers in accordance to the previous request...
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Key: ...
Sec-WebSocket-Version: 13
...whereby the value of the Key-header is a Base64-encoded GUID-value that the server will use to calculate the Sec-WebSocket-Accept header value. I also precalculate the expected Sec-WebSocket-Accept header value, for validation...
I tried to make that request using HttpClient as well, but that does not seem to work... I actually don´t understand why, because I expect an HTTP response. I also tried to make the request using TcpClient by sending a manually prepared GET request over a SslStream, which accepts the remote certificate as expected. Sending data seems to work, but there´s no response data... the Read-method returns zero.
What do I miss here? Do I need to setup a listener for the WebSocket connection as well, and if yes how? I don´t want to implement a feature complete socket.io client, I´d just like to keep it as simple as possible to catch some events...
The best way of debugging these issues is to use a sniffer like wireshark or fiddler. Often connect using an IE and compare IE results with my application and modify my app so it works like the IE. Using WebClient instead of HttpClient will also work better because the WebClient does more automatically than the HttpClient.
A web connection uses the header of the client and the headers in the server webpage to negotiate a connection mode. Adding additional headers to you client will change the connection mode. Cookies are also used to select the connection mode. Cookies are the results of previous connection to the same server which shortens the negotiations and stores info from previous connection so less data has to be downloaded from server. The server remembers the cookies. Cookies have a timeout and is kept until timeout expires. The IE history in your client has a list of IP addresses and Net automatically sends the cookies associated with the server IP.
If a bad connection is made to the server the cookies is also bad so the only was of connection is to remove the cookie. Usually I go into the IE and delete cookies manually in the IE history.
To check if a response is good the server returns a status. A completed response contains a status 200 DONE. You can get status which are errors. You can also get a 100 Continue which means you need to send another request to get the rest of the webpage.
Http has 1.0 (stream mode) and 1.1 (chunk mode). Net library doesn't work with chunk. Chunk requires client to send message to get next chunk and I have not found a way in Net to send the next chunk message. So if a server responds with a 1.1 then you have to add to your client headers to use 1.0 only.
Http uses TCP as the transport layer. So in a sniffer you will see TCP and HTTP. Usually you can filter sniffer just to return Http and look at header for debugging. Occasionally TCP disconnects and then you have to look at TCP to find why the disconnect occurs.

How can a c# client receive http POST?

I am currently working on a simple app to make my life easier. I made an android app which lets me pick a file and uploads it to a server. I am working on a windows PC c# app that sends its ip (dynamic) and its open port to my server.
Whenever the server receives a file from my phone, I want it to send a POST request to my PC.
I am fairly new to web stuff (I have done tons of coding before though), but as far as I understand only a server can receive a POST request.
How can I make a C# server that runs on my PC with a dynamic IP and receives POST requests?
I have been struggling with this for a while now, just simple keywords I should research would be very helpful, thanks.
HTTP is a protocol which lets Web Servers and Clients communicate. It requires you to have a web server (IIS, Apache or other) to respond to client http requests.
Client can send a GET, POST and others request type messages.
The prefable way is to send a web client using a WebClient class. Here is a sample taken from another answer given by Andrew
string URI = "site.com/mail.php";
using (WebClient client = new WebClient())
{
System.Collections.Specialized.NameValueCollection postData =
new System.Collections.Specialized.NameValueCollection()
{
{ "to", emailTo },
{ "subject", currentSubject },
{ "body", currentBody }
};
string pagesource = Encoding.UTF8.GetString(client.UploadValues(URI, postData));
}
I would create some kind of server application using WebAPI, SignalIR, WCF or ASMX web services. All of these can handle server/client communication and would make it easy to communicate with your device.

Inspect headers set by WebClient proxy

I'm executing request through some free proxy servers, and I would like to know what headers each proxy server sets. Right now I'm visiting a page that prints out the result in the html body.
using(WebClient client = new WebClient())
{
WebProxy wp = new WebProxy("proxy url");
client.Proxy = wp;
string str = client
.DownloadString("http://www.pagethatprintsrequestheaders.com");
}
The WebClient doesn't show the modified headers, but the page prints the correct ones. Is there any way to find out what headers that are being set by the proxy without visiting a page that prints them like in my example? Do I have to create my own http listener?
When the proxy server sets its own headers, it is essentially performing its own web request. It can even hide or override some of the headers that you set using your WebProxy.
Consequently, only the target page (pagethatprintsrequestheaders.com) can reliably see the headers being set by the proxy. There is no guarantee that the proxy server will send back the headers that it had sent to the target, back to you.
To put it another way, it really depends on the proxy server implementation. if the proxy server you are using is based on Apache's ProxyPass, you'd probably see the headers being set! If it's a custom implementation, then you may not see it.
You can first try inspecting the client.ResponseHeaders property of the WebClient after your response comes back. If this does not contain headers matching what (pagethatprintsrequestheaders.com) reports, then it's indeed a custom or modified implementation.
You could then create your own proxy servers, but this is more involved. You would probably spin up an EC2 instance, install Squid/TinyProxy/YourCustomProxy on it and use that in your WebProxy call.
You may also want to modify your question and explain why you want to read the headers. There may be solutions to your overall goal that don't require reading headers at all but could be done in some other way.
It looks like your sending a request from your WebClient, through the proxy and its received by the host at www.pagethatprintsrequestheaders.com.
If the proxy is adding headers to the request, your webclient will never see them on it's request.
webclient proxys request
request with headers added
client -----------> proxy ----------------------> destination host
The webclient can only see the state of the request between it and the proxy. The proxy will create a new request to send to the destination host, and its that request to which the headers are added. It also that request that is received by the destination host (which is why when it echoes back the headers it can see those added by the proxy)
When the response comes back, the headers are set by the host. It's possible that the proxy will add some headers to the response, but even if it did, they are not likely to be the same headers it adds to a request.
response response
(forwarded by proxy) (headers set by host)
client <------------------- proxy <------------------------- destination host
Using a host that echo the headers back as part of the response payload is one option.
Another would be to use something between the proxy and the destination host to inspect the request there (e.g a packet sniffer or another proxy like Fiddler that lets you see the request headers).
If the proxy is outside of you network, getting between the proxy and the destination host will be difficult (unless the host is under your control).

Extract HTTP header information using Packet.Net

I would like to extract the HTTP header information using Packet.Net. I am using SharpPcap to capture the packet and need to access the User-Agent field in the TCP packet. If I understand correctly Packet.Net is used to analyze the packet captured. Help would be appreciated on this regard. I have tried to display the TCP packet with the following code but I get bytes displayed. I am using C# as development language.
private static void device_OnPacketArrival(object sender,CaptureEventArgs packet){
Packet p =Packet.ParsePacket(packet.Device.LinkType,packet.Packet.Data);
System.Text.ASCIIEncoding ASCII = new System.Text.ASCIIEncoding();
String StringMessage = ASCII.GetString(p.Bytes);
Console.WriteLine(StringMessage);
}
Packet.Net doesn't currently have http decoding support. Because http messages can be split across multiple packets, it seems like a good approach would be to first add support to allow the following of tcp connections, then add http session detection and parsing on top of the tcp data stream. Trying to parse http data on a per-packet basis might work for the headers of the data or some http messages but isn't a robust solution as it would prevent being able to get the full content of the http message that might be several kilobytes in size.
(I have a commercial library that builds upon SharpPcap/Packet.Net that adds tcp session following and http session following and decode. Post your email here if you want me to email you with more details.)

SSL in a C# Web Proxy; how do I determine if the request is SLL or not?

I have built a web proxy from scratch (using Socket and NetworkStream classes). I am now trying to implement SSL support for it so that it can handle HTTPS requests and responses. I have a good idea of what I need to do (using SslStream) but I don't know how to determine if the request I get from the client is SSL or not.
I have searched for hours on this subject and have been unable to find a suitable solution.
After I do this:
TcpListener pServer = new TcpListener(localIP, port);
pServer.Start(256);
Socket a_socket = pServer.AcceptSocket();
How do I know if I need to read the information using SslStream or NetworkStream?
Client will send you a CONNECT method request after this point you need to just redirect the traffic.
Sample Connect :
CONNECT www.google.com:443 HTTP/1.1
After seeing this just switch to data redirect mode. You can not intercept or read the data so you don't need to worry about SSLStream anyway, you won't touch it.
However if you want to MITM (man in the middle) then you need to switch to SSL otherwise just redirect whatever comes to the target URL and port, that's it.
Obviously client browser will popup with an SSL certificate exception if you intercept the request.
You need to add support for the CONNECT command.
http://www.codeproject.com/KB/IP/akashhttpproxy.aspx
This is why proxy clients use one proxy for HTTP and different one for HTTPS. You can't know what type of connection you're going to receive.

Categories