Create simple HTTP proxy server which replies fake contents, Java - java

I am trying to create a simple proxy server(very simple, doesn't even cache everything) that swaps contents(words, Images, and href) from the reply of origin and forward back to the client. (A proxy server that sends "Fake News" to the client).
I can change every occurrence of "Cat" into "Dog" and every occurrence of "Moon" to "Sun", but I don't know how to swaps the images and hrefs.
Thank you!
public class GetHttp {
public static String extractHost(String request) {
String[] tokens = request.split("\n");
String url = tokens[1].split(" ")[1];
return url;
}
public static byte[] replaceContext(byte[] message) {
String toReturn = new String(message);
// Here is the problem: I don't know how to swap href and images.
//toReturn = toReturn.replaceAll("<img src=\"This is a place holder\"","<img src=\"This is a place holder\" width");
//toReturn = toReturn.replaceAll("<a href=\"This is a place Holder\">", "<a href=\"This is a place Holder\">");
toReturn = toReturn.replaceAll("Cat", "Dog");
toReturn = toReturn.replaceAll("Moon", "Sun");
System.out.println(toReturn);
);
return toReturn.getBytes();
}
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(8888);
while (true) {
Socket connectionSocket = server.accept();
BufferedInputStream inFromClient = new BufferedInputStream(connectionSocket.getInputStream());
// Server reads the HTTP request
byte[] buffer = new byte[8192];
inFromClient.read(buffer);
String clientRequest = new String(buffer);
String originName = extractHost(clientRequest);
// Create the http request from server to the origin
Socket origin = new Socket(InetAddress.getByName(originName.trim()), 80);
BufferedOutputStream outToOrigin = new BufferedOutputStream(origin.getOutputStream());
outToOrigin.write(clientRequest.getBytes());
outToOrigin.flush();
// receive the content from origin
// return back to the client
BufferedInputStream inFromOrigin = new BufferedInputStream(origin.getInputStream());
buffer = new byte[8192];
int buffersize = 0;
BufferedOutputStream outToClient = new BufferedOutputStream(connectionSocket.getOutputStream());
while ((buffersize=inFromOrigin.read(buffer)) != -1) {
byte[] temp = new byte[buffersize];
for(int i=0;i<buffersize;i++){
temp[i] = buffer[i];
}
// swap the context
outToClient.write(replaceContext(temp));// ,0,buffsize);
}
outToClient.flush();
outToOrigin.close();
inFromOrigin.close();
inFromClient.close();
outToClient.close();
origin.close();
connectionSocket.close();
}
}
}

Related

How to receive multiple POST requests from same client on the server

I am trying to write a java server and client such that the client sends the server a POST request with some xml string read from a file as payload, the server fetches the request from the client and sends it an acknowledgment, and this process repeats till all the xml strings that the client has have been sent (as separate POST requests).
I have made the code for 1 single exchange of request and response between the client and server. But I am unable to extend it for multiple requests from the same client because the client waits for server's response and the server's response is not sent to the client till I write wr.close() or socket.close() after writing bytes in the DataOutputStream object. But as soon as I write either of the two commands, my connection between the server and client closes and the client needs to establish connection all over again in order to send the second request.
This is my server side function that receives the request and sends the response:
public HTTPServer(int port) {
try {
private ServerSocket server = new ServerSocket(port);
private Socket socket = server.accept();
int ind = 0;
while (ind<19) {
//socket is an instance of Socket
InputStream is = socket.getInputStream();
InputStreamReader isReader = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isReader);
//code to read and print headers
String headerLine = null;
while ((headerLine = br.readLine()).length() != 0) {
System.out.println(headerLine);
}
ind++;
//send response to the client
Date today = new Date();
String httpResponse = "HTTP/1.1 200 OK\r\n\r\n" + today;
DataOutputStream wr = new DataOutputStream(socket.getOutputStream());
wr.writeBytes(httpResponse);
wr.flush();
}
socket.close(); // or wr.close()
} catch (IOException i) {
System.out.println(i);
}
}
This is my client side code:
public void postMessage() throws IOException {
// string to read message from input
File folder = new File("path/to/my/files");
String[] listOfFiles = folder.list();
for (int i = 0; i < listOfFiles.length; i++) {
File file = new File(listOfFiles[i]);
Scanner sc = null;
try {
sc = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
final URL url = new URL("http://localhost:8080");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
conn.setDoOutput(true);
conn.setConnectTimeout(5000);
// Send post request
conn.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
String line = "";
while (sc.hasNextLine()) {
line += sc.nextLine();
line += '\n';
}
wr.writeBytes(line);
wr.flush();
wr.close();
// read response
BufferedReader in;
if (200 <= conn.getResponseCode() && conn.getResponseCode() <= 299) {
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
in = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
String str;
while ((str = in.readLine()) != null) {
System.out.println(str);
}
}
}
Unless I write socket.close() or wr.close() after wr.flush(), my response is not sent to the client and the client keeps waiting for it, but as soon as I do, the server socket is closed and the code terminates. How can I send response to my client without having to close the socket?
EDIT:
This is updated HTTP Client code, which uses sockets to send HTTP request, but the error persists.
public static void main(String[] args) throws Exception {
InetAddress addr = InetAddress.getByName("localhost");
Socket socket = new Socket(addr, 8080);
boolean autoflush = true;
// string to read message from input
File folder = new File("/Users/prachisingh/IdeaProjects/requests_responses");
String[] listOfFiles = folder.list();
for (int i = 0; i < listOfFiles.length; i++) {
System.out.println("File " + listOfFiles[i]);
File file = new File("/Users/prachisingh/IdeaProjects/requests_responses/" + listOfFiles[i]);
Scanner sc = null;
try {
sc = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String line = "";
while (sc.hasNextLine()) {
line += sc.nextLine();
line += '\n';
}
PrintWriter out = new PrintWriter(socket.getOutputStream(), autoflush);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// send an HTTP request to the web server
out.println("POST / HTTP/1.1");
out.println("Host: http://localhost:8080");
out.println(line);
out.println();
// read the response
boolean loop = true;
StringBuilder sb = new StringBuilder(8096);
while (loop) {
if (in.ready()) {
int r = 0;
while (r != -1) {
r = in.read();
sb.append((char) r);
}
loop = false;
}
}
System.out.println(sb.toString());
}
socket.close();
}

File transfer (.png , .txt) between Server and Client using UDP

I wrote a server and client for client to connect to the server and select a data from the server's directory to transfer the data with UDP protocol but the problem is, it is only working for .txt files it isn't working for .png files and also in the .txt files the output files are not the same with the original one forexample lines between words are not there and all the words printed side by side instead of line by line. How can i fix this problem ?
Server side:
import java.io.*;
import java.net.*;
public class FTPServer {
public static void main(String[] args)
{
DatagramSocket socket = null;
DatagramPacket inPacket = null;
DatagramPacket outPacket = null;
byte[] inBuf, outBuf;
String msg;
final int PORT = 50000;
try
{
socket = new DatagramSocket(PORT);
while(true)
{
System.out.println("\nRunning...\n");
inBuf = new byte[1000];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
int source_port=inPacket.getPort();
InetAddress source_address = inPacket.getAddress();
msg = new String(inPacket.getData(), 0, inPacket.getLength());
System.out.println("CLient: " + source_address + ":" + source_port);
String dirname = "/home/erke/Desktop/data";
File f1 = new File(dirname);
File fl[] = f1.listFiles();
StringBuilder sb = new StringBuilder("\n");
int c=0;
for(int i = 0;i<fl.length;i++)
{
if(fl[i].canRead())
c++;
}
sb.append(c+ " files found.\n\n");
for(int i=0; i<fl.length;i++)
sb.append(fl[i].getName()+ " " + fl[i].length()+ " Bytes\n");
sb.append("\nEnter file name to Download: ");
outBuf = (sb.toString()).getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length, source_address, source_port);
socket.send(outPacket);
inBuf = new byte[1000];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
String filename = new String(inPacket.getData(), 0, inPacket.getLength());
System.out.println("Requested File: " + filename);
boolean flis = false;
int index =-1;
sb = new StringBuilder("");
for(int i=0;i<fl.length;i++)
{
if(((fl[i].getName()).toString()).equalsIgnoreCase(filename))
{
index = i;
flis = true;
}
}
if(!flis)
{
System.out.println("ERROR");
sb.append("ERROR");
outBuf = (sb.toString()).getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length, source_address, source_port);
socket.send(outPacket);
}
else
{
try
{
//File send
File ff=new File(fl[index].getAbsolutePath());
FileReader fr = new FileReader(ff);
BufferedReader brf = new BufferedReader(fr);
String s = null;
sb=new StringBuilder();
while((s=brf.readLine())!=null)
{
sb.append(s);
}
if(brf.readLine()==null)
System.out.println("File Read Succesfull, CLosing Socket");
outBuf=new byte[100000];
outBuf = (sb.toString()).getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length,source_address, source_port);
socket.send(outPacket);
} catch (Exception ioe) {
System.out.println(ioe);
}
}
}
} catch (Exception e){
System.out.println("Error\n");
}
}
}
Client side:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class FTPClient {
public static void main(String[] args) {
DatagramSocket socket = null;
DatagramPacket inPacket = null;
DatagramPacket outPacket = null;
byte[] inBuf, outBuf;
final int PORT = 50000;
String msg = null;
Scanner src = new Scanner(System.in);
try
{
InetAddress address = InetAddress.getByName("127.0.0.1");
socket = new DatagramSocket();
msg = "";
outBuf =msg.getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length,address,PORT);
socket.send(outPacket);
inBuf = new byte[65535];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
String data = new String(inPacket.getData(), 0, inPacket.getLength());
//Print file list
System.out.println(data);
//Send file name
String filename = src.nextLine();
outBuf = filename.getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length, address, PORT);
socket.send(outPacket);
//Receive file
inBuf = new byte[100000];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
data = new String(inPacket.getData(), 0, inPacket.getLength());
if(data.endsWith("ERROR"))
{
System.out.println("File doesn't exists.\n");
socket.close();
}
else
{
try
{
BufferedWriter pw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename)));
pw.write(data);
//Force write buffer to Fİle
pw.close();
System.out.println("File Write Succesful. Closing Socket");
socket.close();
} catch (Exception ioe) {
System.out.println("File Error\n");
socket.close();
}
}
} catch (Exception e) {
System.out.println("\nNetwork Error. Try Again Later. \n");
}
}
}
In your code you are using String to store file data in both client and the server. In order to be able to transfer any file other then a text file, in your server you should have a byte[] buffer instead of String, and use it for loading file contents. You can do this by using classes with names ending with InputStream. After you do that send those bytes over a network. Same goes for the client.
InputStream and OutputStream are used to read\write bytes from files directly, while Reader and Writer classes are specifically intended to work with text files. You cannot read\write bytes with these classes, they work only with characters and strings. You will still be able to transfer text files too though since they are also just an array of bytes.
Also you should be using TCP if you want to transfer your files without losing packets, which UDP tends to do as it doesn't have mechanisms to ensure that packets are safely delivered to a destination like TCP does.

Connect to MD110 pbx using c# Socket Programming

I am trying to login Ericsson MD110 alex through the c# application. The md110 returned values that asking the username for login the application, but once I pass the username and password through the following code:
public static void Main(string[] args)
{
try
{
byte[] data = new byte[1024];
string stringData;
//TcpClient tcpclnt = new TcpClient();
//Console.WriteLine("Connecting.....");
string ipaddress = "192.168.1.30";
int port=23;
IPAddress ipadd = IPAddress.Parse(ipaddress);
IPEndPoint ipend = new IPEndPoint(ipadd, port);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.NoDelay = false;
sock.Connect(ipend);
//recive data
int recv = sock.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, recv);
//textBox4.AppendText(stringData + "\r\n");
Console.Write(stringData);
//while (true)
//{
Byte[] bBuf;
string buf;
//Application.DoEvents();
//buf = String.Format("{0}\r\n{1}\r\n", "MDUSER", "HELP");
buf = String.Format("ALREI;");
//buf = string.Format("ENTER USER NAME<.MDUSER;MDUSER;ENTER PASSWORD<.HELP;");
bBuf = Encoding.ASCII.GetBytes(buf);
sock.Send(bBuf);
data = new byte[1024];
recv = sock.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, recv);
//textBox4.AppendText(stringData + "\r\n");
string df = "";
Console.Write(stringData);
Console.ReadLine();
//}
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
Console.ReadKey();
}
}
Further, I checked with wireshark, but md110 doesn't return any value.
only acknowledge data packet will receive.
I need some advice.

not able to send byte array from server to client,able to send from client to server

I have a task to do this.
Create a client and server socket interaction which accepts byte data and converts the byte data data received at server in the String and send back the response with the confirmation of the data conversation with success/unsuccess as the data passed will be with fix data length format so the validation should be done at server end.
As for e.g.
there are fields which ur sending to server like,
field 1 - number
field 2 - String
field 3 as Floating number i.e. 108.50
After conversion from byte to String :
152|any msg|108.50
In Byte it will be something like this,
10101|1001010010000000011000000000|1110111011
I have tried the following programs to do this
Server.java
public class Server extends Thread
{
private ServerSocket serverSocket;
public Server(int port) throws IOException
{
serverSocket = new ServerSocket(port);
//serverSocket.setSoTimeout(100000);
}
public void run()
{
while(true)
{
try
{
Socket server = serverSocket.accept();
byte Message[]=null;
DataInputStream in =
new DataInputStream(server.getInputStream());
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = in.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
System.out.println("On this line"); //This doesnt get printed
buffer.flush();
data= buffer.toByteArray();
System.out.println(data);
String convertmsg = new String(data);
System.out.println("Msg converted "+convertmsg);
DataOutputStream out =
new DataOutputStream(server.getOutputStream());
System.out.println("below dataoutputstream");
out.write("Success".getBytes());
server.close();
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
public static void main(String [] args)
{
int port = 4003;
try
{
Thread t = new Server(port);
t.start();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
client
public class Client {
public static void main(String args[]) throws IOException
{
int userinput =1;
while(userinput==1)
{
String serverName = "192.168.0.8";
int port = 4003;
try
{
System.out.println("Connecting to " + serverName
+ " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out =
new DataOutputStream(outToServer);
System.out.println("above out.wirte()");
out.write("any msg".getBytes());
InputStream inFromServer = client.getInputStream();
DataInputStream in =
new DataInputStream(inFromServer);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
System.out.println("converting array "+in);
byte[] data = IOUtils.toByteArray(in);
System.out.println(data);//This line doesnt get printed
//System.out.println("Server says " + in.readUTF());
client.close();
}catch(IOException e)
{
e.printStackTrace();
}
System.out.println("Enter userinput ");
DataInputStream dis = new DataInputStream(System.in);
String s = dis.readLine();
userinput = Integer.parseInt(s);
}
}
}
If i send data from client to server in bytes,it reads it and prints it.Also then the line "Enter userinput " gets printed and if the user enters '1' the program continues.
But the problem is this program given above. If i try to send data from server stating "success"(meaning the data has been converted from bytes to String successfully) then the program stucks and the cursor doesnt go below the line which are in comments "This line doesnt get printed".There is no error printed and none of the program terminates.I am new to socket programming and dont understand much about networking.
Any help will be truly appreciated.
You're reading the input until end of stream, but the peer isn't closing the connection, so end of stream never arrives.
I suggest you read and write lines, or use writeUTF() and readUTF().

Socket in Android remains stuck

I have a server written in C# and a client side in Android. If I send a message from client (Android) to server (c#) and from server to client, everything works fine. If I try to send one message from client , one from server, another from client, the client remains stuck at reading the message from the server. What could be the problem?
My client code is:
sendBytes("HELLOX".getBytes());
readBytes(byDataReceived);//here it gets stucked
...
try
{
int nrsend=sendBytes("HELLOX".getBytes());
readBytes(byDataReceived);
}
catch (Exception se)
{
Log.d("IdealLog","Exception: "+se.getMessage()+" ");
Toast.makeText(context, se.getMessage()+" " , 10000).show();
// MessageBox.Show(se.Message);
return false;
}
...
public static int readBytes(byte[] myByteArray) throws IOException
{
Log.d("IdealLog","readBytes-begin");
InputStream in = socket.getInputStream();
BufferedReader buffreader = new BufferedReader(new InputStreamReader(in));
String finalText = "";
String text = "";
while ((text = buffreader.readLine()) != null)
{
finalText += text;
}
myByteArray=new byte[myByteArray.length];
myByteArray=EncodingUtils.getAsciiBytes(finalText);
Log.d("IdealLog","Input Stream: "+finalText);
Log.d("IdealLog","TEST: "+EncodingUtils.getAsciiString(myByteArray));
Log.d("IdealLog","readBytes-end");
byDataReceived=myByteArray;
buffreader.close();
return myByteArray.length;//myByteArray.length;
}//readBytes end
public static int sendBytes(byte[] myByteArray) throws IOException
{
return sendBytes(myByteArray, 0, myByteArray.length);
}//sendBytes end
public static int sendBytes(byte[] myByteArray, int start, int len) throws IOException
{
if (len < 0)
{
throw new IllegalArgumentException("Negative length not allowed");
}
if (start < 0 || start >= myByteArray.length)
{
throw new IndexOutOfBoundsException("Out of bounds: " + start);
}
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
// dos.writeInt(len);
if (len > 0)
{
dos.write(myByteArray, start, len);
}
int size=dos.size();
dos.flush();
return size;
}//sendBytes end
My server code:
static void Main(string[] args)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, 1408);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(ip);
socket.Listen(10);
Console.WriteLine("Waiting for a client...");
Socket client = socket.Accept();
IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
Console.WriteLine("Connected with {0} at port {1}", clientep.Address, clientep.Port);
string welcome = "HELLO&";
byte[] data = new byte[200];
client.Receive(data);
Console.WriteLine("Received data from CLIENT TEST1: {0}", System.Text.ASCIIEncoding.ASCII.GetString(data));
ASCIIEncoding asen = new ASCIIEncoding();
byte[] data2 = new byte[200];
data2 = asen.GetBytes(welcome);
client.Send(data2, data2.Length, SocketFlags.None);
//if i comment out from this 3 lines, everything is working fine
byte[] data3 = new byte[200];//this
client.Receive(data3);//this
Console.WriteLine("Received data from CLIENT TEST2: {0}", System.Text.ASCIIEncoding.ASCII.GetString(data3));//this
Console.WriteLine("Disconnected from {0}", clientep.Address);
client.Close();
socket.Close();
Console.ReadLine();
}
Modify into this:
//if i comment out from this 3 lines, everything is working fine
byte[] data3 = new byte[200];//this
client.Receive(data3);//this
Console.WriteLine("Received data from CLIENT TEST2: {0}", System.Text.ASCIIEncoding.ASCII.GetString(data3));//this
client.Send(data2, data2.Length, SocketFlags.None);
Console.WriteLine("Disconnected from {0}", clientep.Address);
client.Close();
socket.Close();
Console.ReadLine();
}

Categories