Delphi http get request with another port - rest

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.

Related

Handle REST requests in golang GRPC server

Is it possible for a GRPC server written in golang to also handle REST requests?
I've found the grpc-gateway which enables turning an existing proto schema into a rest endpoint but I don't think that suits my needs.
I've written a GRPC server but I need to also serve webhook requests from an external service (like Github or Stripe). I'm thinking of writing a second REST based server to accept these webhooks (and possibly translate/forward them to the GRPC server) but that seems like a code-smell.
Ideally, I'd like for my GRPC server to also be able to, for example, handle REST requests at an endpoint like /webhook or /event but I'm not sure if that's possible and if it is how to configure it.
Looks like I asked my question before giving a large enough effort to resolve it my own. Here's an example of serving REST requests alongside GRPC requests
func main() {
lis, err := net.Listen("tcp", ":6789")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
// here we register and HTTP server listening on port 6789
// note that we do this in with gofunc so that the rest of this main function can execute - this probably isn't ideal
http.HandleFunc("/event", Handle)
go http.Serve(lis, nil)
// now we set up GRPC
grpcServer := grpc.NewServer()
// this is a GRPC service defined in a proto file and then generated with protoc
pipelineServer := Server{}
pipeline.RegisterPipelinesServer(grpcServer, pipelineServer)
if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("failed to serve: %s", err)
}
}
func Handle(response http.ResponseWriter, request *http.Request) {
log.Infof("handling")
}
With the above, sending a POST to localhost:6789/event will cause the handling log line to be emitted.

when i use the exec RestApi, i got the error message "x509: certificate is valid for 127.0.0.1, not xx.xx.xx.xx"

first i test with https but get 400:upgrade response
then i test with websocket, and get "Can't connect to console: x509: certificate is valid for 127.0.0.1, not xx.xx.xx.xx" when i use NewClient() or Dialer.Dial(url,req.Header) to create the client conn
is it sth related to the Bearer token?
i put it in the request's header
wsurl := "wss://xx.xx.xx.xx:8080/r/projects/1a92/kubernetes:6443/api/v1/namespaces/NM/pods/testPod-546cdd8d79-7h8nv/exec?command=ls&container=testPod&stderr=true&stdin=true&stdout=true&tty=false"
u, err := neturl.Parse(wsurl)
rawConn, err := net.Dial("tcp", u.Host)
wsHeaders := http.Header{
"Authorization": {"Bearer "+env_bearer_token},
"Origin": {"https://xx.xx.xx.xx:8080/r/projects/1a92/kubernetes:6443"},
"Sec-WebSocket-Extensions": {"permessage-deflate; client_max_window_bits, x-webkit-deflate-frame"},
}
wsConn, resp, err := websocket.NewClient(rawConn, u, wsHeaders, 1024, 1024)
anything wrong?
is it sth related to the Bearer token?
No, is related to exactly what the error says: the X.509 certificate does not have an SAN entry for whatever IP is xx-ed out. There are a few paths forward out of that situation:
update away from using an IP address toward a hostname that is covered by the cert
reissue the cert to include that IP in its SAN list
update your Dialer to provide a tls.Config with InsecureSkipVerify: true and take your chances

How can I debug the following Go code, which tries to make a TCP connection to an IP address and port?

I am getting an IP address and port number from a Bittorrent tracker, for a specific torrent file. It represents a peer on the bittorrent network. I am trying to connect to the peer using this code. The connection always times out (getsockopt: operation timed out). I think I am missing something very fundamental here, because I tried the same code in python with the exact same result, operation timed out. It happens for every single peer IP address.
I downloaded this bittorrent client - https://github.com/jtakkala/tulva
which is able to connect to peers from my system using this type of code (Line 245, peer.go). I have also been able to use similar code for connecting to a tcp server running on localhost.
Edited details after JimB's comment and Kenny Grant's answer
package main
import (
"fmt"
"net"
)
func main() {
raddr := net.TCPAddr{IP: []byte{}/*This byte slice contains the IP*/, Port: int(/*Port number here*/)}
conn, err := net.DialTCP("tcp4", nil, &raddr)
if err != nil {
fmt.Println("Error while connecting", err)
return
}
fmt.Println("Connected to ", raddr, conn)
}
Try it with a known good address, and you'll see your code works fine (with a 4 byte IPv4 address for SO say). Bittorrent peers are transient, so it probably just went away, if testing you should use your own IPs that you know are stable.
raddr := net.TCPAddr{IP: net.IPv4(151, 101, 1, 69), Port: int(80)}
...
-> Connected to {151.101.1.69 80 }
if you're trying to connect to 187.41.59.238:10442, as jimb says, it's not available. For IPs, see the docs:
https://sourcegraph.com/github.com/golang/go#9fd359a29a8cc55ed665542d2a3fe9fef8baaa7d/-/blob/src/net/ip.go#L32:6-32:8

delphi 7, indy tcp proxy without remote server

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?

Lua socket error on connection

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).