if (args.length!=2) {
System.out.println("Usage: java httpServer <80> <www.mdx.ac.uk>");
System.exit(-1);
}
int port = Integer.parseInt(args[0]);
String wwwmdx = args[1];
// open server socket
ServerSocket socket = null;
try {
socket = new ServerSocket(port);
} catch (IOException e) {
System.err.println("Could not start server: " + e);
System.exit(-1);
}
System.out.println("httpServer accepting connections on port " + port);
// request handler loop
while (true) {
Socket connection = null;
try {
// wait for request
connection = socket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
OutputStream out = new BufferedOutputStream(connection.getOutputStream());
PrintStream pout = new PrintStream(out);
// read first line of request (ignore the rest)
String request = in.readLine();
if (request==null)
continue;
log(connection, request);
while (true) {
String misc = in.readLine();
if (misc==null || misc.length()==0)
break;
}
// parse the line
if (!request.startsWith("GET") || request.length()<14 ||
!(request.endsWith("HTTP/1.0") || request.endsWith("HTTP/1.1"))) {
// bad request
errorReport(pout, connection, "400", "Bad Request",
"Your browser sent a request that " +
"this server could not understand.");
} else {
String req = request.substring(4, request.length()-9).trim();
if (req.indexOf("..")!=-1 ||
req.indexOf("/.ht")!=-1 || req.endsWith("~")) {
// evil hacker trying to read non-wwwhome or secret file
errorReport(pout, connection, "403", "Forbidden",
"You don't have permission to access the requested URL.");
} else {
String path = wwwmdx + "/" + req;
File f = new File(path);
if (f.isDirectory() && !path.endsWith("/")) {
// redirect browser if referring to directory without final '/'
pout.print("HTTP/1.0 301 Moved Permanently\r\n" +
"Location: http://" +
connection.getLocalAddress().getHostAddress() + ":" +
connection.getLocalPort() + "/" + req + "/\r\n\r\n");
log(connection, "301 Moved Permanently");
} else {
if (f.isDirectory()) {
// if directory, implicitly add 'index.html'
path = path + "index.html";
f = new File(path);
}
try {
// send file
InputStream file = new FileInputStream(f);
pout.print("HTTP/1.0 200 OK\r\n" +
"Content-Type: " + guessContentType(path) + "\r\n" +
"Date: " + new Date() + "\r\n" +
"Server: httpServer1 1.0\r\n\r\n");
sendFile(file, out); // send raw file
log(connection, "200 OK");
} catch (FileNotFoundException e) {
// file not found
errorReport(pout, connection, "404", "Not Found",
"The requested URL was not found on this server.");
}
}
}
}
out.flush();
} catch (IOException e) { System.err.println(e); }
try {
if (connection != null) connection.close();
} catch (IOException e) { System.err.println(e); }
}
}
private static void log(Socket connection, String msg)
{
System.err.println(new Date() + " [" + connection.getInetAddress().getHostAddress() +
":" + connection.getPort() + "] " + msg);
}
private static void errorReport(PrintStream pout, Socket connection,
String code, String title, String msg)
{
pout.print("HTTP/1.0 " + code + " " + title + "\r\n" +
"\r\n" +
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n" +
"<TITLE>" + code + " " + title + "</TITLE>\r\n" +
"</HEAD><BODY>\r\n" +
"<H1>" + title + "</H1>\r\n" + msg + "<P>\r\n" +
"<HR><ADDRESS>FileServer 1.0 at " +
connection.getLocalAddress().getHostName() +
" Port " + connection.getLocalPort() + "</ADDRESS>\r\n" +
"</BODY></HTML>\r\n");
log(connection, code + " " + title);
}
private static String guessContentType(String path)
{
if (path.endsWith(".html") || path.endsWith(".htm"))
return "text/html";
else if (path.endsWith(".txt") || path.endsWith(".java"))
return "text/plain";
else if (path.endsWith(".gif"))
return "image/gif";
else if (path.endsWith(".class"))
return "application/octet-stream";
else if (path.endsWith(".jpg") || path.endsWith(".jpeg"))
return "image/jpeg";
else
return "text/plain";
}
private static void sendFile(InputStream file, OutputStream out)
{
try {
byte[] buffer = new byte[1000];
while (file.available()>0)
out.write(buffer, 0, file.read(buffer));
} catch (IOException e) { System.err.println(e); }
}
}
JAVA RMI
- Introduction
- RMI architecture
- Steps of developing RMI
- Designing remote interface & implementing
- Develop the client program
- Develop the server program
Introduction
Remote method invocation allows applications to call object methods located remotely, sharing resources and processing load across systems. Unlike other systems for remote execution which require that only simple data types or defined structures be passed to and from methods, RMI allows any Java object type to be used - even if the client or server has never encountered it before. RMI allows both client and server to dynamically load new object types as required.
Remote Method Invocation (RMI) facilitates object function calls between Java Virtual Machines (JVMs). JVMs can be located on separate computers - yet one JVM can invoke methods belonging to an object stored in another JVM. Methods can even pass objects that a foreign virtual machine has never encountered before, allowing dynamic loading of new classes as required.
General RMI architecture
- The server must first bind its name to the registry
- The client lookup the server name in the registry to establish remote references.
- The Stub serializing the parameters to skeleton, the skeleton invoking the remote method and serializing the result back to the stub.
Stub and Skeleton
- A client invokes a remote method, the call is first forwarded to stub.
- The stub is responsible for sending the remote call over to the server-side skeleton
- The stub opening a socket to the remote server, marshaling the object parameters and forwarding the data stream to the skeleton.
- A skeleton contains a method that receives the remote calls, unmarshals the parameters, and invokes the actual remote object implementation.
Specific RMI architecture
The diagram blow shows the architecture of the JAVA RMI. Which consists three layers:Stub/Skeleton Layer, Remote Reference Layer and Transport Layer.
Stub/Skeleton Layer
Stub steps
It Forwards invocation requests to the server objects. Initiating a call to the remote object. Marshalling arguments to a marshal stream. Informing the remote reference layer that the call should be invoked. Unmarshalling the return value or exception from a marshal stream and finally. And finally Informing the remote reference layer that the call is completed.
Skeleton steps
Server-side entity that contains a method which dispatches calls to the actual remote object implementation. Unmarshalling arguments from the marshal stream. Making the up-call to the actual remote object implementation, and finally. Marshalling the return value of the call or an exception onto the marshal stream.
Remote Reference Layer
Remote Reference Layer carries out the semantics of the invocation. For example the remote reference layer handles such items as: Whether the server is a single object or is a replicated object, whether the server is always running or is only run when called on.
Transport Layer
Its job is setting up connections to remote address spaces. Managing connections. Monitoring connection liveness. Listening for incoming calls.Maintaining a table of remote objects that reside in the address space.
Setting up a connection for an incoming call.
Located the dispatcher for the target of the remote call and passing the connection to this dispatcher.
Steps of developing RMI
- Define the remote interface
- Develop the remote object by implementing the remote interface.
- Develop the client program.
- Compile the Java source files.
- Generate the client stubs and server skeletons.
- Start the RMI registry.
- Start the remote server objects.
- Run the client
Designing remote interface & implementing
Overview
The Remote interface serves to identify interfaces whose methods may be invoked from a non-local virtual machine. Any object that is a remote object must directly or indirectly implement this interface. Only those methods specified in a "remote interface", an interface that extends java.rmi.Remote, are available remotely.
Implementation classes can implement any number of remote interfaces and can extend other remote implementation classes. RMI provides a convenience class, java.rmi.server.UnicastRemoteObject, that remote object implementations can extend to facilitate remote object creation.
When you create a remote interface, you must follow these guidelines:
1. The remote interface must be public.
2. The remote interface must extend the interface java.rmi.Remote
3. Each method in the remote interface must declare java.rmi.RemoteException in its throws clause, in addition to any application-specific exceptions.
4. A remote object passed as an argument or return value (either directly or embedded within a local object) must be declared as the remote interface, not the implementation class.
Designing the Remote Interface
As you can see in the diagram above, Remote Interface is between the client and server objects. Its job is to pass an arguments or returns to/from client or server.
Develop the client program
-
In order for the client object to invoke methods on the server, it must first look up the name of server in the registry. You use the java.rmi.Naming class to lookup the server name.
- The server name is specified as URL in the from ( rmi://host:port/name )
- Default RMI port is 1099.
- The name specified in the URL must exactly match the name that the server has bound to the registry. In this example, the name is “SAMPLE-SERVER”
Develop the client program
To develop the server program, you have to implement the Interface program and its functions. Then you can develop the server application, as follows.
The server accepts tasks from the client, runs the tasks, and returns any results to the client. The server is comprised of an interface and a class. The interface provides the definition for the methods that can be called from the client. Essentially the interface defines the client's view of the remote object. The class provides the implementation.
Code of RMI
INTERFACE
//Before the client can call a remote method, it will need to retrieve a remote interface. The interface in the code below is written for all methods that should be public.
Here is the interface definition for the remote interface, examples.hello.Hello. The interface contains just one method, sayHello, which returns a string to the caller:
import java.rmi.*;
public interface Hello extends Remote
{
String decryptionMessage(String mes) throws RemoteException;
String getMessage(int lNum,char pW) throws RemoteException;
}
RMI CLIENT
import java.rmi.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
public class HelloApp
{
public static void main(String arg[])
{
int lNo;
char pWord;
String res1,res2,number,letter;
number = JOptionPane.showInputDialog("Enter a number :");
//The inputbox allows the user to enter the client can retrieve an specified line by a given number, i.e., any number between 1 and 10.
lNo = Integer.parseInt(number);
letter = JOptionPane.showInputDialog("Enter a letter :");
pWord = letter.charAt(0);
try
{
Hello obj = (Hello)Naming.lookup("rmi://127.0.0.1/HelloServer");
res1 = obj.getMessage(lNo,pWord);
System.out.println("Before Decryption: "+res1);
res2 = obj.decryptionMessage(res1);
System.out.println("After Decryption: "+res2);
}
catch (Throwable e)
{
System.err.println(e.getMessage());
System.exit(1);
}
System.exit(0);
}
}
RMI SERVER
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.util.*;
import java.io.*;
public class HelloImpl extends UnicastRemoteObject implements Hello
{
private String name;
private char passwd;
private int noOfChar;
public HelloImpl(String s) throws RemoteException
{
super();
try
{
name = s;
File outputFile = new File("Greetings.txt");
FileWriter out = new FileWriter(outputFile);
for(int i = 0; i<10; i++)
{
out.write("hello world "+(i+1)+"\n");
}
out.close();
}
catch (Throwable e)
{
System.err.println(e.getMessage());
System.exit(1);
}
}
public String getMessage(int lNum, char pW) throws RemoteException
{
passwd = pW;
String messageToEncryption = "";
try
{
open a file for reading
FileReader fr=new FileReader("Greetings.txt");
wrap the filereader to a bufferedreader
BufferedReader frb=new BufferedReader(fr);
String ast ;
/*read one line*/
for (int i = 0; i < lNum; i++)
{
if(i == (lNum -1))
{
ast = frb.readLine();
messageToEncryption = encryptionMessage(ast);
}
frb.readLine();
}
frb.close();
}
catch(Throwable e)
{
System.err.println(e.getMessage());
}
return messageToEncryption;
}
public String decryptionMessage(String mes) throws RemoteException
{
The client should provide linenum and passwd.After getting the line, it should use the passwd to decrypt the message. Decryption The following example show you how decrypt the messages
char[] bb=mes.toCharArray();
for(int i=0;i<noOfChar; i++)
bb[i]=(char)(bb[i]^passwd);
String kkk=new String(bb);
return kkk;
}
private String encryptionMessage(String mes)
{
Encryption of the messages
char[] aa=mes.toCharArray();
noOfChar = aa.length;
for(int i=0;i<noOfChar;i++)
aa[i]=(char)(aa[i]^passwd);
String ooo=new String(aa);
return ooo;
}
public static void main(String argv[])
{
//System.setSecurityManager(new RMISecurityManager());
The security manager has been set here The main method of the server first needs to create and install a security manager: either the RMISecurityManager or one that you have defined yourself. For example:
try
{
HelloImpl obj = new HelloImpl("HelloServer");
code binds the name "HelloServer" to a reference for the remote object
Naming.rebind("//localhost/HelloServer", obj);
System.out.println("HelloServer bound in registry");
}
catch (Throwable e)
{
System.err.println(e.getMessage());
System.exit(1);
}
}
}
NAME
FAHAD TAHIR
STUDENT NUMBER
2216684
MODULE
2072
ASSIGNMENT
LECTURER
CONTENTS
Pages
1. Overview of Http Protocol………………………………
2. HTTP Package…………………………………………..
3. (WWW) World Wide Web……………………………...
3. Designing Http client……………………………………