Receive non Http messages using jetty - java

I am using embedded jetty and spring for java to java communication over http. My problem is that my server application must handle plain TCP messages also on the same port.
Is there a way to detect if a TCP message arrived which cannot be handled by the servlet?
Thanks for the answers I add some more details:
I cannot modify the client. The reason for this is that the old version of the client uses pure java tcp socket and it turned out that the new server must be backward compatible with the old client.
Have to use the same port
Old client messages are short serialized text over simple socket. 1: open connection, 2: send text, 3: close connection
My server looks something like this: http://kielczewski.eu/2013/11/using-embedded-jetty-spring-mvc/
I do not need to parse the message. It is enough to detect that a message was arrived which is not using http and get the source host name.

You might want to take a look at how to add a custom ConnectionFactory to the ServerConnector of your HTTP port.
This ConnectionFactory concept is how the PROXY Protocol is supported within Jetty currently.
In your case, you might have something like ...
MyTcpConnectionFactory tcpConnectionFactory = new MyTcpConnectionFactory();
ServerConnector http = new ServerConnector(server);
http.addFirstConnectionFactory(tcpConnectionFactory);
server.addConnector(http);
In your case, you would override the newConnection(Connector connector, EndPoint endPoint) method and implement the check for your TCP flow, or the HTTP flow.
If its your flow, you handle the communications on that connection yourself and then throw an IOException when you are done indicating that you don't want jetty to process that connection as HTTP.
Otherwise you return that Connection object to Jetty to process as HTTP.

You are in for a wild ride here my friend. You need to realize that HTTP IS TCP ... its just the content being sent on the TCP socket that classifies it as HTTP or not. That being said, you can intercept the Connection with a filter ie
1) create a filter (google Java Application Server Filters and check the Jetty implementation) for ALL incoming connections
2) check for URI on the request, if it fails, then the request is not HTTP (might want to double check on the request testing logic here)
3) Redirect the request to the appropriate Servlet / Function based on serial socket / http request
On another note, why not use https (port 443) for http and port 80 for your socket requirments ?
I stand corrected. Filters wont work.
In that case, you will have to code a mini firewall. you have to scan all inputs for https headers and redirect accordingly. Can you at least provide some context on the plain TCP messages you want to receive? do you have any control over the sending code ? you do know you can upgrade a TCP/HTTP connection to a websocket (involves client and server) and it will work even better than plain TCP, same port connections, and comes built in Jetty so no custom boiler plates, just a websocket servlet

Related

Jetty - proxy server with dynamic registration

We have a number of Jetty http(s) servers, all behind different firewalls. The http servers are at customer sites (not under our control). Opening ports in the firewalls at these sites is not an option. Right now, these servers only serve JSON documents in response to REST requests.
We have web clients that need to interact with a given http server based on URL parameter or header value.
This seems like a straightforward proxy server situation - except for the firewall.
The approach that I'm currently trying is this:
Have a centralized proxy server (also Jetty based) that listens for inbound registration requests from the remote http servers. The registration request will take the form of a Websocket connection, which will be kept alive as long at the remote HTTP server is available. On registration, the Proxy Server will capture the websocket connection and map it to a resource identifier.
The web client will connect the proxy server, and include the resource identifier in the URL or header.
The proxy server will determine the appropriate Websocket to use, then pass the request on to the HTTP server. So the request and response will travel over the Websocket. Once the response is received, it will be returned to the web client.
So this is all well and good in theory - what I'm trying to figure out is:
a) is there a better way to achieve this?
b) What's the best way to set up Jetty to do the proxying on the HTTP Server end of the pipe?
I suppose that I could use Jetty's HttpClient, but what I really want to do is just pull the HTTP bytes from the websocket and pipe them directly into the Jetty connector. It doesn't seem to make sense to parse everything out. I suppose that I could open a regular socket connection on localhost, grab the bytes from the websocket, and do it that way - but it seems silly to route through the OS like that (I'm already operating inside the HTTP Server's Jetty environment).
It sure seems like this is the sort of problem that may have already been solved... Maybe by using a custom jetty Connection that works on WebSockets instead of TCP/IP sockets?
Update: as I've been playing with this, it seems like another tricky problem is how to handle request/response behavior (and ideally support muxing over the websocket channel). One potential resource that I've found is the WAMP sub-protocol for websockets: http://wamp.ws/
In case anyone else is looking for an answer to this one - RESTEasy has a mocking framework that can be used to invoke the REST functionality without running through a full servlet container: http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html_single/index.html#RESTEasy_Server-side_Mock_Framework
This, combined with WAMP, appears to do what I'm looking for.

Netty4 application as both client and a server

I want to write a program in Netty4 that should act as a server to other clients and also it itself is a client to another server. How to do this in Netty4? So far all examples I have seen are either client or server. Thanks.
There are no special difficulties here. You need to create a part that will act as a server (using ServerBootstrap), and a part that will act as a client (using Bootstrap).
If you need to establish a connection to another server while handling incoming connection from a client, you can place that logic into a ChannelHandler of the server's pipeline.
Netty provides two examples of this approach:
Hex dumping proxy
SOCKS proxy

jsocks library for proxy

it's been a 2 days i find "jSocks" library.
i tried so may to findout how i can code with this library.
i must say that documentation is very poor.
i don't want you to code for me, i just want a simple workflow.
here is my scenario:
1) i want to write 2 app, one for client and one for server.(it's simple client server proxy)
2) client app will listen to specific port on localhost (127.0.0.1) for incoming connection (for example browser request).
3) client app accept incoming connection from browser and create a socks socket between her and browser for send and recieve data.
4) client app create a socks socket between her and server app (server app hosted on web and listening to a port for incoming connection).
5) server app accept incoming connection and create a socks socket for Communicate.
6) server app recieve data ( may be browser request ), process it and connect to a remote web site(on internet).
7) server app recive data from web and send it to client app.
8) client app send the recived data to browser.
i create this app with java standard "Socket" & "ServerSocket" for http request without problem, now i want to write this program with socks socket for all request.
i tried every thing with jsocks without any success.
i need a workflow on how to work with jsocks for creating this app.
tnx.
#BGR
acording to your mentioned file (SOCKS.java) the simple line like below must work :
ServerAuthenticator auth = new ServerAuthenticatorNone();
ProxyServer pServer = new ProxyServer(auth);
pServer.setLog(System.out);
pServer.start(50352);
when i execute this, the log is : Starting SOCKS Proxy on:0.0.0.0:50352 (if i pass 127.0.0.1 as address to start() method, log is "Starting SOCKS Proxy on:127.0.0.1:50352 but the result is the same)
but when i redirect my browser request to this port nothing happens.
acually i'am not sure how the start(port) method works, because it's void.
when i use ServerSocket, accept() method it return me a Socket for communication.
but when i use start(port) nothing will return
I am not sure I full understand your request (a socks server is meant for proxying; it is constantly listening on a single port and forwards requests) but looking at this java file it seems reasonable easy to create a Socks proxy server using jsocks.
Once you proxy server is running, you create a java socket on your client using this constructor where you specify the location of your socks proxy server. You then connect to your remote server SocketAddress and
... that should be it.
You seem to have lot of redirections going on. Maybe you should chart a diagram of your flows and see where you need a Socks proxy server and why.

Implementing a protocol exchanging four messages within a single persistent connection

I have a complete implementation of a protocol where four messages are exchanged between the client (a native Android application) and the server (a standalone Java server) in the following way using a persistent connection through Java sockets:
(client->server): message1
(server->client); message2
(client->server): message3
(server->client): message4
Between sending each message, both client and server have to do heavy mathematical (cryptographic) operations (pairing-based computations over elliptic curves).
This project works properly in my local development machine using sockets and mantaining opened this socket from message1 to the message4 between the Android app and the Java server. Now, I need to do the same with Google AppEngine, but since it does not allow opening sockets, I do not know how can I do it. I already checked the Channel and XMPP APIs, but I do not know whether my use-case applies to that APIs. Is it the right method using Channel and XMPP APIs from AppEngine? Is it possible to emulate the functionality implemented in my local machine through sockets on AppEngine?
Thank you for your response.
Google App Engine doesn't support persistent connections.
You will need to significantly re-design your protocol to run over HTTP.
As an example, message1 can be sent over an HTTP request, message2 can be returned with the matching HTTP response. At that point, your socket connection ends.
You'll have to issue a second HTTP request to open a new socket with message3, and you can return message4 with the second HTTP response.
You can "connect" the first and second HTTP request by using an HTTP session. A session is basically an id with extra data stored on the server side. You'd create the session in the first HTTP request, and pass it as a parameter to the second HTTP request. The server can look up the session id and the associated data when processing the second request.
You can find more info about sessions on SO: How to use session on Google app engine
The XMPP API will not help you, it's for communicating between the GAE server-side code and other XMPP clients that use HTTP as a communcation protocol.
The Channel API can be used to send data from the server->client, but it's actually implemented as an HTTP long poll. Multiple long HTTP requests are used, and you are not guaranteed to have a single socket that stays open; multiple sockets are opened and closed in the process. It will be more complicated that what I described above, and more expensive.

Listening for an HTTP Request

I have an assignment where I need to create a Proxy server, that will manipulate some of the requests/responses it gets, implement caching, etc.
For starters, I want to create the simplest proxy, that simply passes on all requests and responses. I've done some searches online and I am a bit confused on how to listen to requests in a certain port and get the HTTP requests. I've stumbled on the classes Socket, ServerSocket, HttpURLConnection, but I'm not sure how all these interact. I tried to read the docs, but they are all intertwined and a bit hard to understand.
Can you point me in the right direction regarding which classes I should probably use for this assignment, and maybe share a snippet for listening on a port, getting HTTP request headers, etc.?
Well, I can only assume that your Proxy will be a ServerSocket listening for requests on the HTTP port. You read the request through the server socket input stream. After checking the request is compliant with the proxy's rules you will open a HttpConnection to the real HTTP Server, and using the output stream in the http connection you will forward the client's request, then using the http connection input stream, you read the real HTTP Server's response, which you will ultimately forward back to the client using the socket's output stream.
In the proxy, since you intercept requests and responses you can manipulate them before forwarding.
Sounds right?
Here's some introductory Java socket material: http://www.oracle.com/technetwork/java/socket-140484.html

Categories