Internet-Draft A. Pareek
Intended status: Experimental
Expires: January 10, 2017
Knowledge Based Web Pages
draft-anshul-knowledge-based-web-pages-00
Abstract
This document tries to address a problem of delivering redundant
content of a dynamic web page to the same client over the
Internet. The dynamic web page made up of two kind of data first
one comes from external sources such as database or some text
files etc which is dynamic in the nature and may change over
the next request made from the same client, the second one is
static in the nature such as formatting tag of html[3] which
remain unchanged until the program of dynamic web page does
not modified.
Instead of sending the whole page at each subsequent request
from the same client it is better to send the dynamic data and
client can use the static data from the cache of previous
response to format the dynamic data of current response.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts.
The list of current Internet-Drafts is at
http://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents
at any time. It is inappropriate to use Internet-Drafts
as reference material or to cite them other than
as "work in progress.
Copyright (c) 2016 IETF Trust and the persons identified as the document
authors. All rights reserved.
Anshul,et al. January 10, 2017 [Page 01]
Internet-Draft Knowledge Based Web Page July 2016
This document is subject to BCP 78 and the IETF Trust's Legal Provisions
Relating to IETF Documents (http://trustee.ietf.org/license-info)
in effect on the date of publication of this document. Please
review these documents carefully, as they describe your rights
and restrictions with respect to this document.
Table of Contents
1. Introduction.................................02
1.1 Static Web Page............................03
1.2 Dynamic Web Page...........................03
1.2.1 Server Side Dynamic Web Page..........03
1.2.2 Client Side Dynamic Web Page..........03
1.3 Terminology................................03
1.4 Overall Operation..........................04
2. The Caching of Web Pages......................06
3. The Knowledge Based Web Page..................06
3.1 The Content-Status Request Header
& Offset Response Header...................07
3.2 Identifying Static & Dynamic Part
of a web page..............................07
3.3 Updating Cached Entry.......................10
4. Offset Generation............................12
5. Implementation in Java.......................13
6. Difference between delta Encoding
and Knowledge Based Web Page...............63
7. The Version Number of HTTP Protocol..........63
8. Security Considerations.......................63
9. References....................................64
10. Author's Address.............................64
1. Introduction
A web server is a place where all World Wide Web pages simply
called web pages reside over the internet. The Hyper Text
Markup Language used to create a web page. When a request arrives
to the web server for a web page it simply delivers the set
Anshul,et al. January 10, 2017 [Page 02]
Internet-Draft Knowledge Based Web Page July 2016
of HTML instructions to the client using HTTP (Hyper Text
Transfer Protocol)[1]. The HTTP is a delivery system through which
a web page moves from a server to a client.
There are two types of Web Pages.[5]
1.1 Static Web Page: - A static web page is an html file
stored on the web server. When a request arrives to the web server
for a static web page the server copies the file and delivers
it as it is to the client.
1.2 Dynamic Web Page: - A web page, if its content changes
over the time called dynamic web page. There are two types of
dynamic web page
1.2.1 Server-Side Dynamic Web Page: - A dynamic web page is a
program stored on a web server. When a request arrives to a web
server for the dynamic web page the server executes the program
and delivers output of the program to the client.
1.2.2 Client-Side Dynamic Web Page: - A dynamic web page is a
program stored on the web server. When a request arrives to a
web server for the dynamic web page the server delivers the
program to the client. The client executes the program and gets
output which is the desired web page.
This Internet-Draft tries to improvise the delivery system of
the Server-Side dynamic web pages and try to develop a caching
mechanism for server side dynamic web pages.
1.3 Terminology
This Internet-Draft uses a number of terms to refer to the roles
played by participants in, and objects of, the HTTP commu
nication for more details refer RFC 2616[1].
Connection
A transport layer virtual circuit established
between two programs for the purpose of communication.
Message
The basic unit of HTTP communication,
consisting of a structured
sequence of octets matching the syntax defined in rfc 2616
Anshul,et al. January 10, 2017 [Page 03]
Internet-Draft Knowledge Based Web Page July 2016
Request
An HTTP request message, as defined in rfc 2616
Response
An HTTP response message, as defined in rfc 2616
Client
A program that establishes connections for the purpose of sending requests.
Server
An application program that accepts connections in order to
service requests by sending back responses.
Origin server
The server on which a given resource resides or is to be created.
Cache
A programs local store of response messages
and the subsystem that controls its message
storage, retrieval, and deletion.
A cache stores cacheable responses in order to reduce
the response time and network bandwidth
consumption on future, equivalent requests.
Validator
A protocol element (e.g. an entity tag or a Last-Modified time)
that is used to find out whether a cache entry is an equivalent
copy of an entity.
1.4 Overall Operation
At present time, when a request for a dynamic web page arrives
at a server, the server executes the correspond program to
the request and send back the result to the client as illustrated
below
Example:-
Suppose a client makes a request of an employee named vikas to
a web server. The clients request would be as follow
Request message format of HTTP 1.1 would be
Get /search.htmltxtCriteria=Vikas HTTP/1.1
Host: www.xyz.com
Connection: Keep-Alive
Accept: *
Anshul,et al. January 10, 2017 [Page 04]
Internet-Draft Knowledge Based Web Page July 2016
The response from the server would be
HTTP/1.1 200 OK
Date: Mon, 08 Feb 2016 11:26:20 GMT
Content-Type: text/html
Content-Length: 325
Cache-Control: no-cache
Home Page
Sr.No | Name | Designation | Dept
th> |
1. | Vikas Soni | CA-II | Accounts<
/th> |
2. | Vikas Singh | CA-I | Accounts<
/th> |
Database search engine finds the two records begin with Vikas
string. Now, again a request reaches to the server with the
different search string at this time client wants the records
begin with Viren String.
The response of the server would be as follows
HTTP/1.1 200 OK
Date: Mon, 08 Feb 2016 11:26:24 GMT
Content-Type: text/html
Content-Length: 245
Cache-Control: no-cache
Home Page
Sr.No | Name | Designation | Dept
th> |
1. | Viren Singh | CA-II | Accounts
|
In both responses only the content of the table has changed
but the formatting tags and other part of the table and web
page remains same.
This document tries to eliminate this redundant information/
formatting tags to be send each time to the same client. This
document tries to develop an algorithm which enable proxy
Anshul,et al. January 10, 2017 [Page 05]
Internet-Draft Knowledge Based Web Page July 2016
server/client to store the static part of the web page/formatting
tags etc and ask only for the dynamic information from the
server then build the whole page.
2. The caching of Web pages
The caching is a process of improving the response time of a
server. In other words, when a server sends a response to satisfy
a request the response reaches to the client through the
intermediaries nodes among them some of nodes are caching proxy
servers which stores a copy of the response in order to satisfy
subsequent request of the resource which saves the time of
both parties and improves the performance of the network.[9]
3. The Knowledge Based Web Page
If a client has an expired copy of a page, it requests the
latest instance of the page. If the server has a newer instance
of the page, it will send it to the client, and it will sent
the full new instance of the page.
Rather than sending it the entire new page, the client would
get the page faster if the server sent just the changes to the
clients copy of the page.
Server can achieve this objective without help of a copy of
the previous response if it delivers the OFFSETs which are the
index of the content of a web page that separates the static
part and dynamic part of web page, the detail explanation of
this algorithm is as follow.
The server needs two additional Header fields for accomplishing
this task first one is Content-Status and second one if Offset.
Content-Status header field present in the request message
and has a string in its value either Data or Page. Data Value
indicates the client requests only for update of a web page,
Anshul,et al. January 10, 2017 [Page 06]
Internet-Draft Knowledge Based Web Page July 2016
in response to this request the server sent the changes to the
clients copy of the page along with offset header in response.
For the Page Value server sent the full new instance of the
page along with offset header in response.
3.1 Content-Status Request Header Offset Response Header
This Internet-Draft requests to the Internet
Engineering Task Force to add these two new
headers into the HTTP Protocol in
order to achieve the caching of Dynamic web page.
The Content-Status request header presents in a request message
with value either PAGE or DATA. The value PAGE tells the
server that client wants a whole copy of a requested web page.
The Value DATA tells the server that client wants only changes
/ Dynamic data of a requested web page.
If content-status header is not present in a request message
then server send the full instance of requested web page. In
other words, server considers this case equivalent to
Content-Status: PAGE.
Offset header presents in the response message with paired
integer values. The first value of a pair indicates the static
part of the page and second value of a pair indicates the
dynamic part of a page and this header can has as many
paired value as needed.
3.2 Identifying Static and Dynamic Part of a Web Page
A program is a sequence of instructions every instruction has
a specific meaning to the microprocessor. A static part of page
would be those instructions which contain simple html tags.
A Dynamic Part of a page would be those instructions which call
a function or perform other processing and then their result
adds to the page.
import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
public class DemoServlet extends HttpServlet{
public void doGet(HttpServletRequest req,HttpServletResponse
res) throws ServletException,IOException
Anshul,et al. January 10, 2017 [Page 07]
Internet-Draft Knowledge Based Web Page July 2016
{
Date d=new Date();
res.setContentType("text/html");//setting the content type
PrintWriter pw=res.getWriter();//get the stream to write the
data
pw.println(""); //Length is 13
pw.println("Welcome to servlet");// Length 19
pw.println(Date d); //At this time Length is 5
//The above line of code generates the dynamic data
pw.println("");
pw.close();//closing the stream
}}[8]
Output of this program is
Welcome to servlet
Date May 04 09:51:52 CDT 2009
The Offset header for this Servlet program would be Offset:
37-24
The value 37 indicates that after 37 characters, dynamic data
begins of length 24 characters long.
When a client makes a request first time of a page, the server
would sent the full instance of the page, the request and
response messages would look like as follows.
The request message:-
----------------------------------------
Get /search.htmltxtCriteria=Viren HTTP/1.1
Accept-Encoding: gzip, compress
Date: Mon, 08 Feb 2016 11:26:20 GMT
Content-Type: text/html
Content-Status: Page
Keep-Connection: alive
----------------------------------------
On this request web server returns the full instance of the
page along with an Offset header.
The Content-Status header field tells the server that client
needs full instance of the page.
If client needs only updated information, Content-Status value
will be set to DATA in the request message.
The response message:-
----------------------------------------
HTTP/1.1 200 OK
Date: Mon, 08 Feb 2016 11:26:20 GMT
Anshul,et al. January 10, 2017 [Page 08]
Internet-Draft Knowledge Based Web Page July 2016
Cache-Control: must-revalidate
Offset: 148-72
Content-Length: 245
Home Page
Sr.No | Name | Designation | Dept
th> |
1. | Viren Singh | CA-II | Accounts
|
---------------------------------------
The Caching-Proxy-Server/Client Cache simply stores a copy of
the response message which helps next time to make request only
for updated information, offset header has two integer values
in a pair and may has as many paired values as necessary, in
each pair the first value represent the static data length and
second pair value represent the dynamic data length as explain
below.
Now client makes an another request for the same page with
different search criteria Vikas.
The request message:-
----------------------------------------
Get /search.htmltxtCriteria=Vikas HTTP/1.1
Accept-Encoding: gzip, compress
Date: Mon, 08 Feb 2016 11:26:20 GMT
Content-Type: text/html
Content-Status: Data
Keep-Connection: alive
----------------------------------------
On this request web server returns the changes of the page from
previous request with an Offset header as follow.
Anshul,et al. January 10, 2017 [Page 09]
Internet-Draft Knowledge Based Web Page July 2016
The response message:-
----------------------------------------
HTTP/1.1 200 OK
Date: Mon, 08 Feb 2016 11:26:22 GMT
Cache-Control: must-revalidate
Offset: 148-142
Content-Length: 142
1. | Vikas Soni | CA-II | Accounts<
/th> |
2. | Vikas Singh | CA-I | Accounts<
/th> |
-----------------------------------------
Now, it a duty of the Caching Proxy Server/Client Caching
Algorithm to generate a fresh copy of the page, the algorithm of
updating cached copy is as discuss below for different sets of
inputs.
3.3 Updating Cached Entry
The Caching-Proxy-Server has to know the way that helps it to
generate the fresh copy with the help of Cached response and
fresh response. The Algorithm of updating cached
copy is discussed below with use of an example.
Input Set 1
Cached-Data: 148-72
Response-Data: 148-142
Step 1: Copy first 148 bytes from the cached copy to the fresh
copy because this is the static part of the page and initialize
the New-Offset variable to 148.
Step 2: Copy the 142 bytes from the response from it 0th position
to its 142nd position and update the New-Offset variable
to 148-142
Step 3: Copy the remaining bytes left in the cached copy to
the fresh copy.
Step 4: Perform the following calculation on Content-Length
Header
Content-Length=148 Bytes (Static Part) 142 Bytes (fresh
information from the response) 25 Bytes (Remained in the
cached to the end of the file, Static part)
Anshul,et al. January 10, 2017 [Page 10]
Internet-Draft Knowledge Based Web Page July 2016
Content-Length of Cached Data=245
Total of Offset header of Cached Data=220 (148+72)
245-220=25 (Remaining Static Part of Cached page)
Step 5: Exit
Input Set 2
Cached Data: 83-718,831-2,843-7
Response Data: 83-600,713-3,726-8
Step 1: Copy 83 bytes from Cached Copy to a fresh Copy and
initialized a tempContentLength Variable to 83.
Step 2: Append 600 bytes from response to the fresh copy and
modify the tempContentLength=600.
Step 3: Append 30 bytes from cache copy to the fresh copy
starting 801th position and modify the tempContentLength=30.
83+718=801
831-801=30 bytes
Step 4: Append 3 bytes from response to the fresh copy and
modify the tempContentLength=3.
Step 5: Append 10 bytes from Cached copy to the fresh copy
and modify the tempContentLength=10.
831+2=833
843-833=10 bytes
Step 6: Append 8 bytes from the response and modify the tempC
ontentLength=8
Step 7: Use the recent Offset header from the last response.
Step 8: Perform the following calculation on Content-Length
Header
Content-Length of Cached Data=864
Total of the last pair of the Offset header of Cached Data=
850 (843+7)
864-850=14 (Remaining Static Part of Cached page)
tempContentLength=14
Step 9: Append 14 bytes of the cached response from the position
843+7 to the end of the file.
Step 10: Content-Length= tempContentLength
Step 11: Exit
Anshul,et al. January 10, 2017 [Page 11]
Internet-Draft Knowledge Based Web Page July 2016
4. Offset Generation
The Offset generation is a duty of a web server. However it is
a difficult to prepare a response message that contains only
changes to the previous message without having a copy of the
delivered message.
To accomplish this task, the web server can make use of a
program that produces the web page. If the program can be modify
in a way that it also output the offsets along with the html
page.
The amendments into the program have to be made at the level
of its parser and synthesize analyzer.
Suppose a parser supports the following grammar
The Grammar (Without Left Factoring)[10]
STMTS -> PRINT TEXT; STMTS |
PRINT GETCOLUMN; STMTS |
WHILE ( CONDITION )
{
STMTS
} STMTS | NULL
CONDITION-> isNextRow | isNextColumn
For a simplicity of implementation of the parser the GETCOLUMN,
isNextRow and isNextColumn work like functions and are going
to be define into the definition of the parser.
The GETCOLUMN will be used to retrieve a column from the data
base and its functionality defines into the parser explicitly
for simplicity.
The isNextRow returns true if there is any row in the recordset
otherwise false and its functionality defines into the parser
explicitly for simplicity.
The isNextColumn returns true if there is any column in the
recordset otherwise false and its functionality defines into the
parser explicitly for simplicity.
Input Program: Source Code
PRINT Simple Test;
PRINT ;
Anshul,et al. January 10, 2017 [Page 12]
Internet-Draft Knowledge Based Web Page July 2016
PRINT ;
PRINT Sr.No | Name | Designation |
Dept |
;
WHILE ( isNextRow )
{
PRINT ;
WHILE ( isNextColumn )
{
PRINT ;
PRINT GETCOLUMN;
PRINT | ;
}
PRINT
;
}
PRINT
;
The first three line and last line of this program produces
static data, the while part contains the dynamic data which
depends on the condition in the while loop.
At the time of parsing, using symbol table the program can
identify the static part and dynamic part. If a PRINT statement
contains the ID (TEXT) which implies that it is a static part
or if a PRINT statement contains the function in this grammar
this would be GETCOLUMN only but for other languages such as
Java Server Pages and Active Server Pages this function can be
any which language supports.
The Evaluator which going to generate Offset for the above
Grammar, can count the length of the static part at instantaneously
and for the dynamic part it can execute that function which
supplied in the PRINT statement and then count the length of
the result of that function. The Evaluator takes two arguments
as it parameter the program and integer variable for calculaing
offset. The Output of the Evaluator is the html page along
with the Offset.
5. Implementation in Java [6][7]
Web Server Code
/*Class WebServer, Accept the incoming request
And handover the request to HTTPProtocol Class
This Server listen incoming request on port 81 Because
all three processes i.e. Cache Server and Client
are on the same machine*/
import java.util.*;
import java.net.*;
import java.io.*;
public class WebServer
{
public static void main(String arg[])
{
ServerSocket requests;
Socket connection;
Runnable r;
Thread t;
try
{
Anshul,et al. January 10, 2017 [Page 13]
Internet-Draft Knowledge Based Web Page July 2016
requests=new ServerSocket(81);
while(true)
{
connection=requests.accept();
r=new HTTPProtocol(connection);
t=new Thread(r);
t.setDaemon(true);
t.start();
}
}
catch(Exception E)
{
System.out.print("Error: "+E);
}
}
}
/*Class HTTPProtocol, read the incoming request
And serve them as described by this draft*/
import java.util.*;
import java.net.*;
import java.io.*;
import javax.swing.*;
import java.text.*;
public class HTTPProtocol implements Runnable
{
Socket con;
InputStream in;
OutputStream out;
HTTPRequest request;
HTTPResponse response;
BufferedInputStream inStream;
int ch=-1;
public HTTPProtocol(Socket con) throws IOException,Exception
{
this.con=con;
in=con.getInputStream();
out=con.getOutputStream();
inStream=new BufferedInputStream(in);
inStream.mark(25);
}
public void run()
{
try{
while((ch=inStream.read())!=-1) //This loop ensure persistent Connection with client
{
inStream.reset();
request=new HTTPRequest(inStream);
System.out.println(request);
if(request.getMethod().equals("GET"))
{
if(request.getQueryString()!=null)
{
Thread t=Thread.currentThread();
Anshul,et al. January 10, 2017 [Page 14]
Internet-Draft Knowledge Based Web Page July 2016
try{
String pageStatus;
if((pageStatus=request.getHeaderValueByName("Content-Status"))==null)
pageStatus="Page";
ClassLoader loader=t.getContextClassLoader();
String fileName=request.getUrl();
Class> cl=loader.loadClass(fileName.substring(0,fileName.indexOf('.')));
String arg[]={request.getQueryString()," "+(request.getQueryString().length())
,""+pageStatus};
(cl.getMethod("main",String[].class)).invoke(null,(Object)arg);
HTTPHeader hdr=
new HTTPHeader("200 OK","Pages/Result.html",
request.getMethod());
response=new HTTPResponse(out,hdr,"Pages/Result.html");
response.sendDynamicData();
}
catch(Exception e)
{
System.out.print("Client Side Error"+e);
}
}
else
if(request.getHeaderValueByName
("If-Modified-Since")!=null)
{
String strDate=request.getHeaderValueByName
("If-Modified-Since");
boolean modified=isModified
(strDate,(new File(request.getUrl())).lastModified());
if(modified)
{
//System.out.println("\n200 OK sending");
HTTPHeader hdr=new HTTPHeader("200 OK",request);
response=new HTTPResponse(out,hdr,request.getUrl());
response.send();
}
else
{
//System.out.println("\n304 sending");
HTTPHeader hdr=new HTTPHeader("304 Not Modified",request);
response=new HTTPResponse(out,hdr);
response.send();
}
}
else
{
HTTPHeader hdr=new HTTPHeader("200 OK",request);
response=new HTTPResponse(out,hdr,request.getUrl());
response.send();
}}
Anshul,et al. January 10, 2017 [Page 15]
Internet-Draft Knowledge Based Web Page July 2016
else if(request.getMethod().equals("POST"))
{
//Request arrived from save.html, update.html
Thread t=Thread.currentThread();
try{
ClassLoader loader=t.getContextClassLoader();
Class> cl=loader.loadClass(request.getUrl());
String arg[]={request.getMessageBody(),request.getContentLength()};
(cl.getMethod("main",String[].class)).invoke(null,(Object)arg);
HTTPHeader hdr=new HTTPHeader("200 OK","Pages/Result.html",request.getMethod());
hdr.setContentLength("Pages/Result.html");
response=new HTTPResponse(out,hdr,"Pages/Result.html");
response.send();
}
catch(Exception e)
{
System.out.print("Client Side Error"+e);
}}
inStream.mark(25);
}
con.close();
}
catch(Exception e)
{
System.out.println("Error in Run Method: "+e+" "+ch);
try{
con.close();
System.out.println("Connection Closed "+request);
}
catch(Exception e1)
{}
}}
public boolean isModified(String strDate, long fileDate) throws Exception
{
DateFormat fmt=new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz");
TimeZone tz=TimeZone.getTimeZone("GMT");
fmt.setTimeZone(tz);
Date lastDate=fmt.parse(strDate);
Date fileModified=fmt.parse(fmt.format(new Date(fileDate)));
return (lastDate.before(fileModified));
}
public String toString()
{
return request.toString(); }}
Anshul,et al. January 10, 2017 [Page 16]
Internet-Draft Knowledge Based Web Page July 2016
/*Class HTTP Response, defines the methods to handle
the response and delivery*/
import java.io.*;
import java.util.*;
public class HTTPResponse
{
PrintWriter out;
HTTPHeader hdr;
String url;
public HTTPResponse(OutputStream out,HTTPHeader hdr,String url)throws IOException, Exception
{
this.out=new PrintWriter(out,true);
this.hdr=hdr;
this.url=url;
}
public HTTPResponse(OutputStream out,HTTPHeader hdr)throws IOException, Exception
{
this.out=new PrintWriter(out,true);
this.hdr=hdr;
this.url=null;
}
public void send()throws IOException,Exception
{
out.write(hdr.getStatusLine());
out.write(hdr.getHeader());
out.write("\r\n");
out.flush();
if(url!=null)
{
FileInputStream file=new FileInputStream(url);
int c=0;
String msg="";
while((c=file.read())!=-1)
{
msg=msg+(char)c;
}
out.write(msg);
file.close();
}
out.flush();
}
Anshul,et al. January 10, 2017 [Page 17]
Internet-Draft Knowledge Based Web Page July 2016
public void sendDynamicData() throws IOException, Exception
{
out.write(hdr.getStatusLine());
System.out.print(hdr.getStatusLine());
out.write(hdr.getHeader());
System.out.print(hdr.getHeader());
if(url!=null)
{
FileInputStream file=new FileInputStream(url);
int c=0;
String msg="";
while((c=file.read())!=-1)
{
msg=msg+(char)c;
}
System.out.print(msg);
out.write(msg);
file.close();
}
out.flush();
}}
Anshul,et al. January 10, 2017 [Page 18]
Internet-Draft Knowledge Based Web Page July 2016
/*Class HTTPRequest, Read incoming request and process*/
import java.util.*;
import java.io.*;
public class HTTPRequest
{
String method;
String url;
String HttpVer;
String mBody;
String queryString="";
BufferedInputStream input;
Map headerList;
public HTTPRequest(BufferedInputStream in)
{
queryString=null;
mBody="";
try
{
input=in;
headerList=new HashMap();
method=readRequestLine();
url=readRequestLine();
setQueryString(url);
HttpVer=readRequestLine();
String header="",value="";
while(!((header=getHeader()).equals("\r\n")))
{
value=getHeaderValue();
headerList.put(header,value);
}
String temp="";
if((temp=headerList.get("Content-Length"))!=null)
{
mBody=readMessageBody(Integer.parseInt(temp.substring(1)));
}
}
catch(Exception e)
{
System.out.println("Error in HttpRequest Class "+e);
}
}
public void setQueryString(String query)
{
if(query.indexOf('?')!=-1)
queryString=query.substring(query.indexOf('?')+1);
}
public String getQueryString()
{
return queryString;
}
Anshul,et al. January 10, 2017 [Page 19]
Internet-Draft Knowledge Based Web Page July 2016
public String readMessageBody(int mLength) throws IOException, Exception
{
String body="";
char ch;
while(mLength>0)
{
ch=(char)input.read();
body=body+ch;
mLength--;
}
return body;
}
public String getHeaderValue() throws Exception, Exception
{
String token=new String();
char ch;
String CRLF="\r\n";
ch=(char)input.read();
while(ch!='\n')
{
if(ch!='\r')
{
token=token+ch;
}
ch=(char)input.read();
}
return token;
}
public String getHeader() throws IOException, Exception
{
String token=new String();
char ch;
String CRLF="\r\n";
ch=(char)input.read();
while((ch!=':') && (ch!='\n'))
{
if(ch!='\r')
{
token=token+ch;
}
else if(token.length()==0)
{
token=CRLF;
}
ch=(char)input.read();
}
return token;
}
Anshul,et al. January 10, 2017 [Page 20]
Internet-Draft Knowledge Based Web Page July 2016
public String readRequestLine() throws IOException, Exception
{
String token=new String();
char ch;
String CRLF="\r\n";
ch=(char)input.read();
while((ch!=' ') && (ch!='\n'))
{
if(ch!='\r')
{
token=token+ch;
}
else if(token.length()==0)
{
token=CRLF;
}
ch=(char)input.read();
}
return token;
}
public String getMethod()
{
return method;
}
public String getUrl()
{
if(url.equals("/"))
return "welcome.html";
else
{
if(url.startsWith("/"))
{
if(url.indexOf('?')==-1)
{
int i=url.indexOf('/');
url=url.substring(i+1);
}
else
{
url=url.substring(1,url.indexOf('?'));
}
}
return url;
}
}
public String getHTTPVersion()
{
return HttpVer;
}
Anshul,et al. January 10, 2017 [Page 21]
Internet-Draft Knowledge Based Web Page July 2016
public String getMessageBody()
{
return mBody;
}
public String getContentLength()
{
return headerList.get("Content-Length");
}
public String getHeaderValueByName(String hName)
{
String temp=headerList.get(hName);
if(temp!=null)
return temp.substring(1);
else
return temp;
}
public String toString()
{
String headers="";
for(Map.Entry entry: headerList.entrySet())
{
String key=entry.getKey();
String value=entry.getValue();
headers+=key+": "+value+"\r\n";
}
return "HTTPRequest [ "+method+" "+url+" "+HttpVer+" ]\r\n"+headers;
}}
/*Class HTTP Header, assist the HTTPResponse class and HTTPRequest Class*/
import java.util.*;
import java.io.*;
import java.text.*;
public class HTTPHeader
{
String statusLine;
List hdr;
static Map mimeType;
String CRLF="\r\n";
public HTTPHeader(String statusCode,HTTPRequest request) throws IOException, Exception
{
statusLine=request.getHTTPVersion()+" "+statusCode+CRLF;
hdr=new LinkedList();
Date d=new Date();
DateFormat fmt=new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz");
TimeZone tz=TimeZone.getTimeZone("GMT");
fmt.setTimeZone(tz);
setHeader("Date",fmt.format(d));
// Setting Expire Header Field's Value
d.setTime(d.getTime()+120*60*1000);
setHeader("Expires",fmt.format(d));
Anshul,et al. January 10, 2017 [Page ]
Internet-Draft Knowledge Based Web Page June55
if(statusCode.startsWith("200"))
{
mimeType=new HashMap();
mimeType.put("html","text/html");
mimeType.put("htm","text/htm");
int i=request.getUrl().lastIndexOf('.'); /*This code is setting the content type of the response*/
String ext=request.getUrl().substring(i+1);
ext=getMimeType(ext);
if(ext!=null)
setHeader("Content-Type",ext);
setContentLength(request.getUrl());
}
if(statusCode.startsWith("200") || statusCode.startsWith("304"))
{
File f=new File(request.getUrl());
if(f.exists())
{
d.setTime(f.lastModified());
setHeader("Last-Modified",fmt.format(d));
}
}
if(request.getHTTPVersion().equals("HTTP/1.1"))
setHeader("Connection","keep-alive");
else
setHeader("Connection","close");
}
//Sending Daynamic pages using this constructor
public HTTPHeader(String statusCode,String url,String method) throws Exception
{
statusLine="HTTP/1.1 "+statusCode+CRLF;
hdr=new LinkedList();
mimeType=new HashMap();
mimeType.put("html","text/html");
mimeType.put("htm","text/htm");
Date d=new Date();
DateFormat fmt=new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz");
TimeZone tz=TimeZone.getTimeZone("GMT");
fmt.setTimeZone(tz);
setHeader("Date",fmt.format(d));
if(method.equals("GET"))
{
setHeader("Cache-Control","must-revalidate");
}
setHeader("Content-Type",mimeType.get("html"));
setHeader("Connection","keep-alive");
}
Anshul,et al. January 10, 2017 [Page 22]
Internet-Draft Knowledge Based Web Page July 2016
public HTTPHeader(String statusLine) throws IOException, Exception
{
this.statusLine=statusLine;
}
public String getMimeType(String ext)
{
return mimeType.get(ext);
}
public String getStatusLine()
{
return statusLine;
}
public void setContentLength(String url) throws IOException, Exception
{
File f;
try{
f=new File(url);
}
catch(Exception e)
{
f=new File("welcome.html");
}
hdr.add("Content-Length: "+f.length()+CRLF);
}
public void setHeader(String hdrName,String hdrValue)
{
hdr.add(hdrName+": "+hdrValue+CRLF);
}
public String getHeader()
{
Iterator itr=hdr.iterator();
String hdrs="";
while(itr.hasNext())
{
hdrs=hdrs+itr.next();
}
return hdrs;
}}
Anshul,et al. January 10, 2017 [Page 23]
Internet-Draft Knowledge Based Web Page July 2016
/*Class MsgBody, Read the message body of POST Method*/
public class MsgBody
{
String str;
int length;
public MsgBody(String body, int length)
{
str=body;
this.length=length;
}
public int getLength()
{
return length;
}
public String getParameter(String pName)
{
String temp;
temp=str.substring(str.indexOf(pName)+pName.length()+1);
int L=(str.indexOf(pName)+pName.length()+1);
if(temp.indexOf("&")==-1)
L=L+temp.length();
if(L==length)
{
if(temp.length()!=0)
{
int idx=0;
String result="";
while(idx executeSearchQuery(String query)
{
HashMap rs=new HashMap();
try
{
ResultSet result=s.executeQuery(query);
int total=1;
int idx=1;
String row="",temp="";
String header="ID+FIRST_NAME+MIDDLE_NAME+LAST_NAME+DOB+GENDER+MOBILE_NO+APPOINT_ODR_NO+APPOINT_DIS_NO+APPOINT_DATE+JOIN_DATE+FILE_NO+POST+STATUS";
while(result.next())
{
idx=1;
row="";
while(idx<15)
{
temp=result.getString(idx);
if(temp!=null)
{
row+=temp+"+";
}
else
row+="NotExist"+"+";
idx++;
}
rs.put(""+total,row);
total++;
}
rs.put("0",header);
total--;
rs.put("Total",""+total);
result.close();
return rs;
}
catch(Exception e)
{
rs.put("Failed","-1");
return rs;
}
}
public String toString()
{
return "DBAccess ["+conn+" "+s+" "+database+" ]";
}
}
Anshul,et al. January 10, 2017 [Page 30]
Internet-Draft Knowledge Based Web Page July 2016
/*Class Tag, defines Tag of the Grammer in section 4*/
public class Tag
{
public static final int Num=256,ID=257,TEXT=258,DTEXT=259,WHILE=260,OPENBRAKET=261,CLOSEDBRAKET=262,SEMICOLON=263,OPENCURLYBRAKET=264,CLOSEDCURLYBRAKET=265,ISNEXTROW=266,ISNEXTCOLUMN=267, PRINT=268,EMPTYSTMT=269,UNKNOWN=270;
}
/*Class Token, defines Token of the Grammer in Section 4*/
public class Token
{
public int tag;
public Token(int t)
{
tag=t;
}
public String toString()
{
return ""+tag;
}
}
/*Class HtmlString, define static part of page*/
public class HtmlString extends Token
{
public String lexeme;
public HtmlString(int tag, String str)
{
super(tag);
lexeme=str;
}
public String toString()
{
return "String: "+lexeme;
}
}
Anshul,et al. January 10, 2017 [Page 31]
Internet-Draft Knowledge Based Web Page July 2016
/*Class Statement, define statements of grammer in section 4*/
public class Statement
{
public Token token;
private Statement nextStmt;
public static Statement EmptyStmt=new Statement(new Token(Tag.EMPTYSTMT));
public Statement(Token t)
{
token=t;
nextStmt=null;
}
public Statement(Token t, Statement stmt)
{
token=t;
nextStmt=stmt;
}
public void setNextStmt(Statement stmt)
{
nextStmt=stmt;
}
public Statement getNextStmt()
{
return nextStmt;
}
public Token getToken()
{
return token;
}
}
/*Class Text, define Text Statements of grammer section 4*/
public class Text extends Statement
{
private int length,offset,total;
public Text(HtmlString html)
{
super(html);
length=html.lexeme.length();
offset=0;
total=0;
}
public Text(HtmlString html,Statement stmt)
{
super(html,stmt);
length=0;
offset=0;
total=0;
}
Anshul,et al. January 10, 2017 [Page 32]
Internet-Draft Knowledge Based Web Page July 2016
public void setLength(int len)
{
length=len;
}
public void setOffset(int offset)
{
this.offset=offset;
}
public void setTotal()
{
total=length+offset;
}
public int getTotal()
{
return total;
}
}
/*Class OutputStatement, define Output Statements such as PRINT of grammer section 4*/
public class OutputStatement extends Statement
{
private String lexeme;
public OutputStatement(Word w,Statement stmt)
{
super(w,stmt);
lexeme=w.lexeme;
}
public String getLexeme()
{
return lexeme;
}
}
/*Class Word, define word of a lexeme for grammer in section 4*/
public class Word extends Token
{
public final String lexeme;
public Word(String lexeme, int t)
{
super(t);
this.lexeme=lexeme;
}
public String toString()
{
return "Word [ Lexeme "+lexeme+" Tag "+super.toString()+" ]";
}
}
Anshul,et al. January 10, 2017 [Page 33]
Internet-Draft Knowledge Based Web Page July 2016
/*Class While, define while statements of grammer section 4*/
public class While extends Statement
{
private Statement body;
private int length,offset,total;
private Condition con;
public While(Word w)
{
super(w);
length=0;
offset=0;
total=0;
}
public void setBody(Statement stmt)
{
body=stmt;
}
public void setNextStmt(Statement stmt)
{
super.setNextStmt(stmt);
}
public void setCondition(Condition con)
{
this.con=con;
}
public void setLength(int len)
{
length=len;
}
public void setOffset(int offset)
{
this.offset=offset;
}
public void setTotal()
{
total=length+offset;
}
public int getTotal()
{
return total;
}
public Condition getCondition()
{
return con;
}
public Statement getBody()
{
return body;
}
}
Anshul,et al. January 10, 2017 [Page 34]
Internet-Draft Knowledge Based Web Page July 2016
/*Class DText, Define Dynamic data of a page*/
public class DText extends Statement
{
private int length,offset,total;
public DText(Word w)
{
super(w);
length=0;
offset=0;
total=0;
}
public DText(Word w,Statement stmt)
{
super(w,stmt);
length=0;
offset=0;
total=0;
}
public void setLength(int len)
{
length=len;
}
public void setOffset(int offset)
{
this.offset=offset;
}
public void setTotal()
{
total=length+offset;
}
public int getTotal()
{
return total;
}
}
/*Class Condition, define Condition statement of grammer saction 4*/
public class Condition
{
private Token token;
public Condition(Word w)
{
token=(Token)w;
}
public boolean evaluate(Evaluator eval)
{
if(token.tag==Tag.ISNEXTROW)
{
return eval.isNextRow();
}
else
{
return eval.isNextColumn();
}
}
Anshul,et al. January 10, 2017 [Page 35]
Internet-Draft Knowledge Based Web Page July 2016
public Token getToken()
{
return token;
}
}
/*Class Lexer, Define Lexical Analyzer of grammer section 4*/
import java.io.*;
import java.util.*;
public class Lexer
{
public char peek=' ';
public Map table;
FileInputStream in;
public Lexer(FileInputStream file) throws Exception
{
table=new HashMap();
reserve(new Word("PRINT", Tag.PRINT));
reserve(new Word("WHILE",Tag.WHILE));
reserve(new Word("isNextRow",Tag.ISNEXTROW));
reserve(new Word("isNextColumn",Tag.ISNEXTCOLUMN));
reserve(new Word("getNextColumn",Tag.DTEXT));
in=file;
}
public void reserve(Word w)
{
table.put(w.lexeme,w);
}
public Token scan() throws IOException
{
for(;peek==' ' || peek=='\t'|| peek=='\n'|| peek=='\r';peek=(char)in.read()){}
if(peek=='"')
{
String text;
StringBuffer buf=new StringBuffer();
peek=(char)in.read();
do
{
buf.append(peek);
peek=(char)in.read();
if(peek=='\\')
{
peek=(char)in.read();
buf.append(peek);
peek=(char)in.read();
}
}while(peek!='"');
Anshul,et al. January 10, 2017 [Page 36]
Internet-Draft Knowledge Based Web Page July 2016
peek=' ';
text=buf.toString();
return new HtmlString(Tag.TEXT,text);
}
else if(Character.isLetter(peek))
{
StringBuffer buf=new StringBuffer();
do
{
buf.append(peek);
peek=(char)in.read();
}while(Character.isLetterOrDigit(peek));
String str=buf.toString();
Word w=table.get(str);
if(w!=null) return w;
w=new Word(str,Tag.ID);
table.put(str,w);
return w;
}
else
{
Token t;
if(peek=='(')
{
t=new Token(Tag.OPENBRAKET);
}
else if(peek==')')
{
t=new Token(Tag.CLOSEDBRAKET);
}
else if(peek=='{')
{
t=new Token(Tag.OPENCURLYBRAKET);
}
else if(peek=='}')
{
t=new Token(Tag.CLOSEDCURLYBRAKET);
}
else if(peek==';')
{
t=new Token(Tag.SEMICOLON);
}
else
{
t=new Token(Tag.UNKNOWN);
}
peek=' ';
return t;
}
}
}
Anshul,et al. January 10, 2017 [Page 37]
Internet-Draft Knowledge Based Web Page July 2016
/*Class Parser, Define Predictive Parser for grammer in section 4*/
import java.io.*;
public class Parser
{
private Token look;
private Lexer lex;
public Parser(String filename) throws Exception
{
lex=new Lexer(new FileInputStream(filename));
}
Statement Stmts() throws Exception
{
Statement stmt;
look=move();
switch(look.tag)
{
case Tag.PRINT:
stmt=new OutputStatement((Word)look,rest());
break;
case Tag.WHILE:
While loop=new While((Word)look);
look=move();
match(Tag.OPENBRAKET);
look=move();
Condition con=new Condition((Word)look);
loop.setCondition(con);
look=move();
match(Tag.CLOSEDBRAKET);
look=move();
match(Tag.OPENCURLYBRAKET);
loop.setBody(Stmts());
//System.out.println(look.tag);
match(Tag.CLOSEDCURLYBRAKET);
loop.setNextStmt(Stmts());
stmt=loop;
break;
default:
stmt=Statement.EmptyStmt;
}
return stmt;
}
Anshul,et al. January 10, 2017 [Page 38]
Internet-Draft Knowledge Based Web Page July 2016
Statement rest() throws Exception
{
Statement stmt;
look=move();
switch(look.tag)
{
case Tag.TEXT:
stmt=new Text((HtmlString)look);
look=move();
match(Tag.SEMICOLON);
stmt.setNextStmt(Stmts());
break;
case Tag.DTEXT:
stmt=new DText((Word)look);
look=move();
match(Tag.SEMICOLON);
stmt.setNextStmt(Stmts());
break;
default:
System.out.println("Syntax Error at rest");
stmt=null;
}
return stmt;
}
public void match(int tag)
{
if(look.tag!=tag)
{
System.out.println("Syntax Error "+look.tag+": "+tag);
Word w=(Word)look;
System.out.println(w.lexeme);
}
}
public Token move() throws IOException
{
return lex.scan();
}
public static void printPrg(Statement stmt)
{
if(stmt!=null){
if(stmt instanceof OutputStatement)
{
OutputStatement out=(OutputStatement)stmt;
System.out.print(out.getLexeme());
}
else if(stmt instanceof Text)
{
Text text=(Text)stmt;
HtmlString html=(HtmlString)text.getToken();
System.out.println(html.lexeme+";");
}
Anshul,et al. January 10, 2017 [Page 39]
Internet-Draft Knowledge Based Web Page July 2016
else if(stmt instanceof DText)
{
DText text=(DText)stmt;
Word w=(Word)text.getToken();
System.out.println(w.lexeme+";");
}
else if(stmt instanceof While)
{
While loop=(While)stmt;
System.out.print("while ( ");
Condition con=loop.getCondition();
if(con!=null)
{
if(con.getToken().tag==Tag.ISNEXTROW)
System.out.print("isNextRow ) {");
else
System.out.print("isNextColumn ) {");
}
else
System.out.print("con null");
printPrg(loop.getBody());
System.out.println("}");
}
printPrg(stmt.getNextStmt());
}
}
public void initEvaluator(String query,boolean full)
{
try
{
Statement stmt=Stmts();
Evaluator eval=new Evaluator(stmt,0,query,full);
int len=eval.executeProgram();
}
catch(Exception e)
{
System.out.println("Error in Evaluator "+e);
}
}
}
Anshul,et al. January 10, 2017 [Page 40]
Internet-Draft Knowledge Based Web Page July 2016
/*Class Evaluator, Define a simple compiler for grammer in section 4
It produces html page along with Offset in output.eval file*/
import java.util.*;
import java.io.*;
public class Evaluator
{
private int offset=0;
private Statement stmts;
private int length=0;
private String query;
private DBAccess db;
private HashMap rs;
private int totalrow=0, currow=0;
private StringTokenizer strToken;
private String finalOffset="";
private boolean full;
private String output;
public Evaluator(Statement stmts, int offset,String qry,boolean bool)
{
this.offset=0;
this.stmts=stmts;
length=0;
full=bool;
output=new String();
query=qry;
db=new DBAccess();
rs=db.executeSearchQuery(query);
currow=0;
totalrow=Integer.parseInt(rs.get("Total"));
}
public int executeProgram()
{
length=Evaluate(stmts,offset,full);
finalOffset=finalOffset.substring(0,finalOffset.lastIndexOf(','))+"\r\n\r\n";
try{
FileOutputStream fout=new FileOutputStream("Pages/Result.html");
byte header[]=("Content-Length: "+output.length()+"\r\nOffset: "+finalOffset).getBytes();
fout.write(header);
fout.write(output.getBytes());
fout.close();
}
catch(Exception e)
{
System.out.println("Erro During writing output of Evaluator "+e);
}
return length;
}
Anshul,et al. January 10, 2017 [Page 41]
Internet-Draft Knowledge Based Web Page July 2016
private int Evaluate(Statement stmts, int offset,boolean full)
{
int tempResult=0;
switch(stmts.token.tag)
{
case Tag.PRINT:
OutputStatement out=(OutputStatement)stmts;
Statement st=out.getNextStmt();
if(st.token.tag==Tag.TEXT)
{
Text text=(Text)st;
text.setOffset(offset);
HtmlString html=(HtmlString)text.token;
text.setLength(html.lexeme.length());
text.setTotal();
if(full)
output+=html.lexeme;
tempResult= Evaluate(st.getNextStmt(),text.getTotal(),full);
}
else
{
String str=getNextColum();
DText text=(DText)st;
text.setLength(str.length());
text.setOffset(offset);
text.setTotal();
output+=str;
finalOffset+=offset+"-"+str.length()+",";
tempResult=Evaluate(st.getNextStmt(),text.getTotal(),full);
}
break;
case Tag.WHILE:
String tempFinalOffset=finalOffset;
int OFFSET=offset;
int tempOffset=offset;
While wl=(While)stmts;
Condition con=wl.getCondition();
Statement body=wl.getBody();
wl.setOffset(offset);
wl.setTotal();
while(con.evaluate(this))
{
offset=Evaluate(body,wl.getTotal(),true);
wl.setLength(0);
wl.setOffset(offset);
wl.setTotal();
}
finalOffset=tempFinalOffset+OFFSET+"-"+(offset-tempOffset)+",";
tempResult=Evaluate(stmts.getNextStmt(),wl.getTotal(),full);
break;
case Tag.EMPTYSTMT:
tempResult=offset;
}
Anshul,et al. January 10, 2017 [Page 42]
Internet-Draft Knowledge Based Web Page July 2016
Proxy Server Code:
/*Class ProxyServer, Define Caching Proxy Server*/
import java.util.*;
import java.net.*;
import java.io.*;
public class ProxyServer
{
public static void main(String arg[])
{
ServerSocket requests;
Socket connection;
Runnable r;
Thread t;
try
{
requests=new ServerSocket(80);
while(true)
{
connection=requests.accept();
r=new HTTPProtocol(connection);
t=new Thread(r);
t.setDaemon(true);
t.start();
}
}
catch(Exception E)
{
System.out.print("Error: "+E);
}
}
}
Anshul,et al. January 10, 2017 [Page 43]
Internet-Draft Knowledge Based Web Page July 2016
Proxy Server Code:
/*Class ProxyServer, Define Caching Proxy Server*/
import java.util.*;
import java.net.*;
import java.io.*;
public class ProxyServer
{
public static void main(String arg[])
{
ServerSocket requests;
Socket connection;
Runnable r;
Thread t;
try
{
requests=new ServerSocket(80);
while(true)
{
connection=requests.accept();
r=new HTTPProtocol(connection);
t=new Thread(r);
t.setDaemon(true);
t.start();
}
}
catch(Exception E)
{
System.out.print("Error: "+E);
}
}
}
Anshul,et al. January 10, 2017 [Page 44]
Internet-Draft Knowledge Based Web Page July 2016
/*Class HTTPProtocol, HTTP protocol for Proxy Server with
Dynamic page caching facility*/
import java.util.*;
import java.net.*;
import java.io.*;
import java.text.*;
public class HTTPProtocol implements Runnable
{
Socket con,serCon;
InputStream in,serIn;
OutputStream out,serOut;
BufferedInputStream inStream,serInStream;
PrintWriter serOutStream,clientOut;
HTTPRequest request;
int ch=-1;
public HTTPProtocol(Socket con) throws IOException,Exception
{
this.con=con;
in=con.getInputStream();
out=con.getOutputStream();
clientOut=new PrintWriter(out,true);
inStream=new BufferedInputStream(in);
inStream.mark(25);
}
public void run()
{
try
{
try
{
while((ch=inStream.read())!=-1) //This loop ensure persistent Connection with client
{
inStream.reset();
request=new HTTPRequest(inStream);
if(request.getMethod().equals("POST"))
{
/* If request is made by POST method then the response would not be cached until it is specified in this case proxy behaves like a tunnel that means do not make any changes in either request or response*/
serCon=new Socket("127.0.0.1",81);
serIn=serCon.getInputStream();
serOut=serCon.getOutputStream();
serInStream=new BufferedInputStream(serIn);
serOutStream=new PrintWriter(serOut,true);
Anshul,et al. January 10, 2017 [Page 45]
Internet-Draft Knowledge Based Web Page July 2016
serOutStream.write(request.getRequestHeader());
serOutStream.flush();
HTTPResponse response=new HTTPResponse(serInStream);
response.send(clientOut);
}
else
{
File cacheEntry=new File("Cache/"+request.getHeaderValueByName("Host")+"/"+request.getUrl()+"/"+getFileName(request.getUrl()));
if(cacheEntry.exists())
{
Scanner readCacheEntry=new Scanner(cacheEntry);
if(readCacheEntry.hasNext())
{
System.out.println("\nLooking cache entry");
String line=readCacheEntry.nextLine();
while(!(line.startsWith("Expires")) && !(line.endsWith("must-revalidate")) && readCacheEntry.hasNext())
line=readCacheEntry.nextLine();
if(line.startsWith("Expires"))
{
String strDate=line.substring(line.indexOf(':')+2);
TimeZone tz=TimeZone.getTimeZone("GMT");
SimpleDateFormat sdf=new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz");
sdf.setTimeZone(tz);
Date expireDate=sdf.parse(strDate);
System.out.println("Expiry date : "+strDate);
Date now=new Date();
String curTime=sdf.format(now);
now=sdf.parse(curTime);
System.out.println("cur date : "+curTime);
if(now.before(expireDate))
{
/*Cache entry is valid send output from cache*/
System.out.println("\nCache Entry Valid");
HTTPResponse response=new HTTPResponse(new FileInputStream(cacheEntry));
response.send(clientOut);
}
Anshul,et al. January 10, 2017 [Page 46]
Internet-Draft Knowledge Based Web Page July 2016
else
{
/*if Cache entry is stale*/
System.out.println("\nCache Entry Stale");
serCon=new Socket("127.0.0.1",81);
serIn=serCon.getInputStream();
serOut=serCon.getOutputStream();
serInStream=new BufferedInputStream(serIn);
serOutStream=new PrintWriter(serOut,true);
while(!(line.startsWith("Last-Modified")) && readCacheEntry.hasNext())
line=readCacheEntry.nextLine();
String lastDate=line.substring(line.indexOf(':')+2);
serOutStream.write(request.conditionalGetRequest(lastDate));
serOutStream.flush();
HTTPResponse response=new HTTPResponse(serInStream);
if(response.getStatusCode().equals("304"))
{
System.out.println("\nUpdating Cache Entry");
String replaceBy=response.getHeaderByName("Expires");
Scanner scan=new Scanner(cacheEntry);
String curLine;
int skip=0;
while(!( (curLine=scan.nextLine()).startsWith("Expires:") ))
{
skip=skip+curLine.length()+2;
}
RandomAccessFile updateEntry=new RandomAccessFile(cacheEntry,"rw");
updateEntry.seek(skip);
updateEntry.write(replaceBy.getBytes());
response.send(clientOut,cacheEntry);
scan.close();
updateEntry.close();
}
else
{
/*Override on stale entry i.e. 200 OK return*/
System.out.println("\nOverride Previous Entry");
response.sendAndSave(clientOut,cacheEntry);
}}}
else if(line.endsWith("must-revalidate"))
{
serCon=new Socket("127.0.0.1",81);
serIn=serCon.getInputStream();
serOut=serCon.getOutputStream();
serInStream=new BufferedInputStream(serIn);
serOutStream=new PrintWriter(serOut,true);
serOutStream.write(setContentStatusHeader(request.getRequestHeader()));
Anshul,et al. January 10, 2017 [Page 47]
Internet-Draft Knowledge Based Web Page July 2016
serOutStream.flush();
//Reading WebServer Response
HTTPResponse response=new HTTPResponse(serInStream);
/*Here the code of dynamic updating cache will be add*/
UpdateDynamicCacheFiles udcf=new UpdateDynamicCacheFiles(cacheEntry,response);
udcf.buildPage();
response.sendAndSave(clientOut,cacheEntry,udcf.toString());
}}
else
{
/*if there is any error during reading cache entry*/
serCon=new Socket("127.0.0.1",81);
serIn=serCon.getInputStream();
serOut=serCon.getOutputStream();
serInStream=new BufferedInputStream(serIn);
serOutStream=new PrintWriter(serOut,true);
serOutStream.write(request.getRequestHeader());
serOutStream.flush();
HTTPResponse response=new HTTPResponse(serInStream);
response.sendAndSave(clientOut,cacheEntry);
}}
else
{
/*if cache entry does not exists*/
System.out.println("\nCache Entry not Exists");
serCon=new Socket("127.0.0.1",81);
serIn=serCon.getInputStream();
serOut=serCon.getOutputStream();
serInStream=new BufferedInputStream(serIn);
serOutStream=new PrintWriter(serOut,true);
serOutStream.write(request.getRequestHeader());
serOutStream.flush();
HTTPResponse response=new HTTPResponse(serInStream);
response.sendAndSave(clientOut,cacheEntry);
}}
inStream.mark(10);
}}
finally
{
con.close();
serCon.close();
}}
catch(Exception pe)
{
System.out.println("Error at Proxy Server :"+pe);
}}
Anshul,et al. January 10, 2017 [Page 48]
Internet-Draft Knowledge Based Web Page July 2016
public String getFileName(String path)
{
// Pages/xxx.html
int i=path.lastIndexOf('/');
if(i!=-1)
return path.substring(i+1);
else
return path;
}
public String setContentStatusHeader(String str)
{
StringBuffer buff=new StringBuffer();
int i=0;
while(str.charAt(i)!='\r')
{
buff.append(str.charAt(i));
i++;
}
i+=2;
buff.append("\r\n");
buff.append("Content-Status: Data\r\n");
int len=str.length();
while(i headerList;
public HTTPRequest(BufferedInputStream in)
{
queryString=null;
mBody="";
try
{
input=in;
headerList=new HashMap();
method=readRequestLine();
url=readRequestLine();
setQueryString(url);
HttpVer=readRequestLine();
String header="",value="";
while(!((header=getHeader()).equals("\r\n")))
{
value=getHeaderValue();
if(!(header.equals("If-Modified-Since")))
{
headerList.put(header,value);
}
}
String temp="";
if((temp=headerList.get("Content-Length"))!=null)
{
mBody=readMessageBody(Integer.parseInt(temp.substring(1)));
}
}
catch(Exception e)
{
System.out.println("Error in HttpRequest Class "+e);
}
Anshul,et al. January 10, 2017 [Page 50]
Internet-Draft Knowledge Based Web Page July 2016
}
public String getHeaderValueByName(String name)
{
return headerList.get(name).substring(1);
}
public String getRequestHeader()
{
String header=method+" "+url;
header=header+" "+HttpVer+"\r\n";
for(Map.Entry entry : headerList.entrySet())
{
header=header+entry.getKey()+":"+entry.getValue()+"\r\n";
}
header=header+"\r\n";
String temp="";
if((temp=headerList.get("Content-Length"))!=null)
{
header+=getMessageBody();
}
return header;
}
public String conditionalGetRequest(String lastModifiedDate)
{
String header=method+" "+url;
header=header+" "+HttpVer+"\r\n";
for(Map.Entry entry : headerList.entrySet())
{
header=header+entry.getKey()+":"+entry.getValue()+"\r\n";
}
header+="If-Modified-Since: "+lastModifiedDate+"\r\n";
header=header+"\r\n";
String temp="";
if((temp=headerList.get("Content-Length"))!=null)
{
header+=getMessageBody();
}
return header;
}
public void setQueryString(String query)
{
if(query.indexOf('?')!=-1)
queryString=query.substring(query.indexOf('?')+1);
}
Anshul,et al. January 10, 2017 [Page 51]
Internet-Draft Knowledge Based Web Page July 2016
public String getQueryString()
{
return queryString;
}
public String readMessageBody(int mLength) throws IOException, Exception
{
String body="";
char ch;
while(mLength>0)
{
ch=(char)input.read();
body=body+ch;
mLength--;
}
return body;
}
public String getHeaderValue() throws Exception, Exception
{
String token=new String();
char ch;
String CRLF="\r\n";
ch=(char)input.read();
while(ch!='\n')
{
if(ch!='\r')
{
token=token+ch;
}
ch=(char)input.read();
}
return token;
}
public String getHeader() throws IOException, Exception
{
String token=new String();
char ch;
String CRLF="\r\n";
ch=(char)input.read();
while((ch!=':') && (ch!='\n'))
{
if(ch!='\r')
{
token=token+ch;
}
else if(token.length()==0)
{
token=CRLF;
}
ch=(char)input.read();
}
Anshul,et al. January 10, 2017 [Page 52]
Internet-Draft Knowledge Based Web Page July 2016
return token;
}
public String readRequestLine() throws IOException, Exception
{
String token=new String();
char ch;
String CRLF="\r\n";
ch=(char)input.read();
while((ch!=' ') && (ch!='\n'))
{
if(ch!='\r')
{
token=token+ch;
}
else if(token.length()==0)
{
token=CRLF;
}
ch=(char)input.read();
}
return token;
}
public String getMethod()
{
return method;
}
public String getUrl()
{
String url="";
url=this.url;
if(url.equals("/"))
return "welcome.html";
else
{
if(url.startsWith("/"))
{
if(url.indexOf('?')==-1)
{
int i=url.indexOf('/');
url=url.substring(i+1);
}
else
{
url=url.substring(1,url.indexOf('?'));
}
}
return url;
}
}
Anshul,et al. January 10, 2017 [Page 53]
Internet-Draft Knowledge Based Web Page July 2016
public String getHTTPVersion()
{
return HttpVer;
}
public String getMessageBody()
{
return mBody;
}
public String getContentLength()
{
return headerList.get("Content-Length");
}
public String toString()
{
return "HTTPRequest [ "+method+" "+url+" "+HttpVer+" ] ";
}
}
/*Class HTTPResponse, Provide method for response messages at proxy server*/
import java.io.*;
import java.util.*;
/*This class read the server response from serInStream
and direct the output to the client*/
public class HTTPResponse
{
BufferedInputStream serResponse;
String response;
String HttpVer,StatusCode,Phrase;
int length;
String headerList; //holds the header part of the response
public HTTPResponse(InputStream in)throws IOException, Exception
{
serResponse=new BufferedInputStream(in);
length=0;
response=readResponseMsg()+"\r\n";
Scanner scan=new Scanner(response);
HttpVer=scan.next();
StatusCode=scan.next();
Phrase=scan.nextLine();
String header="";
while(!( (header=readResponseMsg()).equals("\r\n")))
{
if(header.startsWith("Content-Length"))
{
int i=header.indexOf(':');
String temp=header.substring(i+2);
length=Integer.parseInt(temp);
}
response=response+header+"\r\n";
}
Anshul,et al. January 10, 2017 [Page 54]
Internet-Draft Knowledge Based Web Page July 2016
response+=header;
headerList=response;
if(length!=0)
{
response+=readMsgBody();
}
}
public String readResponseMsg() throws IOException, Exception
{
String token="",CRLF="\r\n";
char ch;
while((ch=(char)serResponse.read())!='\n')
{
if(ch!='\r')
{
token=token+ch;
}
else if(token.length()==0)
{
token=CRLF;
}
}
return token;
}
public String readMsgBody() throws IOException, Exception
{
String mBody="";
char ch;
while(length>0)
{
ch=(char)serResponse.read();
mBody=mBody+ch;
length--;
}
return mBody;
}
public String readMsgBody(String response) throws IOException, Exception
{
String mBody="",temp="";
Scanner scan=new Scanner(response);
while(scan.hasNext())
{
temp=scan.nextLine();
if(temp.length()==0)
break;
}
Anshul,et al. January 10, 2017 [Page 55]
Internet-Draft Knowledge Based Web Page July 2016
while(scan.hasNext())
mBody+=scan.nextLine();
return mBody;
}
public void send(PrintWriter out)throws IOException,Exception
{
int idx=response.indexOf("Expires");
if(idx!=-1)
{
String output=response.substring(0,idx);
out.write(output);
out.write("Cache-Control: no-cache\r\n");
//System.out.print(output);
output=response.substring(response.indexOf("Expires"));
output=output.substring(output.indexOf("\r\n")+2);
out.write(output);
//System.out.print(output);
}
else
out.write(response);
out.flush();
}
public void send(PrintWriter out, File file)throws IOException,Exception
{
Scanner scan=new Scanner(file);
String line;
while(scan.hasNext())
{
line=scan.nextLine()+"\r\n";
if(line.startsWith("Expires"))
line="Cache-Control: no-cache\r\n";
out.write(line);
out.flush();
}
scan.close();
out.flush();
}
public void sendAndSave(PrintWriter out,File file)throws Exception
{
if(file.exists())
{
PrintWriter cache=new PrintWriter(new FileOutputStream(file));
cache.write(response);
cache.flush();
}
Anshul,et al. January 10, 2017 [Page 56]
Internet-Draft Knowledge Based Web Page July 2016
else if((new File(file.getParent())).mkdirs())
{
PrintWriter cache=new PrintWriter(new FileOutputStream(file));
cache.write(response);
cache.flush();
}
else
System.out.println("Failed to make cahche entry");
int idx=response.indexOf("Expires");
if(idx!=-1)
{
String output=response.substring(0,idx);
out.write(output);
out.write("Cache-Control: no-cache\r\n");
//System.out.print(output);
output=response.substring(response.indexOf("Expires"));
output=output.substring(output.indexOf("\r\n")+2);
out.write(output);
System.out.print(output);
}
else
out.write(response);
out.flush();
}
public void sendAndSave(PrintWriter out,File file,String page)throws Exception
{
if(file.exists())
{
FileWriter cache=new FileWriter(file);
cache.write(page);
cache.flush();
}
else if((new File(file.getParent())).mkdirs())
{
FileWriter cache=new FileWriter(file);
cache.write(page);
cache.flush();
}
else
System.out.println("Failed to make cahche entry");
Anshul,et al. January 10, 2017 [Page 57]
Internet-Draft Knowledge Based Web Page July 2016
int idx=response.indexOf("Expires");
if(idx!=-1)
{
String output=response.substring(0,idx);
out.write(output);
out.write("Cache-Control: no-cache\r\n");
//System.out.print(output);
output=response.substring(response.indexOf("Expires"));
output=output.substring(output.indexOf("\r\n")+2);
out.write(output);
System.out.print(output);
}
else
out.write(response);
out.flush();
}
public String getHeaderByName(String aName)
{
String temp=response;
temp=temp.substring(temp.indexOf(aName));
temp=temp.substring(0,temp.indexOf("\r\n"));
return temp;
}
public String getHeaderList()
{
return headerList;
}
public String getHttpVersion()
{
return HttpVer;
}
public String getStatusCode()
{
return StatusCode;
}
public String getPhrase()
{
return Phrase;
}
public void printServer()
{
System.out.println("Get response from server\n"+response);
}
public String toString()
{
return response;
}
}
Anshul,et al. January 10, 2017 [Page 58]
Internet-Draft Knowledge Based Web Page July 2016
/*Class UpdateDynamicCacheFiles, provide algorithm which build the fresh copy page with dynamic data from response and static data from cache*/
import java.io.*;
import java.util.*;
class UpdateDynamicCacheFiles
{
HTTPResponse response,PreResponse;
String freashCopy,cachedPage,responsePage;
String cpOffset,rpOffset;
public UpdateDynamicCacheFiles(File cacheEntry, HTTPResponse res) throws Exception
{
//Response of older request
PreResponse=new HTTPResponse(new FileInputStream(cacheEntry));
//Response of current request
response=res;
rpOffset=response.getHeaderByName("Offset");
cpOffset=PreResponse.getHeaderByName("Offset");
rpOffset=rpOffset.substring(8);
cpOffset=cpOffset.substring(8);
cachedPage=PreResponse.readMsgBody(PreResponse.toString());
responsePage=response.readMsgBody(response.toString());
}
public void buildPage()
{
StringTokenizer stcpOffset=new StringTokenizer(cpOffset,"-,");
StringTokenizer strpOffset=new StringTokenizer(rpOffset,"-,");
String freashCopy="",temp;
int initIdx=0,fIdx=0,cpCL=0,rpfIdx=0;
while(stcpOffset.hasMoreTokens())
{
if(initIdx==0)
{
fIdx=Integer.parseInt(stcpOffset.nextToken());
temp=strpOffset.nextToken();
freashCopy=cachedPage.substring(initIdx,fIdx);
cpCL=fIdx;
fIdx=Integer.parseInt(strpOffset.nextToken());
freashCopy+=responsePage.substring(initIdx,fIdx);
rpfIdx=fIdx;
cpCL+=Integer.parseInt(stcpOffset.nextToken());
initIdx=cpCL;
}
Anshul,et al. January 10, 2017 [Page 59]
Internet-Draft Knowledge Based Web Page July 2016
else
{
fIdx=Integer.parseInt(stcpOffset.nextToken());
freashCopy=freashCopy+cachedPage.substring(initIdx,fIdx);
cpCL=fIdx;
temp=strpOffset.nextToken();
fIdx=Integer.parseInt(strpOffset.nextToken());
freashCopy+=responsePage.substring(rpfIdx,rpfIdx+fIdx);
rpfIdx=rpfIdx+fIdx;
if(stcpOffset.hasMoreTokens())
cpCL+=Integer.parseInt(stcpOffset.nextToken());
initIdx=cpCL;
}
}
freashCopy+=cachedPage.substring(initIdx);
System.out.println("New Page\n"+freashCopy);
}
public String toString()
{
return freashCopy;
}
}
Anshul,et al. January 10, 2017 [Page 60]
Internet-Draft Knowledge Based Web Page July 2016
File-Name: welcome.html Path WebServer/Welcome.html
Welcome
Welcome
Entry Form
Update Form
View Form
File-Name: Save.html Path WebServer/Pages/Save.html
Employee's Details
Save Form
Anshul,et al. January 10, 2017 [Page 61]
Internet-Draft Knowledge Based Web Page July 2016
File-Name: Update.html Path WebServer/Pages/Update.html
Update Records
Updation Form
Anshul,et al. January 10, 2017 [Page 62]
Internet-Draft Knowledge Based Web Page July 2016
File-Name: Search.html Path WebServer/Pages/Search.html
Search Record
Query Form
6. Difference between Delta Encoding and Knowledge Based Web
Pages
In Delta Encoding, server needs a copy of the previous reply
in order to generate the delta but in this algorithm server can
generates delta on demand without help of previous reply[4].
7. The Version Number of HTTP Protocol
This Draft requests to increase HTTP . version
numbers by one [2].
8. Security Considerations
The Security Considerations of this draft is same as described
in the RFC 2616 for HTTP/1.1.[1]
Anshul,et al. January 10, 2017 [Page 63]
Internet-Draft Knowledge Based Web Page July 2016
9. References
[1] Fielding,R., Gettys,J., Mogul, J.C., Frystyk, H., Masinter,
L.,Leach,P. and T. Berners-Lee Hypertext Transfer Protocol-
HTTP/1.1,RFC 2616, June 1999.
[2] Mogul, J.C., ] Fielding,R., Gettys,J. and H. Frystyk Use
and Interpretation of HTTP Version Numbers, RFC 2145, May 1997.
[3] Berners-Lee,T., Fielding, R. and H. Frystyk
Hypertext Markupkup Language-2.0, RFC 1866, November 1995.
[4] Mogul, J.C., Krishnamurthy, B., Douglis,F., Feldmann, A.,
Goland,Y., Hoff man, A. and D. Hellerstein Delta Encoding in
HTTP, RFC 3229, January 2002.
[5] Forouzan, B.A., Data Communications and Networking, ISBN-
13: 978-0-07-049935-5 Second Edition update, Tata McGraw-Hill
Edition 2003.
[6] Horstmann, C.S., and G. Cornell Core Java Volume-1
Fundamentals Eighth Edidtin, ISBN: 978-81-317-1945-9
[7] Horstmann, C.S., and G. Cornell Core Java Volume-2 Advanced
Features Eighth Edition, ISBN: 978-0-13-235479-0
[8] Hall,M. and L. Brown Core Servlets and Java Server Pages
Volume-1: Core Technologies Second Edition, ISBN: 978-81-317-063-8
[9] D. Wessels Web Caching, ISBN1-56592-596-X
[10] Aho, A.V., Lam. S.M., Sethi, R. and J.D. Ullman Compilers
Principles, Techniques and Tools Second Edition, ISBN: 978-81-317-2101-8
10. Author's Address
Anshul Pareek
Plot No. 138, Nehru Nagar,
Near B.R. Public School,
Jodhpur-342001
E-Mail: pareek.anshul@yahoo.com
Anshul,et al. January 10, 2017 [Page 64]
Internet-Draft Knowledge Based Web Page July 2016