POCO C++ library: connect to server with HTTPS or HTTP - poco-libraries

I am using the POCO::Net::HTTPClientSession class to connect to the web server on IoT devices. I now need to support HTTPS to the device, but whether its HTTP or HTTPS is a configurable parameter in the device profile that may change at runtime.
I can connect just fine on HTTPS using the HTTPSClientSession class, and I can obviously connect on HTTP using the HTTPClientSession class. But I rather not use two objects for the two protocols. It seems I should be able to use the HTTPSClientSession object for both, since class HTTPSClientSession is a subclass of HTTPClientSession.
When I attempt to use an HTTPSClientSession object to talk to a plain HTTP server listening on port 80, The HTTPClientSession::sendRequest method throws exception Poco::Net::NetException with the message:
140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
Is it appropriate to be trying to use the HTTPSClientSession object for HTTP? If so, what do I need to do?

I think you can't use HTTPSClientSession for HTTP communication. But you can make use of the fact that HTTPSClientSession is a subclass of HTTPClientSession:
std::shared_ptr<HTTPClientSession> session;
if(https) {
session.reset(new HTTPSClientSession());
}
else {
session.reset(new HTTPClientSession());
}

Related

GRPC address prefix

When I use WCF's NETTCP binding endpoint address looks like: net.tcp://localhost:51111/MyService/.
When I use Websockets endpoint address looks like: ws://localhost:port/Esv/ocp and for secure connection wss://localhost:port/Esv/ocp.
Is there any common prefix for gRPC services? Or only 192.168.1.1:51111 is OK since called method is binded to GRPC server by:
ServerServiceDefinition.CreateBuilder().AddMethod(_myCommunicationMethodName, CallProcessingMehtod).Build();
In a grpc service, the URL of the underlying HTTP2 request is determined by the name of the of the service and the method name (as found in the .proto definition). Besides that, there is no "prefix" and using one would be against the recommendations in the gRPC wire protocol spec (more on that in github.com/grpc/grpc-dotnet/issues/110).
Note that under normal circumstances, you don't need to know the exact URL used by a gRPC method call as this is something that's encapsulated by the gRPC client and server logic.

Why grpc-go can run grpc server and http server at the same address and port, but grpc-node cannot

I had read this answer: https://stackoverflow.com/a/56943771/6463558, it says that there is no way to run gRPC server and HTTP server at same address and port using grpc-node package.
But I can create gRPC server and HTTP server at same address and port(e.g. both using localhost:3000) using grpc-go package. Here is an example: https://github.com/mrdulin/grpc-go-cnode/blob/master/cmd/server/main.go#L79
So, why grpc-node and grpc-go behave inconsistently. Does this make sense?
The result I expect is that no matter what language is implemented in grpc, the behavior should be consistent. So the grpc server should be able to share the same port with the server created by Node's standard library http in same system process.
It is all about implementation. Each language has its own implementation for gRPC. There are many differences from each language implementation, some due to language capability but also due to the maintainers. Each project is a different project.
In this case, we can not really say that gRPC and HTTP servers are sharing the same address. There is only the HTTP server running. However, Golang implementation for gRPC server has an option to serv the gRPC through HTTP.
Calling
server.ServeHTTP()
instead of
server.Serve()
That is possible because, under the hood, gRPC server is built on top HTTP2
This snippet from the link you shared make what I said clear
if request.ProtoMajor != 2 {
mux.ServeHTTP(writer, request)
return
}
if strings.Contains(request.Header.Get("Content-Type"), "application/grpc") {
grpcServer.ServeHTTP(writer, request)
return
}
If you want to do the same in Node, you need to check in the grpc-node implementation if there is such a thing available
Your example uses http.NewServeMux(), which is provided by the Go standard library. The Node standard library does not provide an equivalent feature, so you can't share the port that way.

What is gRPC programming surface?

In the GPRC Concept document
http://www.grpc.io/docs/guides/concepts.html
The gRPC programming surface concept is mentioned without a definition. Anyone knows exactly what is gRPC programming surface?
Quoting their documentation:
Starting from a service definition in a .proto file, gRPC provides protocol buffer compiler plugins that generate client- and server-side code. gRPC users typically call these APIs on the client side and implement the corresponding API on the server side.
On the server side, the server implements the methods declared by the service and runs a gRPC server to handle client calls. The gRPC infrastructure decodes incoming requests, executes service methods, and encodes service responses.
On the client side, the client has a local object known as stub (for some languages, the preferred term is client) that implements the same methods as the service. The client can then just call those methods on the local object, wrapping the parameters for the call in the appropriate protocol buffer message type - gRPC looks after sending the request(s) to the server and returning the server’s protocol buffer response(s).
In short, the surface is the contract between the client and the service and its realization as the clientside layer (the stub) and the serverside implementation.

split HTTP and TCP-only (non-HTTP) traffic

I have web application that runs on Tomcat (and gets HTTP requests) and some other backend standalone application that gets only TCP. For some reasons, I can use outside only port 8080. So, I need to get all TCP requests (from outside) to port 8080 and forward HTTP ones to web application on Tomcat and all TCP pure requests (that are not HTTP) - to standalone application. Internal forwarding could be done to any port, e.g. 8181 on Tomcat and 8282 on standalone application. Is it possible to setup such configuration? How it could be done?
Thanks in advance.
TCP and HTTP are protocols in different networking stack layer. If you want to use some application to filter HTTP requests, your application should deal with Application-Layer information, not Network-Layer(like TCP/UDP).
I don't see how this can be possible generally. You could look packet-by-packet, but the middle of an http body can be arbitary so you can't just look at the data of each packet
If any particular client will send you either http or general TCP but not both, can you do this by source-IP address? Do you know the addresses of either the servers that will send you http requests or the ones that will send you TCP requests?
If you don't know the source IPs, you could heuristically look at the first packet from some previously unknown IP and see if it looks like http, then tag that address as containing http traffic.
What is the content/format ot the TCP communication? Is there any pattern you can detect in that?
Y
Perhaps you could do something like this using iptables + L7 filter. Of course this will only work if you run Linux on your box. Also I don't know how recently l7 filter project has been updated.
Java servlet technology is not limited to Http. The servlet interface lets you read in the incoming input stream via ServletRequest.getInputStream(). So you can create an implementation of Servlet interface and map it in web.xml and you are all set to receive any TCP traffic.
Once you have the read the input stream to sniff the content you will want to forward HTTP requests to an HttpServlet. To do this you will need to make sure that the input stream you pass on is positioned at the very beginning of the input.
EDIT: On reading your question once again, I noticed that you don't plan to expose the Tomcat directly on external port as I originally thought. If you are willing to make the tomcat listen on the external port, you can try the approach described above

How to implement HTTP Tunneling

I've written a Flash (Flex) client connecting to a back-end server to exchange data.
I've also written my server from scratch, and it serves two purposes:
(1) Web (HTTP) Server- By default listens on port 80
(2) Socket/Application- Server - By default listens on port 443
Just FYI, both servers run in the same process space, for convenience reasons. They are not expected to handle massive loads, so I'm fine with that.
As soon as the Flash client is served to the browser from the HTTP socket, the client attempts to open an XMLSocket to the Socket/Application server.
I now want to implement HTTP tunneling, so that my client can connect to the Application server even if the user is behind a firewall. I do not want any external servers involved (proxies etc.) - simply use the servers I already have.
My questions:
(1) Is it better to use port 443 for that? (does it better fool firewalls?)
(2) As far as I can see, what I am required to do, is just ensure that my actual application data is simply encapsulated in an HTTP structure (preceded by a dummy HTTP header), both from the client and server sides. Is that so or am I missing anything here?
(3) Do I need to keep hiding/encapsulating my data every message I send through the socket, or can I just encapsulate the first message when opening the connection?
Thanks in advance guys!
Fuzz
Don't reinvent the wheel - use remoting via AMF protocol. AMF an HTTP-based binary format that performs serialization between ActionScript (MXML) and server side languages. Technically, this is HTTP tunneling.
Adobe offers BlazeDS (open source) and LCDS (commercial) implementations of AMF for AS/Java, but there are third-party implementations of AMF for AS/PHP, AS/Python, AS/Ruby, AS/.Net.
BTW, AMF is an open source format.

Resources