Is it possible to implement something like IdMappedPortTCP without connecting to a remote proxy server?
What I need is
a) a way to edit every HTTP header (for example change the User-Agent for each request) the for every request sent from my computer without having to connect to a remote server. And
b) If possible, I would also like to capture all the http traffic in delphi without the need of a third party application like proxifier.
What i have tried so far is:
a) IdMappedPortTCP and then binding to a remote proxy server, I then modify the AThread.NetData in each request in the IdMappedPortTCPExecute method.
b) using proxifier to capture all http traffic in the computer.
What I have tried so far is using Mapping with IdMappedPortTCP to a local proxy server (e.g. squid, delegate, fiddler, ccproxy), create my own proxy server (using indy 10) - All these worked great for HTTP connections but require installation of root certificate to modify HTTPS requests which is undesired. If its possible to implement any local proxy without having to install root certificates it would be awesome!
I have also tried to modify the TCP REDIRECTOR CODE but being fresh n all in programming, i haven't been successful. I figured i could change the
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
Cli: TIdTCPClient;
Len: Cardinal;
Data: string;
begin
try
Cli := nil;
try
{ Create & Connect to Server }
Cli := TIdTCPClient.Create(nil);
Cli.Host := 'www.borland.com';
Cli.Port := 80;
{ Connect to the remote server }
Cli.Connect;
..............
Such that I would extract the host and port from request and then assign cli.host to that host and port dynamically for each request. I don't know how viable that is. Like, would it cause computer to hang because of connecting to too many remote host?
Update: with TIdMappedPortTCP, I used AThread.Connection.Capture(myheaders,''); so now I can assign my host to myheaders.Values['host'] and if AThread.Connection.ReadLn = 'CONNECT' I set port to 443 otherwise I set it as 80. Am I on the right track?
procedure TForm1.IdMappedPortTCP1Connect(AThread: TIdMappedPortThread);
var
myheaders: TIdHeaderList;
method : string;
begin
myheaders:=TIdHeaderList.Create;
try
method:= AThread.Connection.ReadLn;
Athread.Connection.Capture(myheaders);
if myheaders.Count<>0 then begin
if Pos('CONNECT',method)<>0 then begin
with TIdTCPClient(AThread.OutboundClient) do begin
Host:=myheaders.Values['host'];
Port:=443;
end;
end else begin
with TIdTCPClient(AThread.OutboundClient) do begin
Host:=myheaders.Values['host'];
Port:=80;
end;
end;
TIdMappedPortThread(AThread).NetData:= method + #13#10 + myheaders.Text + #13#10 + #13#10;
end else begin
TIdMappedPortThread(AThread).NetData:= method + #13#10 + #13#10;
outs.Lines.Add(TIdMappedPortThread(AThread).NetData);
end;
finally
myheaders.Free;
end;
end;
I have put that code in the OnConnect event but it does not seem to be working. What have I done wrong?
Related
How I can make a GET request on this example?
http://localhost:9000/api/public/v1/action=X
I tried with TIdHTTP but only the 80 port its acceptable and when I try the 9000 port this error happen:
Unknow protocol
My code:
var
lHTTP: TIdHTTP;
link: String;
begin
link := 'localhost:9000/api/scanner/Acao?acao=x';
lHTTP := TIdHTTP.Create;
try
link := lHTTP.Get(link);
finally
lHTTP.Free;
end;
end;
TIdHTTP should work fine with non-standard ports, provided you actually have an HTTP server listening on localhost on port 9000, eg:
var s: string;
s := IdHTTP1.Get('http://localhost:9000/api/public/v1/action=X');
The only way to get an "Unknown protocol" error is if you omit the scheme portion from the URL, eg:
s := IdHTTP1.Get('localhost:9000/api/public/v1/action=X');
You must include either http:// or https:// in the URLs you request.
I am using lua as module for nginx (openresty) to get files from remote host. My function:
function readfile(url)
local http = require ("socket.http")
if not http then
error("Couldn't open socket.http")
end
http.TIMEOUT = 5
local body, code = http.request(url)
if not body then
error("Couldn't read the remote file: " .. code)
end
return body
end
I have tested this code by using Siege. When I set the users more then 100 (for example), I catch this error:
2018/03/27 09:36:38 [info] 10#10: *91018 shutdown() failed (107: Socket not connected), client: 172.18.0.7, server: localhost
I have more errors when i set more users. What does it mean? Thank you for the help.
Don't use luasocket library with OpenResty. The resulting code would block on http.request().
I suppose that all nginx worker just blocked and it is the reason of these errors.
For you purpose you may use one of the libraries below:
lua-resty-http
lua-resty-http-simple
First is more fexible, allow to use secure transport.
Second has simpler API.
And both use internally nginx Lua cosocket API and are 100% nonblocking out of the box.
The lua-resty-http or lua-resty-http-simple do not work in the init_by_lua in http context.
it is fine to use it in the init context where blocking is not considered harmful.
I am doing a project that is related with creating TCP/IP communication in Lua language. My computer is going to be a server and I wanna connect it with another computer.
So, here is the code:
local socket = require'socket'
local server = socket.tcp()
server:bind('*', 7200)
server:listen(32)
>>>>local client = server:accept()
--Here I have a problem. It is not working.
--It says:
--calling 'accept' on bad self (tcp{server} expected,got userdata in function)
client:settimeout(10)
-- receive the line
local line, err = client:receive()
-- if there was no error, send it back to the client
if not err then
client:send('test') --end
-- done with client, close the object
client:close()
Where did I make a mistake?
Your code works: If I add an end at the bottom of your code it works for me.
I'm trying to make a http get, using Lua Socket:
local client = socket.connect('warm-harbor-2019.herokuapp.com',80)
if client then
client:send("GET /get_tweets HTTP/1.0\r\n\r\n")
s, status, partial = client:receive(1024)
end
end
I expect s to be a tweet, since the get that I'm making returns one.
But I'm getting:
http/1.1 404 object not found
Here is a runnable version of your code example (that exhibit the problem you described):
local socket = require "socket"
local client = socket.connect('warm-harbor-2019.herokuapp.com',80)
if client then
client:send("GET /get_tweets HTTP/1.0\r\n\r\n")
local s, status, partial = client:receive(1024)
print(s)
end
If you read the error page returned, you can see that its title is Heroku | No such app.
The reason for that is that the Heroku router only works when a Host header is provided. The easiest way to do it is to use the actual HTTP module of LuaSocket instead of TCP directly:
local http = require "socket.http"
local s, status, headers = http.request("http://warm-harbor-2019.herokuapp.com/get_tweets")
print(s)
If you cannot use socket.http you can pass the Host header manually:
local socket = require "socket"
local client = socket.connect('warm-harbor-2019.herokuapp.com',80)
client:send("GET /get_tweets HTTP/1.0\r\nHost: warm-harbor-2019.herokuapp.com\r\n\r\n")
local s, status, partial = client:receive(1024)
print(s, status, partial)
With my version of LuaSocket, s will be nil, status will be "closed" and partial will contain the full HTTP response (with headers etc).
I'm attempting to create a Sinatra server that will return statistics about an EventMachine server. That is, I'm running:
EventMachine.run do
server = EventMachine.start_server 'localhost', 3333, MyApp
dispatch = Rack::Builder.app do
map '/' do
run MySinatraApp
end
end
Rack::Server.start({
app: dispatch,
server: 'thin',
Host: '0.0.0.0',
Port: '1111'
})
end
My goal is to figure out information on that running server started by start_server, such as connection_count. Is there any way to do this?
As far as I know there is no in-built way to do this (hopefully someone disproves me),
you can keep a counter in MyApp and +1 on connect and -1 on unbind for same effect.
Why? Why not just have the EM server provide a /info endpoint or something that returns a dump of the information you need? Why do you need the second server? If you really want a second server then it could just be a simple sinatra app that makes a HTTP request to /info and returns the results.
For connection_count it looks like there is a EM.connection_count you can call. You can see it here.