Java proxy https implementation - java

I try to make my own proxy server and already implemented the http support for my proxy server. The proxy server works fine.
Now I want to have https as well (only with sockets). I looked up what I have to do at https://www.rfc-editor.org/rfc/rfc2817.
In my function I try to establish a TLS tunnel.
With my approach I only get a method not allowed as response. I also check some source in the internet, but didn't find anything which can help me with my problem.
Here is my function.
private Socket openTLSTunnel(String host) throws IOException {
String raw_request = "CONNECT " + host + ":80 HTTP/1.1\n"
+ "Host: " + host + ":80"
+ "\r\n\r\n";
// Make a connection to the website.
Socket tunnel = new Socket();
int timeout = 10000;
var server = new InetSocketAddress(host, 80);
tunnel.connect(server, timeout);
// Write the request to server.
OutputStream out = tunnel.getOutputStream();
byte[] msg = raw_request.getBytes(StandardCharsets.UTF_8);
out.write(msg);
out.flush();
// TODO send error to client.
// Get the response from server.
InputStream in = tunnel.getInputStream();
byte reply[] = new byte[200];
int replyLen = 0;
int newlinesSeen = 0;
boolean headerDone = false;
while (newlinesSeen < 2) {
int i = in.read();
if (i < 0) {
throw new IOException("Unexpected EOF from proxy");
}
if (i == '\n') {
headerDone = true;
++newlinesSeen;
}
else if (i != '\r') {
newlinesSeen = 0;
if (!headerDone && replyLen < reply.length) {
reply[replyLen++] = (byte) i;
}
}
}
String replyStr = new String(reply, 0, replyLen, "ASCII7");
// Check if connection established.
if(!replyStr.toLowerCase().contains("200 connection established")) {
System.out.println("No TLS connection established!");
throw new AccessDeniedException(replyStr);
}
else{
System.out.println("Connection established!");
}
return tunnel;
}
Thanks in advance!

Related

java opening a socket at wrong ip address [duplicate]

This question already has answers here:
Setting a timeout for socket operations
(6 answers)
Closed 7 years ago.
There are 2 backend machines which will provide the same content. I'm trying to create a round-robin setup and fail-safe so that if one goes down, the request should be sent to other.
As for the round-robin thing, my code is working fine.
For the fail-safe thing, I'm trying to change one IP to some invalid ip (on which no service is running) and then it should connect to other. But it is getting hung up on the line:
client = new Socket(ip, port);
What can be done for this? If I'm not getting connection in 2 seconds, I don't want to retry (if that is what java does, can I reduce the retry timeout?).
Also, after long time, it throws IllegalStateException (I was not expecting it at all)
Here is my constructor for Connect.java:
//Variable declartion
private static int balancer = 0;
private static boolean[] down = {false, false};
private static int[] countDown = {0, 0};
private static final int maxRequests = 10000;
private static int countRequests = 0;
//Constructor
public Connect() throws NullPointerException{
int use = balancer;
int flag = 0;
countRequests = (countRequests + 1) % maxRequests;
if(countRequests == 0){
down[0] = down[1] = false;
}
if((balancer == 0 && down[0] == false) || down[1] == true){
ip = Config.IP1;
port = Config.PORT1;
use = 0;
System.out.println("balancer = 0");
}
else{
ip = Config.IP2;
port = Config.PORT2;
use = 1;
System.out.println("balancer = 1");
}
LOGGER.setLevel(Level.INFO);
// Single simple socket
try {
client = new Socket(ip, port);
System.out.println("client");
dos = new DataOutputStream(client.getOutputStream());
dis = new DataInputStream(client.getInputStream());
if(client == null || dos == null || dis == null){
throw new IOException("Connection could not be opened properly\n");
}
LOGGER.log(Level.INFO, "Connection to : " + ip + " Successfully opened");
balancer = (balancer == 0) ? 1 : 0;
countDown[use] = 0;
flag = 1;
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
countDown[use] ++;
if(countDown[use] >= 3){
down[use] = true;
}
LOGGER.log(Level.SEVERE, ": " + ip + " " + e.getMessage());
}
finally{ //if connection was not opened on first
if(flag == 0){
if(use == 0){
ip = Config.IP2;
port = Config.PORT2;
use = 1;
}
else{
ip = Config.IP1;
port = Config.PORT1;
use = 0;
}
try {
client = new Socket(ip, port);
dos = new DataOutputStream(client.getOutputStream());
dis = new DataInputStream(client.getInputStream());
if(client == null || dos == null || dis == null){
throw new IOException("Connection could not be opened properly\n");
}
LOGGER.log(Level.INFO, "Connection to " + ip + " Successfully opened");
balancer = (balancer == 0) ? 1 : 0;
countDown[use] = 0;
flag = 1;
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
countDown[use] ++;
if(countDown[use] >= 3){
down[use] = true;
}
LOGGER.log(Level.SEVERE, ": " + ip + " " + e.getMessage());
throw new NullPointerException("Connection could not be opened properly on both machines\n");
}
}
}
}
What I expected was an IO/NullPointer-Exception and then catch block will be executed
How about using the default Socket() constructor, and then connect(SocketAddress, int), which allows you to specify a specific timeout?
Example:
import java.net.*;
public class Test {
public static void main(String[] args) throws Exception {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(args[0], 80), 2000);
}
}
You can see the timeout in action by timing it:
$ time java Test google.com
real 0m0.154s
user 0m0.079s
sys 0m0.022s
$ time java Test 192.168.2.123
Exception in thread "main" java.net.SocketTimeoutException: connect timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at Test.main(Test.java:5)
real 0m2.111s
user 0m0.076s
sys 0m0.026s

Java sending handshake packets to minecraft server

I have been working on a java program that basically acts like Minechat(text-based app to just view chat.) I have never really worked with networking too much, so the issue is figuring out how to send packets correctly. I am currently at the position of creating the handshake with the server. After hours of research, I have come up with the following code, but it always runs into the "Failed! (Exception)" message. To me, everything looks correct, but for all I know it could be 100% wrong. If someone could point out what I'm doing wrong here, I'd really appreciate it.
For reference, feel free to use this and this.
public static void main(String[] args) throws IOException {
host = new InetSocketAddress("162.244.165.111", 48040);
socket = new Socket();
System.out.println("Connecting...");
socket.connect(host, 3000);
System.out.println("Done!");
System.out.println("Making streams...");
output = new DataOutputStream(socket.getOutputStream());
input = new DataInputStream(socket.getInputStream());
System.out.println("Done!");
System.out.println("Attempting handshake... "+host.getAddress().toString().substring(1));
byte[] msg = ("47;"+host.getAddress().toString().substring(1)+";"+host.getPort()+";2;").getBytes(Charset.forName("UTF-16"));
output.writeInt(msg.length+Integer.valueOf(0x00));
output.writeByte(0x00);
output.write(msg);
output.flush();
try {
if (input.readByte() != 0x02)
System.out.println("Failed!");
else
System.out.println("Done!");
} catch (EOFException e) {
System.out.println("Failed! (Exception)");
}
}
EDIT:
More research suggests I use a Byte array, but this confuses me on how to represent a string and using strings is required?
Looking at this page http://wiki.vg/Protocol it looks like your not writing enough data nor in the right order. You also need to be using varint which is a special type of data representation of an integer.
Relevant links to this issue:
Handshake Protocol
Packet format
Server Ping Explanation and Example (which involves handshake)
The status ping works as follows:
C->S : Handshake State=1
C->S : Request
S->C : Response
C->S : Ping
S->C : Pong
C is client and S is server
Using the wiki and the provided code samples I modified your code to follow the entire status request.
public static void main(String [] args) throws IOException {
String address = "162.244.165.111";
int port = 48040;
InetSocketAddress host = new InetSocketAddress(address, port);
Socket socket = new Socket();
System.out.println("Connecting...");
socket.connect(host, 3000);
System.out.println("Done!");
System.out.println("Making streams...");
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
DataInputStream input = new DataInputStream(socket.getInputStream());
System.out.println("Done!");
System.out.println("Attempting handshake... "+host.getAddress().toString());
byte [] handshakeMessage = createHandshakeMessage(address, port);
// C->S : Handshake State=1
// send packet length and packet
writeVarInt(output, handshakeMessage.length);
output.write(handshakeMessage);
// C->S : Request
output.writeByte(0x01); //size is only 1
output.writeByte(0x00); //packet id for ping
// S->C : Response
int size = readVarInt(input);
int packetId = readVarInt(input);
if (packetId == -1) {
throw new IOException("Premature end of stream.");
}
if (packetId != 0x00) { //we want a status response
throw new IOException("Invalid packetID");
}
int length = readVarInt(input); //length of json string
if (length == -1) {
throw new IOException("Premature end of stream.");
}
if (length == 0) {
throw new IOException("Invalid string length.");
}
byte[] in = new byte[length];
input.readFully(in); //read json string
String json = new String(in);
// C->S : Ping
long now = System.currentTimeMillis();
output.writeByte(0x09); //size of packet
output.writeByte(0x01); //0x01 for ping
output.writeLong(now); //time!?
// S->C : Pong
readVarInt(input);
packetId = readVarInt(input);
if (packetId == -1) {
throw new IOException("Premature end of stream.");
}
if (packetId != 0x01) {
throw new IOException("Invalid packetID");
}
long pingtime = input.readLong(); //read response
// print out server info
System.out.println(json);
System.out.println("Done!");
}
public static byte [] createHandshakeMessage(String host, int port) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream handshake = new DataOutputStream(buffer);
handshake.writeByte(0x00); //packet id for handshake
writeVarInt(handshake, 4); //protocol version
writeString(handshake, host, StandardCharsets.UTF_8);
handshake.writeShort(port); //port
writeVarInt(handshake, 1); //state (1 for handshake)
return buffer.toByteArray();
}
public static void writeString(DataOutputStream out, String string, Charset charset) throws IOException {
byte [] bytes = string.getBytes(charset);
writeVarInt(out, bytes.length);
out.write(bytes);
}
public static void writeVarInt(DataOutputStream out, int paramInt) throws IOException {
while (true) {
if ((paramInt & 0xFFFFFF80) == 0) {
out.writeByte(paramInt);
return;
}
out.writeByte(paramInt & 0x7F | 0x80);
paramInt >>>= 7;
}
}
public static int readVarInt(DataInputStream in) throws IOException {
int i = 0;
int j = 0;
while (true) {
int k = in.readByte();
i |= (k & 0x7F) << j++ * 7;
if (j > 5) throw new RuntimeException("VarInt too big");
if ((k & 0x80) != 128) break;
}
return i;
}

Java Tunnel HTTPS(SSL) Requests

I am writing a java application to serve as a local proxy. I have been helped greatly by this piece of code from http://www.nsftools.com/tips/jProxy.java. See program below:
/* <!-- in case someone opens this in a browser... --> <pre> */
/*
* This is a simple multi-threaded Java proxy server
* for HTTP requests (HTTPS doesn't seem to work, because
* the CONNECT requests aren't always handled properly).
* I implemented the class as a thread so you can call it
* from other programs and kill it, if necessary (by using
* the closeSocket() method).
*
* We'll call this the 1.1 version of this class. All I
* changed was to separate the HTTP header elements with
* \r\n instead of just \n, to comply with the official
* HTTP specification.
*
* This can be used either as a direct proxy to other
* servers, or as a forwarding proxy to another proxy
* server. This makes it useful if you want to monitor
* traffic going to and from a proxy server (for example,
* you can run this on your local machine and set the
* fwdServer and fwdPort to a real proxy server, and then
* tell your browser to use "localhost" as the proxy, and
* you can watch the browser traffic going in and out).
*
* One limitation of this implementation is that it doesn't
* close the ProxyThread socket if the client disconnects
* or the server never responds, so you could end up with
* a bunch of loose threads running amuck and waiting for
* connections. As a band-aid, you can set the server socket
* to timeout after a certain amount of time (use the
* setTimeout() method in the ProxyThread class), although
* this can cause false timeouts if a remote server is simply
* slow to respond.
*
* Another thing is that it doesn't limit the number of
* socket threads it will create, so if you use this on a
* really busy machine that processed a bunch of requests,
* you may have problems. You should use thread pools if
* you're going to try something like this in a "real"
* application.
*
* Note that if you're using the "main" method to run this
* by itself and you don't need the debug output, it will
* run a bit faster if you pipe the std output to 'nul'.
*
* You may use this code as you wish, just don't pretend
* that you wrote it yourself, and don't hold me liable for
* anything that it does or doesn't do. If you're feeling
* especially honest, please include a link to nsftools.com
* along with the code. Thanks, and good luck.
*
* Julian Robichaux -- http://www.nsftools.com
*/
import java.io.*;
import java.net.*;
import java.lang.reflect.Array;
public class jProxy extends Thread
{
public static final int DEFAULT_PORT = 8080;
private ServerSocket server = null;
private int thisPort = DEFAULT_PORT;
private String fwdServer = "";
private int fwdPort = 0;
private int ptTimeout = ProxyThread.DEFAULT_TIMEOUT;
private int debugLevel = 0;
private PrintStream debugOut = System.out;
/* here's a main method, in case you want to run this by itself */
public static void main (String args[])
{
int port = 0;
String fwdProxyServer = "";
int fwdProxyPort = 0;
if (args.length == 0)
{
System.err.println("USAGE: java jProxy <port number> [<fwd proxy> <fwd port>]");
System.err.println(" <port number> the port this service listens on");
System.err.println(" <fwd proxy> optional proxy server to forward requests to");
System.err.println(" <fwd port> the port that the optional proxy server is on");
System.err.println("\nHINT: if you don't want to see all the debug information flying by,");
System.err.println("you can pipe the output to a file or to 'nul' using \">\". For example:");
System.err.println(" to send output to the file prox.txt: java jProxy 8080 > prox.txt");
System.err.println(" to make the output go away: java jProxy 8080 > nul");
return;
}
// get the command-line parameters
port = Integer.parseInt(args[0]);
if (args.length > 2)
{
fwdProxyServer = args[1];
fwdProxyPort = Integer.parseInt(args[2]);
}
// create and start the jProxy thread, using a 20 second timeout
// value to keep the threads from piling up too much
System.err.println(" ** Starting jProxy on port " + port + ". Press CTRL-C to end. **\n");
jProxy jp = new jProxy(port, fwdProxyServer, fwdProxyPort, 20);
jp.setDebug(1, System.out); // or set the debug level to 2 for tons of output
jp.start();
// run forever; if you were calling this class from another
// program and you wanted to stop the jProxy thread at some
// point, you could write a loop that waits for a certain
// condition and then calls jProxy.closeSocket() to kill
// the running jProxy thread
while (true)
{
try { Thread.sleep(3000); } catch (Exception e) {}
}
// if we ever had a condition that stopped the loop above,
// we'd want to do this to kill the running thread
//jp.closeSocket();
//return;
}
/* the proxy server just listens for connections and creates
* a new thread for each connection attempt (the ProxyThread
* class really does all the work)
*/
public jProxy (int port)
{
thisPort = port;
}
public jProxy (int port, String proxyServer, int proxyPort)
{
thisPort = port;
fwdServer = proxyServer;
fwdPort = proxyPort;
}
public jProxy (int port, String proxyServer, int proxyPort, int timeout)
{
thisPort = port;
fwdServer = proxyServer;
fwdPort = proxyPort;
ptTimeout = timeout;
}
/* allow the user to decide whether or not to send debug
* output to the console or some other PrintStream
*/
public void setDebug (int level, PrintStream out)
{
debugLevel = level;
debugOut = out;
}
/* get the port that we're supposed to be listening on
*/
public int getPort ()
{
return thisPort;
}
/* return whether or not the socket is currently open
*/
public boolean isRunning ()
{
if (server == null)
return false;
else
return true;
}
/* closeSocket will close the open ServerSocket; use this
* to halt a running jProxy thread
*/
public void closeSocket ()
{
try {
// close the open server socket
server.close();
// send it a message to make it stop waiting immediately
// (not really necessary)
/*Socket s = new Socket("localhost", thisPort);
OutputStream os = s.getOutputStream();
os.write((byte)0);
os.close();
s.close();*/
} catch(Exception e) {
if (debugLevel > 0)
debugOut.println(e);
}
server = null;
}
public void run()
{
try {
// create a server socket, and loop forever listening for
// client connections
server = new ServerSocket(thisPort);
if (debugLevel > 0)
debugOut.println("Started jProxy on port " + thisPort);
while (true)
{
Socket client = server.accept();
ProxyThread t = new ProxyThread(client, fwdServer, fwdPort);
t.setDebug(debugLevel, debugOut);
t.setTimeout(ptTimeout);
t.start();
}
} catch (Exception e) {
if (debugLevel > 0)
debugOut.println("jProxy Thread error: " + e);
}
closeSocket();
}
}
/*
* The ProxyThread will take an HTTP request from the client
* socket and send it to either the server that the client is
* trying to contact, or another proxy server
*/
class ProxyThread extends Thread
{
private Socket pSocket;
private String fwdServer = "";
private int fwdPort = 0;
private int debugLevel = 0;
private PrintStream debugOut = System.out;
// the socketTimeout is used to time out the connection to
// the remote server after a certain period of inactivity;
// the value is in milliseconds -- use zero if you don't want
// a timeout
public static final int DEFAULT_TIMEOUT = 20 * 1000;
private int socketTimeout = DEFAULT_TIMEOUT;
public ProxyThread(Socket s)
{
pSocket = s;
}
public ProxyThread(Socket s, String proxy, int port)
{
pSocket = s;
fwdServer = proxy;
fwdPort = port;
}
public void setTimeout (int timeout)
{
// assume that the user will pass the timeout value
// in seconds (because that's just more intuitive)
socketTimeout = timeout * 1000;
}
public void setDebug (int level, PrintStream out)
{
debugLevel = level;
debugOut = out;
}
public void run()
{
try
{
long startTime = System.currentTimeMillis();
// client streams (make sure you're using streams that use
// byte arrays, so things like GIF and JPEG files and file
// downloads will transfer properly)
BufferedInputStream clientIn = new BufferedInputStream(pSocket.getInputStream());
BufferedOutputStream clientOut = new BufferedOutputStream(pSocket.getOutputStream());
// the socket to the remote server
Socket server = null;
// other variables
byte[] request = null;
byte[] response = null;
int requestLength = 0;
int responseLength = 0;
int pos = -1;
StringBuffer host = new StringBuffer("");
String hostName = "";
int hostPort = 80;
// get the header info (the web browser won't disconnect after
// it's sent a request, so make sure the waitForDisconnect
// parameter is false)
request = getHTTPData(clientIn, host, false);
requestLength = Array.getLength(request);
// separate the host name from the host port, if necessary
// (like if it's "servername:8000")
hostName = host.toString();
pos = hostName.indexOf(":");
if (pos > 0)
{
try { hostPort = Integer.parseInt(hostName.substring(pos + 1));
} catch (Exception e) { }
hostName = hostName.substring(0, pos);
}
// either forward this request to another proxy server or
// send it straight to the Host
try
{
if ((fwdServer.length() > 0) && (fwdPort > 0))
{
server = new Socket(fwdServer, fwdPort);
} else {
server = new Socket(hostName, hostPort);
}
} catch (Exception e) {
// tell the client there was an error
String errMsg = "HTTP/1.0 500\nContent Type: text/plain\n\n" +
"Error connecting to the server:\n" + e + "\n";
clientOut.write(errMsg.getBytes(), 0, errMsg.length());
}
if (server != null)
{
server.setSoTimeout(socketTimeout);
BufferedInputStream serverIn = new BufferedInputStream(server.getInputStream());
BufferedOutputStream serverOut = new BufferedOutputStream(server.getOutputStream());
// send the request out
serverOut.write(request, 0, requestLength);
serverOut.flush();
// and get the response; if we're not at a debug level that
// requires us to return the data in the response, just stream
// it back to the client to save ourselves from having to
// create and destroy an unnecessary byte array. Also, we
// should set the waitForDisconnect parameter to 'true',
// because some servers (like Google) don't always set the
// Content-Length header field, so we have to listen until
// they decide to disconnect (or the connection times out).
if (debugLevel > 1)
{
response = getHTTPData(serverIn, true);
responseLength = Array.getLength(response);
} else {
responseLength = streamHTTPData(serverIn, clientOut, true);
}
serverIn.close();
serverOut.close();
}
// send the response back to the client, if we haven't already
if (debugLevel > 1)
clientOut.write(response, 0, responseLength);
// if the user wants debug info, send them debug info; however,
// keep in mind that because we're using threads, the output won't
// necessarily be synchronous
if (debugLevel > 0)
{
long endTime = System.currentTimeMillis();
debugOut.println("Request from " + pSocket.getInetAddress().getHostAddress() +
" on Port " + pSocket.getLocalPort() +
" to host " + hostName + ":" + hostPort +
"\n (" + requestLength + " bytes sent, " +
responseLength + " bytes returned, " +
Long.toString(endTime - startTime) + " ms elapsed)");
debugOut.flush();
}
if (debugLevel > 1)
{
debugOut.println("REQUEST:\n" + (new String(request)));
debugOut.println("RESPONSE:\n" + (new String(response)));
debugOut.flush();
}
// close all the client streams so we can listen again
clientOut.close();
clientIn.close();
pSocket.close();
} catch (Exception e) {
if (debugLevel > 0)
debugOut.println("Error in ProxyThread: " + e);
//e.printStackTrace();
}
}
private byte[] getHTTPData (InputStream in, boolean waitForDisconnect)
{
// get the HTTP data from an InputStream, and return it as
// a byte array
// the waitForDisconnect parameter tells us what to do in case
// the HTTP header doesn't specify the Content-Length of the
// transmission
StringBuffer foo = new StringBuffer("");
return getHTTPData(in, foo, waitForDisconnect);
}
private byte[] getHTTPData (InputStream in, StringBuffer host, boolean waitForDisconnect)
{
// get the HTTP data from an InputStream, and return it as
// a byte array, and also return the Host entry in the header,
// if it's specified -- note that we have to use a StringBuffer
// for the 'host' variable, because a String won't return any
// information when it's used as a parameter like that
ByteArrayOutputStream bs = new ByteArrayOutputStream();
streamHTTPData(in, bs, host, waitForDisconnect);
return bs.toByteArray();
}
private int streamHTTPData (InputStream in, OutputStream out, boolean waitForDisconnect)
{
StringBuffer foo = new StringBuffer("");
return streamHTTPData(in, out, foo, waitForDisconnect);
}
private int streamHTTPData (InputStream in, OutputStream out,
StringBuffer host, boolean waitForDisconnect)
{
// get the HTTP data from an InputStream, and send it to
// the designated OutputStream
StringBuffer header = new StringBuffer("");
String data = "";
int responseCode = 200;
int contentLength = 0;
int pos = -1;
int byteCount = 0;
try
{
// get the first line of the header, so we know the response code
data = readLine(in);
if (data != null)
{
header.append(data + "\r\n");
pos = data.indexOf(" ");
if ((data.toLowerCase().startsWith("http")) &&
(pos >= 0) && (data.indexOf(" ", pos+1) >= 0))
{
String rcString = data.substring(pos+1, data.indexOf(" ", pos+1));
try
{
responseCode = Integer.parseInt(rcString);
} catch (Exception e) {
if (debugLevel > 0)
debugOut.println("Error parsing response code " + rcString);
}
}
}
// get the rest of the header info
while ((data = readLine(in)) != null)
{
// the header ends at the first blank line
if (data.length() == 0)
break;
header.append(data + "\r\n");
// check for the Host header
pos = data.toLowerCase().indexOf("host:");
if (pos >= 0)
{
host.setLength(0);
host.append(data.substring(pos + 5).trim());
}
// check for the Content-Length header
pos = data.toLowerCase().indexOf("content-length:");
if (pos >= 0)
contentLength = Integer.parseInt(data.substring(pos + 15).trim());
}
// add a blank line to terminate the header info
header.append("\r\n");
// convert the header to a byte array, and write it to our stream
out.write(header.toString().getBytes(), 0, header.length());
// if the header indicated that this was not a 200 response,
// just return what we've got if there is no Content-Length,
// because we may not be getting anything else
if ((responseCode != 200) && (contentLength == 0))
{
out.flush();
return header.length();
}
// get the body, if any; we try to use the Content-Length header to
// determine how much data we're supposed to be getting, because
// sometimes the client/server won't disconnect after sending us
// information...
if (contentLength > 0)
waitForDisconnect = false;
if ((contentLength > 0) || (waitForDisconnect))
{
try {
byte[] buf = new byte[4096];
int bytesIn = 0;
while ( ((byteCount < contentLength) || (waitForDisconnect))
&& ((bytesIn = in.read(buf)) >= 0) )
{
out.write(buf, 0, bytesIn);
byteCount += bytesIn;
}
} catch (Exception e) {
String errMsg = "Error getting HTTP body: " + e;
if (debugLevel > 0)
debugOut.println(errMsg);
//bs.write(errMsg.getBytes(), 0, errMsg.length());
}
}
} catch (Exception e) {
if (debugLevel > 0)
debugOut.println("Error getting HTTP data: " + e);
}
//flush the OutputStream and return
try { out.flush(); } catch (Exception e) {}
return (header.length() + byteCount);
}
private String readLine (InputStream in)
{
// reads a line of text from an InputStream
StringBuffer data = new StringBuffer("");
int c;
try
{
// if we have nothing to read, just return null
in.mark(1);
if (in.read() == -1)
return null;
else
in.reset();
while ((c = in.read()) >= 0)
{
// check for an end-of-line character
if ((c == 0) || (c == 10) || (c == 13))
break;
else
data.append((char)c);
}
// deal with the case where the end-of-line terminator is \r\n
if (c == 13)
{
in.mark(1);
if (in.read() != 10)
in.reset();
}
} catch (Exception e) {
if (debugLevel > 0)
debugOut.println("Error getting header: " + e);
}
// and return what we have
return data.toString();
}
}
Problem is secure sites like "https://www.google.com" don't work. I have tried to tweak the code over and over again but all to no avail. I have gone through questions answered here and many more sites too but I just cant seem to get it to work. I would av posted links but I cant cos I dnt av enuf reputation yet.
Someone pls help me with what needs to be done to support Secure Sites(HTTPS).
Thanks in advance.
PS: Sorry if I didn't ask the question the right way.I'm a newbie. Cheers...
Default port for https is 443. This is used if no port is specified in the URL, as is the case with the google site you give as an example. Try adjusting the code with this in mind.

Java UDP socket client not blocking

I'm trying to code a UDP client to receive packets from a server that is broadcasting on the local network. The problem is the receive method isn't blocking and waiting for a packet to arrive.
Instead, it's receiving null or empty packets.
I've tried to use .setSoTimeout(0), which supposedly will tell the receive to block until it receives a packet, but it doesn't.
Does anyone know how to fix this?
Here's the code:
while (search == true) {
InetAddress addr = InetAddress.getByName("0.0.0.0");
DatagramSocket sock = new DatagramSocket(1355);
sock.setSoTimeout(0);
byte[] recebe = new byte[1024];
sock.setBroadcast(true);
System.out.println("entrou1");
DatagramPacket packet = new DatagramPacket(recebe, recebe.length);
System.out.println("entrou2");
sock.receive(packet);
String info = new String(packet.getData());
System.out.println("tamanho: " + info.length());
if (info.trim().equals("") == false && info != null) {
System.out.println("entrou aqui");
System.out.println("info recebida:" + info + ":fsadfsfs");
String servs[] = info.split("\n");
list1.clear();
servidores.clear();
for (int i = 0; i < servs.length; i++) {
System.out.println("vec: " + servs[i]);
if (servs[i].trim().equals("")) {
System.out.println("break;");
break;
} else {
String aux = servs[i].substring(0, servs[i].lastIndexOf("->"));
System.out.println("aux: " + aux);
list1.add(aux);
servidores.add(servs[i]);
}
}
}
System.out.println("info:\n" + info);
sock.close();
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException ex) {
Logger.getLogger(AcederPartilhaGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

how to debug a server

I have a server that will be running on another machine and I need to debug with two different machines. Is there a way to virtually debug the server since everything runs ok on my machine but when i put it on another machine everything wrong? I dont have another machine in my possession (I can only host and see results) .
public class fss { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; boolean listening = true; boolean allowed = true; // int port = Integer.parseInt(args[0]); int port
= 60000;
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Could not transmit on port: " + port);
System.exit(-1);
}
while (listening) {
//Take the ip of the client in number form
allowed = true;
Socket socket = serverSocket.accept();
DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
String clientAddress = socket.getRemoteSocketAddress().toString();
clientAddress = clientAddress.substring(1);
for (int i = 0; i < clientAddress.length() - 1; i++) {
if (clientAddress.substring(i, i + 1).equals(":")) {
clientAddress = clientAddress.substring(0, i);
}
}
File f = new File("forbidden.txt");
if (f.exists()) {
BufferedReader forbidden = new BufferedReader(new FileReader("forbidden.txt"));
String addr;
while ((addr = forbidden.readLine()) != null) {
if (Character.isLetter(addr.charAt(0))) {//if the address is in a letter form
addr = InetAddress.getByName(addr).toString();
for (int i = 0; i < addr.length() - 1; i++) {
//System.out.println(addr.substring(i, i + 1));
if (addr.substring(i, i + 1).equals("/")) {
addr = addr.substring(i + 1);
}
}
}
if (clientAddress.equals(addr)) {
allowed = false;
break;
}
}
if (allowed == true) {
new MultiThread(socket).start();
} else {
outToClient.writeBytes("Connection refused" + "\n");
socket.close();
forbidden.close();
}
} else {
new MultiThread(socket).start();
}
}
serverSocket.close();
}
}
You will have to enable debug on server JVM.
This is typically done via following JVM args -
-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8787
You then need to connect to the process using server's IP Address and the above debug port - 8787
One of the answers has already indicated how to enable JDWP on the server. This would require that you have appropriate permissions to open the necessary port as well.
If you do not have this permission, I would humbly suggest using a logger. Your code is completely bereft of any logging calls that would have aided in a scenario where you do not have a lot of control over the runtime environment.
You could start with using the logging framework within Java - java.util.logging, but you'll find log4j or slf4j to be more intuitive.

Categories

Resources