Sunteți pe pagina 1din 68

A Project Report On

HTTP CACHING PROXY SERVER


Submitted in partial fulfillment of the requirements
for the degree of

Bachelor of Technology
In
Computer Science and Technology

Under the guidance of: Submitted By:

Mr. D.L. Gupta 1. Ranvijai Singh


0710410042
2. Vijay Krisha Yadav
0710410057

Department Of Computer Science and Engineering


Kamla Nehru Institute of Technology
Sultanpur-228118 (India)
Gautam Buddha Technical University, Lucknow

1|Page
Certificate
This is to certify that the project report entitled
“HTTP CACHING PROXY SERVER” submitted in partial fulfillment of the
requirements for the degree of Bachelor of the Technology in Computer
Science and Engineering done by Mr. Ranvijai Singh, Roll No. 0710410042
and Mr. Vijay Krishan Yadav, Roll No. 0710410057 is an authentic work
carried out by him at Department of Computer Science and Engineering under
my guidance. The matter embodied in this project has not been submitted earlier
for the award of any degree or diploma to the best of my knowledge and belief.

Date: Signature of the Guide


Mr. D.L. Gupta
Astt. Professor
Comp. Sc. & Engg. Department
Kamla Nehru Institute of Tech.

Mr. D.L. Gupta Dr. A.K. Malviya

Project Guide Project Incharge

Mr. Sameer Srivastava

Head of Department Of Computer


Science and Engineering
Kamla Nehru Institute of Technology
Sultanpur-228118 (India)

2|Page
ACKNOWLEDGEMENT

My foremost and profound gratitude goes to Mr. D.L. Gupta for his
proficient and enthusiastic guidance and encouragement. The suggestions given
undoubtedly helped in supplementing my thoughts in the right direction for
attaining the desired objective.
My heartfelt gratitude also goes to all the faculty members and Staff of
Kamla Nehru Institute of Technology, Gautam Buddha Technical University
who have contributed directly or indirectly towards the successful completion of
this report.

Ranvijai Singh(0710410042)
Vijay Krishan Yadav(0710410057)

3|Page
Content and order of the Project report:

1) Introduction……………………………………………………6
3.1 Objective
3.2 Scope
3.3 Motivation
3.4 Problem Definition
3.5 Technologies Used
3.6 Organization of the Report
2) Background……………………………………………………
3) Project Description
3.1 SRS…………………………………………………….
1. Product Perspective
2. User Interfaces
3. Hardware Requirements of User
4. Software Requirements of User
5. Operations
6. Product Functions
7. User Characteristics
8. Constrains
3.2 Software System Attributes
1. Security
2. Quality
3. Measurement
3.3 Features
3.4 Disadvantage of the Current System
3.5 Advantage of the Proposed System
4) Project Design and Implementation…………………………..
4.1) Feasibility Study
4.2) Data Flow Diagram
4.3) Use Case Diagram
4.4) Development Schedule(Gantt Chart)
4.5) EER Diagram
4.6) Implementation
4.7) Code
4.8) Testing
4.9)Experimental Setup

4|Page
5) Project Output
6) Conclusion and Future Scope
a) Conclusion
b) Future Scope
Appendix
a) Coding
b) Gontt Chart
c) EER Diagram
d) Test Cases

Bibliography

5|Page
INTRODUCTION

1.1 OBJECTIVE:

◦ An HTTP proxy server is a server that handles HTTP requests from clients. If the

clients are of a common organization or domain, or exhibit a similarity in

browsing behavior, the proxy can effectively cache requested documents.

◦ Caching, which migrates documents across the network closer to the users, reduces

network traffic, reduces the load on popular Web servers and reduces the time that

end users wait for documents to load.

1.2 SCOPE:
• Caching proxies keep local copies of frequently requested resources, allowing large

organizations to significantly reduce their upstream bandwidth usage and cost, while

significantly increasing performance.

• A caching proxy server accelerates service requests by retrieving content saved from

a previous request made by the same client or even other clients.

6|Page
1.3 MOTIVATION:

◦ A proxy server accepts requests from clients. When possible and desired, it

generates replies based upon documents stored in its local cache; otherwise, it

forewords the requests, transfers the replies to the clients and caches them when

possible.

◦ The proxy thus acts both as a server and as a client. It is a server when accepting

HTTP requests from its clients, but a client to the remote servers it connects to

when it is unable to fulfill requests by the means of its local cache.

1.4 PROBLEM DEFINITION:

 Administrator can monitor activities of various users like which kind of web

pages are visited by any particular users.

 This project is a step ahead process to solve the various problems we face in

day to day life while surfing through college network.

 It provides web pages from it’s cache instead of the original web page which

saves a lot of money and time.

1.5 TECHNOLOGIES USED:

• Netbeans IDE 6.5 for java programming.


• JDK 1.6 .
• Socket programming.

7|Page
1.6 ORGANIZATION OF THE REPORT:
This report is organized in the six chapters and few appendix:

INTRODUCTION gives a brief introduction about the project. It consist of Objective, Scope,
Motivation, Problem Definition and Technology Used as the sub headings which completely
summarizes about the whole project.

BACKGROUND gives a few details about the various technologies used in this project and
also explains in brief about the functioning of the various technologies.

PROJECT DESCRIPTION includes the software requirement specification (SRS) document


of the project and describes about the various features of the project. It also includes the
disadvantages of the previous system and advantages of the proposed system.

PROJECT DESIGN & IMPLEMENTATION describes about the various designing phases
that the project undergoes such as Gantt chart and data flow diagram. Also includes the
documentation of them and the testing of the various modules incorporated within the project.

PROJECT OUTPUT includes the snapshots of the various screens that the project shows
while running in the real time.

FUTURE SCOPE & CONCLUSION gives the direction about the enhancement of the project
in various dimensions and also concludes the project report.

APPENDIX: It has three parts. Part A consists of , the code of few modules that is in the
project. Part B consists of the development schedule of the whole project described by the
Gantt Chart. And Part C includes the Entity Relationship Diagram (ERD) that is used for the
project. And the last part D includes the Test Case of the project

8|Page
2. BACKGROUND:

The most obvious compromise is to provide a single host with Internet access for all your
users. However, this isn't a satisfactory solution because these hosts aren't transparent to users.
Users who want to access network services can't do so directly. They have to log in to the
dual-homed host, do all their work from there, and then somehow transfer the results of their
work back to their own workstations. At best, this multiple-step process annoys users by
forcing them to do multiple transfers and work without the customizations they're accustomed
to.
The problem is worse at sites with multiple operating systems; if your native system is a
Macintosh, and the dual-homed host is a UNIX system, the UNIX system will probably be
completely foreign to you. You'll be limited to using whatever tools are available on the dual-
homed host, and these tools may be completely unlike (and may seem inferior to) the tools
you use on your own system.
Dual-homed hosts configured without proxies therefore tend to annoy their users and
significantly reduce the benefit people get from the Internet connection. Worse, they usually
don't provide adequate security; it's almost impossible to adequately secure a machine with
many users, particularly when those users are explicitly trying to get to the external universe.
You can't effectively limit the available tools, because your users can always transfer tools
from internal machines that are the same type. For example, on a dual-homed host you can't
guarantee that all file transfers will be logged because people can use their own file transfer
agents that don't do logging.
Proxy systems avoid user frustration and the insecurities of a dual-homed host. They deal
with user frustration by automating the interaction with the dual-homed host. Instead of
requiring users to deal directly with the dual-homed host, proxy systems allow all interaction
to take place behind the scenes. The user has the illusion he is dealing directly (or almost
directly) with the server on the Internet that he really wants to access, with a minimum of
direct interaction with the dual-homed host.

9|Page
3. PROJECT DESCRIPTION:
3.1. SRS:
1. Product Perspective:
Product is designed to solve the problems regarding use of internet services and speed related

with bandwidth and to enhance surfing facility and minimize load from server .

2. USER INTERFACES:
User interface of the product is interactive and easily understandable by the user.

3. HARDWARE REQUIREMENT FOR USER:


* Intel 486 or higher. RISC support shoul be available.

* 24 MB Ram for Intel chips and 32 MB Ram for RISC.

* 10 MB for installation.100 MB + .5 MB per client for Cache space.

* 2 Network interfaces (Adapters, Dial-Up, etc)

4. SOFTWARE REQUIREMENT FOR USER:


* Windows NT server 4.0

* Internet Information Server 2.0

* Service Pack 3

* TCP/IP

5. OPERATIONS:
• A cache/proxy server network conserves bandwidth, decreases network-

imposed latency, and offsets the load on the origin server from which the

content is published. Network bandwidth is minimized because only one

10 | P a g e
connection from the origin server is required to upload content to and

receive information from remote cache/proxy servers on the network.

• Latency is decreased because a client can receive content from a nearby

cache/proxy server more quickly than it could if it had to traverse the

network or the Internet to receive content from the origin server.

• Additionally, the load on the origin server is offset because fewer clients

are connecting directly to it. These three factors result in a better viewing

experience for users and operating cost reduction.

6. PRODUCT FUNCTIONS:
▪ Caching

▪ Reduces Latency

▪ Reduces traffic on the web

▪ Bandwidth Conservation

▪ Increases accessibility

▪ Firewalling and filtering

▪ Connection sharing

7. USER CHARACTERISTICS:
8. CONSTRAINS:
• The existing physical network, hardware, and operating systems place

certain technical requirements and constraints on your design.

• As you create your Proxy Server design, ensure that your design meets the

technical requirements and stays within the technical constraints.

11 | P a g e
3.2. SOFTWARE SYSTEM ATTRIBUTES:
1. Security:

◦ By caching pages that have been previously requested, the proxy server

speeds up performance by responding to future requests for the same

page using the cached information rather than going to the web site

again.

◦ When using a proxy server external systems only see the IP address of

the proxy server so the true identity of internal computers is hidden.

The proxy server can also be configured with basic rules of what ports

or IP addresses are or are not allowed to pass through which makes it a

type of basic firewall.

2. Quality:
◦ A horizontal and vertical involvement of all concerned in project

management processes and procedures becomes very important. These

concerned persons may also be termed as stakeholders and may vary

with their existence at various levels inside and outside the

organization. All stakeholders must be well aware of the existence of

standard procedures and processes related to any project.

◦ Well defined processes and procedures documented and distributed to

all must be harnessed for strategic long term benefits. This is important

to achieve and is possible only by way of adherence to what is

documented. A continuous adoption of such well defined processes and

procedures will definitely help in understanding, optimization and


12 | P a g e
finding out gap between benchmarks and currently adopted processes

and procedures.

◦ Once these processes and procedures are deployed by way of providing

documents by way of hard copies of publishing on a whiteboard on

internet, it helps all to clear doubts if any in mind of any of the persons

on distribution list. Welcome any suggestion, feedback, queries or

comment from all readers of these documents.

3. Measurement:
◦ Hits

◦ Page View/Impression

◦ Visit / Total user sessions

3.3. FEATURES:
* It may rewrites the client's request.

* It provides anonymity and security.

* It is a Caching Proxy Server.

* It serves as a content filter.

* Multithreadi

13 | P a g e
3.4. DISADVANTAGE OF CURRENT SYSTEM:

• Proxy services lag behind nonproxied services.

• Proxy services may require different servers for each service

• Proxy services usually require modifications to clients, procedures, or both

• Proxy services aren't workable for some services

• Proxy services don't protect you from all protocol weaknesses

3.5. ADVANTAGES OF PROPOSED SYSTEM:


* Better Performance

* Less trafficking

* Reduces latency

* Conserves Bandwidth

* Good at Logging

4. PROJECT DESIGN AND IMPEMENTATION:


4.1. FEASIBILITY STUDY:
Several interrelated technical, managerial, and financial factors need to be considered

when evaluating the feasibility of accessing online journals (whether from Africa or anywhere

else). Feasibility is of course a fluid concept, as most of the important factors are adaptable,

given the will, the knowledge, and the resources. Some of the issues are relatively simple

university policy matters, others more intransigent technical or financial matters. The key

factors include:

◦ The university’s Internet and local area network (LAN) setup: What type of server

is used? Is a university-wide proxy server in place? Does it perform caching? How

14 | P a g e
much space is available for caching? How is the LAN set up (single ring? multiple

nodes?)

◦ The size of the user community relative to the available bandwidth: Is the user

community limited, for example to exclude undergraduates? Should the university

resell its bandwidth to third party users?

◦ There are several possible reasons the connection worked so poorly at University.

One is that the LAN is a single physical ethernet segment connecting some one

thousand computers, with all those computers competing for LAN resources,

including bandwidth for Internet connectivity. In short, that's a lot of traffic. By

contrast, the LAN at UG is organized into smaller ethernet segments connected to

each other by an ethernet switch. This setup manages the traffic more efficiently,

as computers compete only with other computers in the same segment, and inter-

segment traffic is minimized. Thus utilization of the ethernet is made more

efficient, making it possible to add more terminals to the network with less

degradation of service. Another possible reason is that the problems were a result

of the way that Windows handles Internet data transfers. Downloading is a two-

way process involving data coming in and receipt confirmations going out. When

there is a delay in the incoming data, Windows slows down its response rate, but if

the incoming rate increases, Windows does not speed back up to match it. This

creates a tendency toward ever-decreasing speed that eventually kills the

connection once it reaches a delay of a certain length.

15 | P a g e
4.2. DATA FLOW DIAGRAM:

Request for internet


Resource data

Send No Yes Yes


Request to Can request
Be filled from
Is TTL still
internet
Cache info valid

No

Generate
Data retrieved No error Yes Request
Has update
successfully

No

Yes No Update TTL


Can error in cache
be cached

Yes
Does object
meet Mark in
Cacheable Yes cache
guidelines?

NO

Send data to client

16 | P a g e
4.3. USE CASE DIAGRAM:

4.4. Development Schedule (Gantt Chart):


A Gantt chart is a type of bar chart that illustrates a project schedule. Gantt charts illustrate

the start and finish dates of the terminal elements and summary elements of a project.

Terminal elements and summary elements comprise the work breakdown structure of the

project. Some Gantt charts also show the dependency (i.e., precedence network) relationships

between activities.

17 | P a g e
4.5. EER Diagram:
In computer science, the enhanced entity-relationship (EER) model is a high-level or

conceptual data model incorporating extensions to the original entity-relationship (ER) model,

used in the design of databases. It was developed by a need to reflect more precisely

properties and constraints that are found in more complex databases, such as in engineering

design and manufacturing (CAD/CAM), telecommunications, complex software systems and

geographic information systems (GIS).

4.6. Implementation:
It is very important part of software development as we complete our
software than we go for the installation of the software to the user end. Where we
keep in mind the h/w & s/w requirement and plus we also train the employee who do
not have knowledge of computers. Though we have made the software user friendly
but than also we prepare user manual to operate the software easily & safely. We
also bring out the changes in h/w if it would not support the software and same would
be the case with the s/w and operating system.
Implementation is the most important part of software development. In
this phase after the completion of the software we go for its installation on the
system. In this phase we keep in mind that it takes the minimum amount of software
and hardware requirements in order to perform its various tasks correctly and
accurately. The software should be such that even a naïve user can easily operate all
its functions properly.
In the implementation phase we make sure that the software is performing
all its desired tasks properly using the minimum possible software and hardware
requirements. In the implementation phase we make sure that the software is user
friendly so that any new user can easily operate on it.
I hope this software will fully satisfy the needs and requirements of Caching
Proxy Server.

18 | P a g e
4.7. CODE:
Coding is undertaken once the design phase is complete and the design documents have been

successfully reviewed. In the coding phase, every module identified and specified in the

design document is independently code and unit tested. Project coding is given under

Appendix A.

4.8. TESTING:
Objective of Testing:
◦ Testing is a process of the executing a program with the intent of the

finding an error.

◦ A good test case is one that has a high probability of the finding an as-yet

undiscovered error.

◦ A successful test is one that is one uncovers as-yet undiscovered error. If

the testing is conducted successfully it will uncover errors in the software.

Testing can not show the absence of the defects, it can only show that

software errors are present.

Testing principles:

2. All tests should be traceable to customer requirements.


3. Tests should be planned long before testing begins.

4. Testing should begin “in the small” and progress toward testing “in the large”.

5. Exhaustive testing is not possible.

19 | P a g e
Type of Testing:

1. White-box Testing:

This testing is also known as “glass-box testing”. Using white-box testing, test

cases are derived that

• Guarantee that all independent path with in a module have been exercised at

last once;

• Exercise all logical decisions on their boundaries and with in their operational

bounds; and

• Exercise internal data structures to assure their validity.

Reasons for preferring White-box Testing:


• Logic errors and incorrect assumptions are inversely proportional to the

probability that a program path will be executed.

• We often believe that a logical path is not likely to be executed when

infect it may be executed on a regularly basis.

• Topographical errors are random.

2. Black Box Testing:

This testing focuses on the functional requirements of the software i.e. it

enables to derive set of the input conditions that will folly exercise all functional

requirements for a program. It is not an alternative to white-box techniques

rather it is a complementary approach i.e. likely to uncover a different class of

than white-box Testing methods.

20 | P a g e
Black-box attempts to find errors the following categories:

• Incorrect or missing function,

• Interface errors,

• Error in data structure or external database access

• Performance errors

4.9. EXPERIMENTAL SETUP:


Your experimental setup will consist of running your client and the proxy server on one

machine, while the origin server on another machine (most likely in the same lab). You

might have some issues with making your proxy server talk to the remote server through

RMI because of firewall issues. Java RMI does not use port 80 for communication: by

default rmiregistry runs on port 1099 and then assigns some random ports to RMI

sockets). A representative of the Techstaff in the CS Department has assured me that all

the Linux machines in undergraduate labs are not firewalled for intra-domain access.

Windows machines are more heavily firewalled, but this still should not be a problem for
intra-domain access. You’ll have to find a setup that’ll make it possible for you to run all

your experiments. Since this is a Java-based project, you should have no problem running

your programs on any operating system.

6. CONCLUSION AND FUTURE SCOPE:


a) CONCLUSION:
The caching proxy server proved to be the single biggest saver of available bandwidth

for the hobbits. It reduced the effective browsing time for the common sites to a minimum and

surfing was no longer the drag it used to be.

21 | P a g e
b) FUTURE SCOPE:
The caching proxy server as stand-alone product is an endangered species.In its place, we'll

continue to see software firewalls expand their breadth to include the kind of content filtering,

caching, and authentication that was traditionally the role of the proxy server.
However, the testing process downloads webpages which consume network bandwidth, so
it

is suggested that in the future, it can re-use the statistical information from some existing

measurement system like perfSONAR, so that it need not download webpages frequently..

5. APPENDIX:
a) Coding:
Module 1: Server.java
import java.net.*;

import java.io.*;

import java.util.*;

import java.awt.*;

import proxy.Proxy;

import proxy.HttpReplyHdr;

import proxy.HttpRequestHdr;

import proxy.Configuration;

import proxy.ServerDataBase;

import proxy.Cache;

22 | P a g e
import proxy.ServersAccessibleWOProxy;

import proxy.DocumentInfo;

import proxy.ServerInfo;

import proxy.MainFrame;

/*

* Server

*/

public class Server extends Thread

final static int defaultServerPort = 8080;

final static int maxServerPort = 65536;

private static Configuration config ;

private static ServerDataBase serverDataBase ;

private static Cache cache ;

private static ServersAccessibleWOProxy serversAccessibleWOProxy;

public static void main(String args[])

int serverPort;
23 | P a g e
switch (args.length) {

case 0: serverPort = defaultServerPort;

break;

case 1: try {

serverPort = Integer.parseInt(args[0]);

} catch (NumberFormatException e) {

System.out.println("Error: Invalid server port");

return;

if (serverPort > maxServerPort) {

System.out.println("Error: Invalid server port");

return;

break;

default:System.out.println("Usage: Server [port]");

return;

ServerSocket serverSocket = null;

int initialNoOfThreads = 0;

// Initialize main data structures.

config = new Configuration();

24 | P a g e
MainFrame mainFrame = new MainFrame("HTTP Proxy Server",config);

mainFrame.updateLog("HTTP Proxy Server 1.0");

mainFrame.updateLog("Initializing servers database...");

serverDataBase = new ServerDataBase(config);

mainFrame.updateLog("Initializing cache...");

cache = new Cache(config, serverDataBase, mainFrame);

mainFrame.updateLog("Initializing list of servers whose documents should not be

cached...");

serversAccessibleWOProxy = new ServersAccessibleWOProxy(config);

mainFrame.setServersAccessibleWOProxy(serversAccessibleWOProxy);

mainFrame.setCache(cache);

// accept incoming requests and initiate threads to handle them.

try {

mainFrame.updateLog("Initializing listening port ("+serverPort+")...");

serverSocket = new ServerSocket(serverPort);

mainFrame.serverSocket = serverSocket;

mainFrame.updateLog("Initializations complete, server up and running.\n");

initialNoOfThreads = activeCount();System.out.println(initialNoOfThreads);

25 | P a g e
for (int i=1;i<4;i++) {

mainFrame.updateLog("welcome\n");

Socket sck = serverSocket.accept();

mainFrame.updateLog("hi\n");

Proxy thd = new Proxy(sck, config, serverDataBase, cache,

serversAccessibleWOProxy, mainFrame);

thd.start();System.out.println("after proxy");if(i==1)

{BufferedReader b= new BufferedReader(new InputStreamReader(System.in));

b.read();}

} catch (IOException e) {

mainFrame.updateLog("\nProxy shutting down...");

} catch (Exception e) {

mainFrame.updateLog("\nProxy error! Shutting down... "+e);

} finally {

try {

serverSocket.close();

} catch (Exception b ) {}

// while (activeCount() > initialNoOfThreads)

// yield();

// shut down the proxy.

config.shutDown(serverDataBase.shutDown() &&

26 | P a g e
cache.shutDown() &&

serversAccessibleWOProxy.shutDown());

System.exit(0);

Module 2: Proxy.java

package proxy;

import java.net.*;

import java.io.*;

import java.util.*;

import java.awt.*;

import proxy.HttpReplyHdr;

import proxy.HttpRequestHdr;

import proxy.Configuration;

import proxy.ServerDataBase;

import proxy.Cache;

import proxy.ServersAccessibleWOProxy;

import proxy.DocumentInfo;

import proxy.ServerInfo;

import proxy.MainFrame;

27 | P a g e
public class Proxy extends Thread {

private static Integer hits = new Integer(0);

private static Integer misses = new Integer(0);

private Configuration config;

private ServerDataBase serverDataBase;

private Cache cache;

private ServersAccessibleWOProxy serversAccessibleWOProxy;

private MainFrame mainFrame;

private Socket client = null;

public Proxy(Socket socket,

Configuration p_config,

ServerDataBase p_serverDataBase,

Cache p_cache,

ServersAccessibleWOProxy p_serversAccessibleWOProxy,

MainFrame p_mainFrame)

client = socket;

config = p_config;

serverDataBase = p_serverDataBase;

cache = p_cache;

serversAccessibleWOProxy = p_serversAccessibleWOProxy;

mainFrame = p_mainFrame;

public void run(){


28 | P a g e
Socket server = null;

String clientName ="";

String serverName ="";

URL url;

HttpRequestHdr request = new HttpRequestHdr();

HttpReplyHdr reply = new HttpReplyHdr();

boolean documentInCache = false;

boolean serverFilesMayBeCached = false;

DocumentInfo documentInfo;

File file = null;

FileOutputStream fileToCache = null;

try {

System.out.println("in proxy");

request.parse(client.getInputStream());

clientName = client.getInetAddress().getHostName();

url = new URL(request.url);

mainFrame.updateLog("Client '" + clientName +

"' Requesting '" + request.url+"'");

synchronized(serversAccessibleWOProxy) {

if(!serversAccessibleWOProxy.containsKey(url.getHost()))

29 | P a g e
serverFilesMayBeCached = true;

synchronized(cache) {

if(serverFilesMayBeCached &&

!request.pragmaNoCache &&

request.ifModifiedSince.equals("") &&

cache.containsKey(url)) {

documentInCache = true;
documentInfo = (DocumentInfo)cache.get(url);

else documentInfo = null;

// If the request is cached, channel it to client.

if(documentInCache) {

synchronized (documentInfo) {

File cachedFile = new File(config.getCacheDirectory(),

documentInfo.getFileName());

if (cachedFile.exists()) {

mainFrame.updateLog("Retrieving "+ request.url + "

from cache.");

synchronized (hits) {

hits = new Integer(hits.intValue()+1);

mainFrame.updatePieChart(hits.intValue(),

misses.intValue());

30 | P a g e
}

documentInfo.incrementReferences();

FileInputStream in = new

FileInputStream(cachedFile);

OutputStream out = client.getOutputStream();

byte data[] = new byte[2000];

int count;

while (-1 < ( count = in.read(data))) {

out.write(data,0,count);

Thread.yield();

try {out.flush();} catch (Exception ef1){}

try {in.close();} catch (Exception e){}

try {client.close();} catch (Exception e){}

return;

}
}

if(serverFilesMayBeCached &&

!request.pragmaNoCache &&

request.ifModifiedSince.equals(""))

31 | P a g e
synchronized(misses) {

misses = new Integer(misses.intValue()+1);

mainFrame.updatePieChart(hits.intValue(), misses.intValue());

Date timerStart;

Date timerEnd;

if (config.alternativeProxyOn()) {

serverName = config.getAlternativeProxyName();

timerStart = new Date();

server = new Socket(serverName,config.getAlternativeProxyPort());

else {

serverName = serverName(request.url);

timerStart = new Date();

server = new Socket(serverName,serverPort(request.url));

timerEnd = new Date();

long connectionTime = timerEnd.getTime() - timerStart.getTime();

mainFrame.updateLog("Passing the request for "+request.url+" to "+

serverName);

DataOutputStream srvOut =
32 | P a g e
new DataOutputStream(server.getOutputStream());

if (!config.alternativeProxyOn())

request.url = serverUrl(request.url);

srvOut.writeBytes(request.toString(false));

srvOut.flush();

/*

* Send data to server (needed for post method and things

* that go bump in the net).

*/

for (int i =0; i < request.contentLength; i++) {

server.getOutputStream().write(client.getInputStream().read());

server.getOutputStream().flush();

/*

* Echo and send the HTTP responce header from

* the server to the client.

*/

DataInputStream Din =

new DataInputStream(server.getInputStream());

DataOutputStream Dout =

new DataOutputStream(client.getOutputStream());

timerStart = new Date(); // start timing transmission of responce.

String statusLine = Din.readLine();

33 | P a g e
StringTokenizer st = new StringTokenizer(statusLine);

// Parse responce header

st.nextToken(); // HTTP version

String returnCode = st.nextToken();

if (!returnCode.equals("200") || !serverFilesMayBeCached) {

mainFrame.updateLog("Transferring "+request.url+ " to

"+clientName);

Dout.writeBytes(statusLine + "\r\n");

if (statusLine.length() > 0) {

while (true) {

String str = Din.readLine();

Dout.writeBytes(str+"\r\n");

if (str.length() <= 0) break;

Dout.flush();

InputStream in = server.getInputStream();

OutputStream out = client.getOutputStream();

byte data[] = new byte[2000];

int count;

while (-1 < ( count = in.read(data))) {

out.write(data,0,count);

Thread.yield(); // Remember this is multi-threaded

34 | P a g e
}

try {out.flush();} catch (Exception ef1){}

try {in.close();} catch (Exception e){}

try {client.close();} catch (Exception e){}

if (serverFilesMayBeCached) {

// reply did not include body, so only connection time info

// is saved.
synchronized (serverDataBase) {

if (serverDataBase.containsKey(url.getHost()))

((ServerInfo)serverDataBase.get(url.getHost())).

updateAverageConnectionTime(connectionTime,

config.getServerInfoSmoothingFactor());

return;

// channel reply to client and cache it

String fileName = config.getNextFileName();

long fileSize = 0;

35 | P a g e
file = new File(config.getCacheDirectory(), fileName);

fileToCache = new FileOutputStream(file);

mainFrame.updateLog("Transferring "+request.url+ " to "+clientName +

" and saving to local file " +fileName);

byte[] bytes; // buffer for outputing strings.

statusLine += "\r\n";

fileSize += statusLine.length();

Dout.writeBytes(statusLine);

bytes = new byte[statusLine.length()];

statusLine.getBytes(0,statusLine.length(),bytes,0);

fileToCache.write(bytes);

if (statusLine.length() > 2) {

while (true) {

String str = Din.readLine() + "\r\n";

fileSize += str.length();

Dout.writeBytes(str);

bytes = new byte[str.length()];

str.getBytes(0,str.length(),bytes,0);

fileToCache.write(bytes);

if (str.length() <= 2) break;

36 | P a g e
Dout.flush();

InputStream in = server.getInputStream();

OutputStream out = client.getOutputStream();

byte data[] = new byte[2000];

int count;

while (-1 < ( count = in.read(data))) {

fileSize += count;

out.write(data,0,count);

fileToCache.write(data,0,count);

Thread.yield(); // Remember this is multi-threaded

timerEnd = new Date();

// Estimate bandwidth [bytes/seconds]

double bandWidth = 1000 * fileSize

/(timerEnd.getTime() - timerStart.getTime());

try {out.flush();} catch (Exception ef1){}

try {in.close();} catch (Exception e){}

try {client.close();} catch (Exception e){}

try {fileToCache.flush();} catch (Exception e) {}

try {fileToCache.close();} catch (Exception e){}

// Update server data base.

37 | P a g e
synchronized (serverDataBase) {

ServerInfo serverInfo;

if (!serverDataBase.containsKey(url.getHost())) {

serverInfo = new ServerInfo(url.getHost(),

connectionTime,bandWidth);

serverDataBase.put(url.getHost(), serverInfo);

else {

serverInfo = (ServerInfo)serverDataBase.get(url.getHost());

serverInfo.updateAverageBandWidth(bandWidth,

config.getServerInfoSmoothingFactor());

serverInfo.updateAverageConnectionTime(connectionTime,

config.getServerInfoSmoothingFactor());

serverInfo.incrementReferences();

mainFrame.updateLog("Caching "+request.url);

synchronized (cache) {

if (cache.containsKey(url)) {

documentInfo = (DocumentInfo)cache.get(url);

synchronized (documentInfo) {

cache.incrementCurrentWaterMark(

38 | P a g e
fileSize - documentInfo.getSize());

File oldFileName = new

File(config.getCacheDirectory(),

documentInfo.getFileName());

try { oldFileName.delete(); } catch(Exception e) {};

documentInfo.setFileName(fileName);

documentInfo.setSize(fileSize);

documentInfo.incrementReferences();

cache.put(url, documentInfo);

else {

documentInfo = new DocumentInfo(url, fileName, fileSize);

cache.incrementCurrentWaterMark(fileSize);

cache.put (url, documentInfo);

mainFrame.updateCacheBar(config.getCacheHighWaterMark(),

config.getCacheLowWaterMark(),

cache.getCurrentWaterMark());

return;

39 | P a g e
catch (UnknownHostException uhe)

mainFrame.updateLog("Server Not Found"+uhe.toString());

try {

DataOutputStream out =

new DataOutputStream(client.getOutputStream());

out.writeBytes(reply.formNotFound());

out.flush();

} catch (Exception uhe2){}

} catch (Exception e) {

mainFrame.updateLog("Proxy error"+e.toString());

try {

DataOutputStream out =

new DataOutputStream(client.getOutputStream());

out.writeBytes(reply.formInternalError());

out.flush();

} catch (Exception uhe2){}

try {fileToCache.close();} catch (Exception e1) {}

try {file.delete();} catch (Exception e2) {}

} finally {

try {client.getOutputStream().flush();} catch (Exception ef1){}

40 | P a g e
try {server.close();} catch (Exception e){}

try {client.close();} catch (Exception e){}

mainFrame.updateLog("Done [" + clientName+"] "+ request.url);

private String serverName(String str) {

// chop to "server.name:x/thing"

int i = str.indexOf("//");

if (i< 0) return "";

str = str.substring(i+2);

// chop to server.name:xx

i = str.indexOf("/");

if (0 < i) str = str.substring(0,i);

// chop to server.name

i = str.indexOf(":");

if (0 < i) str = str.substring(0,i);

return str;

private int serverPort(String str) {

// chop to "server.name:x/thing"

int i = str.indexOf("//");
41 | P a g e
if (i< 0) return 80;

str = str.substring(i+2);

// chop to server.name:xx

i = str.indexOf("/");

if (0 < i) str = str.substring(0,i);

// chop XX

i = str.indexOf(":");

if (0 < i) {

return Integer.parseInt(str.substring(i).trim());

return 80;

private String serverUrl(String str) {

int i = str.indexOf("//");

if (i< 0) return str;

str = str.substring(i+2);

i = str.indexOf("/");

if (i< 0) return str;

return str.substring(i);

42 | P a g e
Module 3: Mainframe.java

import java.net.*;

import java.awt.*;

import proxy.Configuration;

import PieChart;

import CacheDlg;

import ServerDataBaseDlg;

import AlternativeProxyDlg;

import proxy.ServersAccessibleWOProxy;

import AboutDlg;

import proxy.Cache;

public class MainFrame extends Frame

private Configuration config;

private Cache cache;

public ServerSocket serverSocket;

private MainMenu mainMenu;

private PieChart pieChart;

private CacheBar cacheBar;

private LogArea logArea;

private GridBagLayout gridBag;

private GridBagConstraints constraints;


43 | P a g e
private boolean shuttingDown;

private ServersAccessibleWOProxy serversAWOP = null;

public MainFrame(String title, Configuration p_config)

super(title);

config = p_config;

resize(800,500);

mainMenu = new MainMenu(this);

mainMenu.CreateMenu();

gridBag = new GridBagLayout();

constraints = new GridBagConstraints();

setLayout(gridBag);

constraints.gridwidth = 1;

constraints.gridheight = 2;

constraints.fill = GridBagConstraints.BOTH;

constraints.weightx = 1;

constraints.weighty = 1;

logArea = new LogArea(30,60);

gridBag.setConstraints(logArea,constraints);
44 | P a g e
add(logArea);

constraints.gridwidth = GridBagConstraints.REMAINDER;

constraints.gridheight = 1;

constraints.weightx = 0;

pieChart = new PieChart();

pieChart.setBackground(Color.gray.brighter());

gridBag.setConstraints(pieChart,constraints);

add(pieChart);

cacheBar = new CacheBar(config.getCacheHighWaterMark(),

config.getCacheLowWaterMark(),

config.getCacheCurrentWaterMark());

cacheBar.setBackground(Color.gray.brighter());

gridBag.setConstraints(cacheBar,constraints);

add(cacheBar);

shuttingDown = false;

repaint();

pack();

move (250, 30);

show();

45 | P a g e
public void updatePieChart(int hits, int misses)

pieChart.updatePieChart(hits, misses);

public void updateCacheBar(long p_highWM, long p_lowWM, long p_currentWM)

cacheBar.updateCacheBar(p_highWM, p_lowWM, p_currentWM);

public void updateLog(String str)

logArea.appendText(str+"\n");

public boolean handleEvent (Event event)

if(shuttingDown)

return (true);

switch (event.id) {

case Event.WINDOW_DESTROY:

shuttingDown = true;

try {serverSocket.close();} catch (Exception e) {}

break;

case Event.ACTION_EVENT:

if(event.target instanceof MenuItem) {

46 | P a g e
if(((String)event.arg).equals("Exit")) {

shuttingDown = true;

try {serverSocket.close();} catch (Exception e) {}

else if(((String)event.arg).equals("Cache")) {

if (cache == null)

return super.handleEvent(event);

CacheDlg cd = new CacheDlg(this, "Cache

Parameters",config, cache);

else if(((String)event.arg).equals("Servers Data Base")) {

ServerDataBaseDlg sdb = new ServerDataBaseDlg(this,

"Servers Data Base

Parameters",config);

else if(((String)event.arg).equals("Alternative Proxy")) {

AlternativeProxyDlg ap = new

AlternativeProxyDlg(this,

"Alternative Proxy

Parameters",config);

else if(((String)event.arg).equals("No Cache Servers")) {

if (serversAWOP == null)

return super.handleEvent(event);

ServersAccessibleWOProxyDlg sawp =

new ServersAccessibleWOProxyDlg(this,

"No Cache Servers", serversAWOP);


47 | P a g e
}

else if(((String)event.arg).equals("About")) {

AboutDlg cd = new AboutDlg(this);

break;

default:

return super.handleEvent(event);

return true;

public void setServerSocket(ServerSocket p_serverSocket)

serverSocket = p_serverSocket;

public void setServersAccessibleWOProxy(ServersAccessibleWOProxy sawop)

serversAWOP = sawop;

public void setCache(Cache p_cache)

cache = p_cache;

48 | P a g e
}

Module 4: Cache.java

package proxy;

import java.net.*;

import java.io.*;

import java.util.*;

import java.awt.*;

import proxy.DocumentInfo;

import proxy.ServerDataBase;

import proxy.Configuration;

import proxy.DocumentMark;

import MainFrame;

public class Cache extends Hashtable

private long currentWaterMark;

private Configuration config;

private ServerDataBase serverDataBase;

private MainFrame mainFrame;

public Cache(Configuration p_config,


49 | P a g e
ServerDataBase p_serverDataBase,

MainFrame p_mainFrame)

super();

config = p_config;

serverDataBase = p_serverDataBase;

mainFrame = p_mainFrame;

currentWaterMark = config.getCacheCurrentWaterMark();

DocumentInfo documentInfo;

File fileInHand;

try {

RandomAccessFile in = new RandomAccessFile(

config.getCacheBackupFile(),"r");

String s = in.readLine().substring(1);

in.close();

StringTokenizer st = new StringTokenizer(s);

String key;

String documentInfoStr;

Hashtable filesIndexedInCache = new Hashtable();

int maxEnumerator = 0;

50 | P a g e
try {

if (config.proxyBroughtDownProperly())

while(st.hasMoreElements()) {

key = st.nextToken("=");

while (key.substring(0,1).equals(" "))

key = key.substring(1);

// chop " "

documentInfoStr = st.nextToken(",}");

documentInfoStr = documentInfoStr.substring(1);

//chop "="

put(new URL(key), new

DocumentInfo(documentInfoStr));

else {

Object dummy = new Object();

currentWaterMark = 0;

while(st.hasMoreElements()) {

key = st.nextToken("=");

while (key.substring(0,1).equals(" "))

key = key.substring(1);

// chop " "

documentInfoStr = st.nextToken(",}");

51 | P a g e
documentInfoStr = documentInfoStr.substring(1);

//chop "="

documentInfo = new

DocumentInfo(documentInfoStr);

fileInHand = new

File(config.getCacheDirectory(),

documentInfo.getFileName());

if(fileInHand.exists()) {

put(new URL(key), documentInfo);

filesIndexedInCache.put(fileInHand,

dummy);

try {

((ServerInfo)(serverDataBase

.get(documentInfo.getUrl().

getHost())))

.incrementReferences();

} catch (NullPointerException npe) { //

inconsistent BAK files

serverDataBase.clear();

throw new

NoSuchElementException(); // pass control to next catch

52 | P a g e
incrementCurrentWaterMark(documentInfo.getSize());

if(maxEnumerator <

(new

Integer(fileInHand.getName())).intValue())

maxEnumerator =

(new

Integer(fileInHand.getName())).intValue();

}
}

config.setFileNameEnumerator(maxEnumerator);

config.setCacheCurrentWaterMark(currentWaterMark);

File directory = new File(config.getCacheDirectory());

String files[] = directory.list();

for(int i=0; i<files.length; i++) {

fileInHand = new

File(config.getCacheDirectory(),files[i]);

if(!

filesIndexedInCache.containsKey(fileInHand))

fileInHand.delete();

serverDataBase.clearZeroReferencedItems();

} catch (NoSuchElementException e) { // backup file is corrupted

clear();

try {

53 | P a g e
File f = new File(config.getCacheBackupFile());

f.delete();

} catch (Exception x) {};

throw new IOException(); // pass control to next catch

} catch (IOException e) { // cannot access backup file

File directory = new File(config.getCacheDirectory());

String files[] = directory.list();

for(int i=0; i<files.length; i++) {

fileInHand = new File(config.getCacheDirectory(),files[i]);

try {fileInHand.delete();} catch (Exception e1) {}

} finally {

mainFrame.updateCacheBar(config.getCacheHighWaterMark(),

config.getCacheLowWaterMark(),

currentWaterMark);

public Object put(Object key, Object value)

Object obj = super.put(key, value);

if (currentWaterMark >= config.getCacheHighWaterMark())

54 | P a g e
makeRoom();

return obj;

public long getCurrentWaterMark()

return currentWaterMark;
}

public void incrementCurrentWaterMark(long size)

currentWaterMark += size;

public void decrementCurrentWaterMark(long size)

currentWaterMark -= size;

public boolean shutDown()

File file = new File(config.getCacheBackupFile());

if (file.exists()) file.delete();

try {

55 | P a g e
RandomAccessFile out = new RandomAccessFile(file,"rw");

out.writeBytes(toString()+'\n');

out.close();

} catch (IOException e) {

return false;

config.setCacheCurrentWaterMark(currentWaterMark);

return true;

public void makeRoom()

DocumentMark[] array = new DocumentMark[size()];

URL keyInHand;

double mark;

double wCT,wBW,wRF,wS;

DocumentInfo documentInfoInHand;

ServerInfo serverInfoInHand;

mainFrame.updateLog("\nPerforming cache cleanup...\n");

synchronized (config) {

wCT = config.getWeightConnectionTime();

wBW = config.getWeightBandWidth();

wRF = config.getWeightReferencesFrequency();

56 | P a g e
wS = config.getWeightSize();

Enumeration e = keys();

for (int i=0; e.hasMoreElements(); i++) {

keyInHand = (URL)e.nextElement();

documentInfoInHand = (DocumentInfo)get(keyInHand);

serverInfoInHand = (ServerInfo)serverDataBase.get(

keyInHand.getHost());

mark = documentMark(documentInfoInHand, serverInfoInHand,

wCT, wBW, wRF, wS);

array[i] = new DocumentMark(mark, documentInfoInHand);

sort(array, 0, array.length-1);

File fileInHand;

long lowWaterMark;

long highWaterMark;

String cacheDirectory;

synchronized (config) {

lowWaterMark = config.getCacheLowWaterMark();

highWaterMark = config.getCacheHighWaterMark();

cacheDirectory = config.getCacheDirectory();

57 | P a g e
for(int i = 0; currentWaterMark >= lowWaterMark; i++) {

documentInfoInHand = (DocumentInfo)array[i].getDocumentInfo();

synchronized (documentInfoInHand) {

fileInHand = new File(cacheDirectory,

documentInfoInHand.getFileName());

fileInHand.delete();

decrementCurrentWaterMark(documentInfoInHand.getSize());

remove(documentInfoInHand.getUrl());

synchronized (serverDataBase) {

serverInfoInHand = (ServerInfo)serverDataBase.get(

documentInfoInHand.getUrl().getHost());

if(serverInfoInHand.decrementReferences() == 0)

serverDataBase.remove(documentInfoInHand

.getUrl().getHost());

mainFrame.updateCacheBar(highWaterMark,lowWaterMark,currentWaterMark);

private double documentMark (DocumentInfo documentInfo, ServerInfo serverInfo,

58 | P a g e
double wCT, double wBW, double wRF, double

wS)

return ((wCT * serverInfo.getAverageConnectionTime() +

wBW / serverInfo.getAverageBandWidth()) *

Math.pow(documentInfo.getReferencesPerHour(),wRF) /

Math.pow(documentInfo.getSize(),wS));

private void sort(DocumentMark[] array, int left, int right)

if (left >= right)

return;

int mid = split(array,left,right);

sort(array, left, mid-1);

sort(array, mid+1, right);

private int split(DocumentMark[] array, int p_left, int p_right)

double mid = array[p_left].getMark();

int left = p_left+1;

int right = p_right;

59 | P a g e
DocumentMark temp;

while(left <= right) {

while (left <= right && array[left].getMark() <= mid)

left++;

while (left <= right && array[right].getMark() >= mid)

right--;

if (left <= right) {

temp = array[left];

array[left] = array[right];

array[right] = temp;

left++;

right--;

temp = array[right];

array[right] = array[p_left];

array[p_left] = temp;

return right;

Module 5 : HttpRequestHdr.java

package proxy;

60 | P a g e
import java.io.InputStream;

import java.io.DataInputStream;

import java.util.StringTokenizer;

public class HttpRequestHdr

public String method = new String();

public String url = new String();

public String version = new String();

public String userAgent = new String();

public String referer = new String();

public String ifModifiedSince = new String();

public String accept = new String();

public String authorization = new String();

public String contentType = new String();

public int contentLength = -1;

public int oldContentLength = -1;

public String unrecognized = new String();

public boolean pragmaNoCache = false;

static String CR ="\r\n";

public boolean parse(InputStream In)

{
61 | P a g e
String CR ="\r\n";

DataInputStream lines;

StringTokenizer tz;

try {

lines = new DataInputStream(In);

tz = new StringTokenizer(lines.readLine());

} catch (Exception e) {

return false;

method = getToken(tz).toUpperCase();

url = getToken(tz);

version= getToken(tz);

while (true) {

try {

tz = new StringTokenizer(lines.readLine());

} catch (Exception e) {

return false;

String Token = getToken(tz);

if (0 == Token.length())

break;

if (Token.equalsIgnoreCase("USER-AGENT:")) {

userAgent = getRemainder(tz);
62 | P a g e
} else if (Token.equalsIgnoreCase("ACCEPT:")) {

accept += " " + getRemainder(tz);

} else if (Token.equalsIgnoreCase("REFERER:")) {

referer = getRemainder(tz);

} else if (Token.equalsIgnoreCase("PRAGMA:")) {

// Pragma: <no-cache>

Token = getToken(tz);

if (Token.equalsIgnoreCase("NO-CACHE"))

pragmaNoCache = true;

else

unrecognized += "Pragma:" + Token + " "

+getRemainder(tz) +"\n";

} else if (Token.equalsIgnoreCase("AUTHORIZATION:")) {

// Authenticate: Basic UUENCODED

authorization= getRemainder(tz);

} else if (Token.equalsIgnoreCase("IF-MODIFIED-SINCE:")) {

String str = getRemainder(tz);

int index = str.indexOf(";");

if (index == -1) {

ifModifiedSince =str;

} else {
63 | P a g e
ifModifiedSince =str.substring(0,index);

index = str.indexOf("=");

if (index != -1) {

str = str.substring(index+1);

oldContentLength =Integer.parseInt(str);

} else if (Token.equalsIgnoreCase("CONTENT-LENGTH:")) {

Token = getToken(tz);

contentLength =Integer.parseInt(Token);

} else if (Token.equalsIgnoreCase("CONTENT-TYPE:")) {

contentType = getRemainder(tz);

} else {

unrecognized += Token + " " + getRemainder(tz) + CR;

return true;

public String toString(boolean sendUnknowen) {

String Request;

if (0 == method.length())

method = "GET";

64 | P a g e
Request = method +" "+ url + " HTTP/1.0" + CR;

if (0 < userAgent.length())

Request +="User-Agent:" + userAgent + CR;

if (0 < referer.length())

Request+= "Referer:"+ referer + CR;

if (pragmaNoCache)

Request+= "Pragma: no-cache" + CR;

if (0 < ifModifiedSince.length())

Request+= "If-Modified-Since: " + ifModifiedSince + CR;

// ACCEPT TYPES //

if (0 < accept.length())

Request += "Accept: " + accept + CR;

else

Request += "Accept: */"+"* \r\n";

if (0 < contentType.length())

Request += "Content-Type: " + contentType + CR;

if (0 < contentLength)

Request += "Content-Length: " + contentLength + CR;

65 | P a g e
if (0 != authorization.length())

Request += "Authorization: " + authorization + CR;

if (sendUnknowen) {

if (0 != unrecognized.length())

Request += unrecognized;

Request += CR;

return Request; }

public String toString() {

return toString(true);

String getToken(StringTokenizer tk){

String str ="";

if (tk.hasMoreTokens())

str =tk.nextToken();

return str;

String getRemainder(StringTokenizer tk){

String str ="";

if (tk.hasMoreTokens())

str =tk.nextToken();

while (tk.hasMoreTokens()){

str +=" " + tk.nextToken();

}
66 | P a g e
return str;

b) Gantt Chart:

67 | P a g e
6. BIBLIOGRAPHY:
• Wrox Java Networking.
• Object-Oriented Modeling and Design-James Rambaugh
• Beej's Guide to Socket Programming.
• Wikipedia

68 | P a g e

S-ar putea să vă placă și