Making a http request trough Socks proxy - delphi

I have a socks proxy and I need to make a HTTP Get request
I tried using indy using this sample ( http://www.indyproject.org/KB/index.html?howdoiuseaproxywithindy.htm ) but I always get the error :
Connection closed gracefully.
What am I doing wrong ?

The correct way to handle this is to assign a TIdIOHandlerStack component to the TIdHTTP.IOHandler property, then assign a TIdSocksInfo component to the TIdIOHandlerStack.TransparentProxy property, and then configure the TIdSocksInfo as needed.

Related

How to use TIdWhois with SOCKS proxy

I'm getting whois information using this code:
IdWhois1.Host := 'whois.nic.tld';
ServerResultStr := IdWhois1.WhoIs('google.tld');
But I need to query the whois server (port 43) using a SOCKS proxy server.
I'm using Delphi 10.3.3. Is there any way to achieve this by using TIdWhois?
SOCKS is handled in Indy using the TIdSocksInfo component. You can configure it with the proxy details as needed (Host, Port, Version, Authentication, etc).
To make TIdWhois (or any TCP client) connect to its target server through TIdSocksInfo, you need to do the following:
assign a TIdIOHandlerSocket-derived component (TIdIOHandlerStack, or any TIdSSLIOHandlerSocketBase-derived component, like TIdSSLIOHandlerSocketOpenSSL) to the TIdWhois.IOHandler property.
assign the TIdSocksInfo to the IOHandler's TransparentProxy property.

How can I set user-agent in IOWebSocketChannel?

I work with IOWebSocketChannel and I don't have access to Webscoket inside it
in order to change the user-agent. how can I achieve that and set user agent for IOWebSocketChannel?
according to this issue: Add option to set User Agent for Websocket #32008
and the documentation: WebSocket
you can't set user agent for IOWebSocketChannel but you can just set userAgent for all Websocket instance by call:
Websocket.userAgent = 'your desired agent';
this works for all Websocket instance, so there is no need to access the websocket instance object passed to IOWebSocketChannel.
If you are creating the socket using IOWebSocketChannel.connect you can just add the user-agent in the headers parameter, or otherwise if you are upgrading to a IOWebSocketChannel from a WebSocket (with WebSocket.connect) set your headers there.

TIdHTTP - Get only Responsecode

I am using the TIdHTTP component and it's GET function.
The GET function sends a complete request, which is fine.
However I would like to spare/save some traffic from a GET response and only want to receive the Responsecode which is in the first "line" of a HTTP response.
Is there a possibility of disconnecting the connection in order to save traffic from any further content?
As mentioned, I only need the responsecode from a website.
I alternatively thought about using Indy's TCP component (with SSL IOHandler) and craft an own HTTP Request Header and then receive the responsecode and disconnect on success - but I don't know how to do that.
TIdHTTP has an OnHeadersAvailable event that is intended for this very task. It is triggered after the response headers have been read and before the body content is read, if any. It has a VContinue output parameter that you can set to False to cancel any further reading.
Update: Something I just discovered: When setting VContinue=False in the OnHeadersAvailable event, TIdHTTP will set Response.KeepAlive=False and skip reading the response body (OK so far), but after the response is done being processed, TIdHTTP checks the KeepAlive value, and the property getter returns True if the socket hasn't been closed on the server's end (HTTP 1.1 uses keep-alives by default). This causes TIdHTTP to not close its end of the socket, and will leave any response body unread. If you then re-use the same TIdHTTP object for a new HTTP request, it will end up processing any unread body data from the previous response before it sees thee response headers of the new request.
You can work around this issue by setting the Request.Connection property to 'close' before calling TIdHTTP.Get(). That tells the server to close its end of the socket connection after sending the response (although, I just found that when requesting an HTTPS url, especially after an HTTP request directs to HTTPS, TIdHTTP clears the Request.Connection value!). Or, simply call TIdHTTP.Disconnect() after TIdHTTP.Get() exits.
I have now updated TIdHTTP to:
no longer clear the Request.Connection when preparing an HTTPS request.
close its end of the socket connection if either:
OnHeadersAvailable returns VContinue=False
the Request.Connection property (or, if connected to a proxy, the Request.ProxyConnection property) has been set to 'close', regardless of the server's response.
Usually you would use TIdHttp.Head, because HEAD requests are intended for doing just that.
If the server does not accept HEAD requests like in OP's case, you can assign the OnWorkBegin event of your TIdHttp instance, and call TIdHttp(Sender).Disconnect; there. This immediately closes the connection, the download does not continue, but you still have the meta data like response code, content length etc.

How to set the timeout for a proxy connection in Ruby

I know how to set the open/read timeout for the request going through the proxy. My problem, however, is that occasionally my proxy goes down, and therefore I am unable to ever connect to the proxy. So I want to be able to set the timeout to connect to the proxy to some value, and then handle the timeout by trying something else. Any idea how I can set the timeout value for connecting to an http proxy? Thanks!
First the code, then a bit of explaination below:
# get an instance of Net::HTTP that has proxy settings embedded
# see the source: http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html#method-c-Proxy
proxyclass = Net::HTTP::Proxy("proxy_host");
# Create a new instance of the URL you want to connect to
# NOTE: no connection is attempted yet
proxyinstance = proxyclass.new("google.com");
# Make your setting changes, specifically the timeouts
proxyinstance.open_timeout = 5;
proxyinstance.read_timeout = 5;
# now, attempt connecting through the proxy with the desired
# timeout settings.
proxyinstance.start do |http|
# do something with the http instance
end
The key is realizing open_timeout and read_timeout are instance variables and that Net::HTTP::Proxy actually returns a decorated Net::HTTP class.
You would run into this same problem with similar Net::HTTP usage. You must construct it the "long" way, not using the Net::HTTP.start() class method shortcut.

Indy's TIdHTTPProxyServer: How to filter requests?

I'm using an TIdHTTPProxyServer to implement a simple HTTP proxy, but I'd like now to block some connections if they match certain URLs. Which event and/or component is best to accomplish that? Indy documentation is not too explicative. :(
Thanks!
As a basic filter you can use the OnHTTPBeforeCommand event handler (which fires before the command is sent to the HTTP server).
Inspect the Context parameter properties, you'll find useful:
Context.Command
Context.OutboundClient.Host
Context.OutboundClient.Port
Context.Document
Context.Headers
I never tried to stop the PassTrough at this time, but I bet you can do it by just raising an exception at that point if you determine there's a block rule match.
the component has a "OnConnect" event, double-click it and add this code:
if AContext.Connection.Socket.Binding.PeerIP = '127.0.0.1' then
AContext.Connection.Disconnect;
replace 127.0.0.1 with your filter, this is just a "extremely basic example", same applies to other Indy servers which have a "OnConnect" event.

Resources