Upgrade Request Required when running exec in Kubernetes - java

Im using fabric8 Kubernetes Java Client and Im accessing Kubernetes through HTTP, I followed the example from
fabric8 but I get the following error:
Expected HTTP 100 but received 400 instead, Bad Request.
What do I need to do to upgrade my connection to http/2?

I found out that this has to do with http2, because Kubernetes exec uses SPDY, the problem went away when I upgraded to curl version > 7.36 and installed nghttp2 on the server.
After installing curl I was able to get the response by adding some headers
curl -H "Connection: upgrade" -H "Upgrade: SPDY/3.1" {master url:port/pod/exec}

Related

Can not connect from flutter app to java backend running on Google Cloud Run

I have deployed a java backend in a docker container running on Google Cloud Run, now am having connection issues. I can reach my java backend using chrome and postman, but not flutter.
I am connecting to it using a flutter app. My java backend uses Jetty embedded for http. Previous to this, I did development on my local machine, and in the flutter app I would hard code in my servers LAN IP. The client connected reliably in this scenario
I have since deployed to Google Cloud Run and am not able to connect to the backend with my client.
I have tested the docker container locally, and I was able to connect to my backend when running the container using this command...
docker run -p 8080:8080 --network="host" image1
In the google cloud run console, I set the port to 8443.
In my flutter app. I have changed the URL from...
https://192.168.100.103:8080
To the url the Google Cloud Run specifies as my IP (I then added the port)...
https://blahblah-82j3flsijf-uc.a.run.app:8080
My flutter code that establishes the connection is as follows...
HttpClient client = HttpClient();
client.connectionTimeout = Duration(seconds:2); // throws SocketException after timeout
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true); // find the way to specifically accept a self signed certificate
HttpClientRequest request = await client.getUrl("https://blahblah-82j3flsijf-uc.a.run.app:8443");
request.headers.contentLength = requestBody.length;
request.write(requestBody);
My java backend code that establishes the jetty http server is as follows....
Server server = new Server(8080);
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]{ new MessageHandler(), new DefaultHandler()});
server.setHandler(handlers);
server.start();
server.join();
When I try to connect from my flutter client, I get http 400 bad request.
I solved my issue. I had a few problems here.
First was that I was using https encryption in my java app when Google Cloud Run takes care of that for me. So I disabled https in my java app. I assume Google Cloud Run requires your container to handle only http requests (not positive though).
Secondly, I changed all my ports to run the Google Cloud Run default of 8080, and then completely removed the port from my flutter url.
Thirdly, I was calling HttpClient.getUrl which performs an http GET, but I was also adding a request body to the get. You should not add a body to a GET request. This previously worked for me because both my jetty based java backend, and the flutter dart:io HttpClient are completely fine with this violation, and both worked with a GET with a body. As soon as I introduced Google Cloud Run layer, it introduced more stringent enforcement of the http protocol, and correctly returned bad request when I sent a GET with a body.
If you are adding a body, use dart:io HttpClient.postUrl.

Force tomcat to use only HTTP 1.0 or ignore Except header

Is there a possibility to force tomcat to ignore "Expect" header or to use only HTTP 1.0?
I am sending curl request curl POST -vv 'http://127.0.0.1:8080/test' -d "#requests/test.xml" -H "SOAPAction: abc/test" -H "Content-Type: text/xml; charset=UTF-8" and curl adds by default "Expect" header which causes server waits for another request which never come.
Tech stack: Springboot 2.1.3.RELEASE, Tomcat 9.0.16
I cannot modify clients and to their requests empty header "Expect:".
I don't think there is a way to get Tomcat to respond only with an HTTP 1.0 response. That would be a protocol violation. If server gets an HTTP 1.1 request it must either respond with a HTTP 1.1 compatible response, or signal that it can't with a 505 HTTP Version Not Supported error.
Likewise, I don't think there is a way to get Tomcat to ignore a (well-formed / non-empty) Expect header. That would also be a protocol violation.
(While it is possible in theory for a server to violate the spec, I couldn't find a way to configure Tomcat to do that. Obviously you could download the Tomcat source code and modify it, but then you have the problem of maintaining your "fork".)
So what are the alternatives:
The HTTP spec says that server must ignore an Expect header in an HTTP 1.0 request. So you could add the --http1.0 option to the curl command.
The curl command uses a defaults file - ~/.curlrc - to get default overrides for various things. You could add an empty default for the Expect header into this file; see How to setup default "Expect" header for curl.
However, I think you may be worried unduly:
If you are worried that this will slow up the client (curl), don't. By default it only waits for 1 second for the 100 Continue response. (And I don't think that is what you are talking about ...)
If you are worried that this might tie up server side resources (in Tomcat), I can't see how that could be significant. The Tomcat server will timeout and close a client connection if there is no activity. This should deal with a curl command that sends the initial request but doesn't follow up.

Apache Mina SSHD port forwarding like NGROK

I'm trying to implement a "dynamic" proxy forward to access localhost from Internet, like Ngrok in pure Java.
This guy does essentially the same thing: https://serveo.net/#intro (but, without a client)
The idea would be to use the SAME port on the server, and make a dynamic proxy for each client, based on a subdomain
The problem is that the default implementation throws error on the second connection .. saying that the port is already open.
org.apache.sshd.common.forward.DefaultForwardingFilter # doBind
Who has an idea of how to implement this?
The advantage of this is that you do not even need a CLIENT like Ngrok for that ... just using normal ssh would be possible.
ssh -R http2:9000:localhost:8002 localhost -p 4440
ssh -R http2:pSERVER:localhost:pLOCAL localhost -p SSHD_PORT
an option I imagined, is to generate the ports dynamically on the server: IGNORING THE 'pSERVER' port, and creating an HttpProxy, to do the redirection for each port. But I find this very inefficient, I believe it would be possible to do only by analyzing the request header and making the redirects for the corresponding channels / connections
After too much headache.
The code is in very low quality, just a proof of concept that can be implemented.
The implemented idea was made by changing sshd-netty, and adding a function to unpack the http request and remove the HOST HEADER (this needs to be improved here).
Only 1 port on the server is used, and it is kind of a reverse proxy for clients ...
I would like the help of the developers to improve the code in question. My knowledge in Netty and Mina is very limited.
Appreciate:
Source: https://github.com/ricardojlrufino/sshd-dyn-tunneling
Testing: Open 2 connections:
ssh -v -R http1:9000:localhost:8001 localhost -p 4440
ssh -v -R http2:9000:localhost:8002 localhost -p 4440
Make requests:
curl -v -H "Host: http1" http1:9000
curl -v -H "Host: http2" http2:9000
Start test servers:
https://github.com/ricardojlrufino/sshd-dyn-tunneling/blob/tunel/src/test/resources/setup_remotes.sh

Is command line the only way to configure wildfly 10 programatically?

From what I can tell, the docs all point to the command line interface. We have a java interface that can call a section of our API that is generic that uses JMX for weblogic to configure everything. Our code would be more simple if I kept it similar between the two server types.
What I am finding is that everything I would normally configure in JMX (JDBC, Mail Sessions, JMS, etc) is documented to be called by wildfly on command line.
Is this the normal (recommended) way to configure wildfly so it is ready for your EAR deployment?
One way is to use the native management API - ModelControllerClient - in Java to do your configuration tasks:
ModelControllerClient client = ModelControllerClient.Factory
.create(new ModelControllerClientConfiguration.Builder().setHostName(HOSTNAME).setPort(9990)
.setConnectionTimeout(36000).build());
ModelNode operation = new ModelNode();
operation.get("operation").set("whoami");
operation.get("verbose").set("true");
ModelNode result = client.execute(operation);
System.out.println(result.toString());
Other way is to use the HTTP management API and do the same by this way using any fitting client (e.g. curl):
curl --digest -u admin:passwd.123 -L -D - http://localhost:9990/management \
--header "Content-Type: application/json" \
-d '{"operation":"whoami","verbose":"true","json.pretty":1}'

HTTP test server: print all client requests to stdout

I need simple web server for debugging my application (Arduino web client, curl, etc.).
What is my idea:
I run command like
curl -X POST -H "Content-Type: application/json" \
-H "Accept: application/json" -d '{"address":"192.168.200.3", \
"title":"Abc" }' http://SERVER/xyz
to test webserver running at http://SERVER:80. This webserver write data + all http headers to standard terminal output.
It will be great for testing Arduino with Ethernet shield.
Is there any exiting product (for Linux)? I can write it in Java, but I do not want to reinvent the wheel...
I always use nc (netcat) for this, in a style like:
nc -l -p 8080
It isn't really a "HTTP server" but only a dumb TCP server, but if you're mostly interested in seeing the client request and not necessarily serving back a proper HTTP response then it is good enough.

Categories