// HTTPSender.java
package protocol; // protocol package
import java.util.*; // import Java utility classes
import support.*; // import Jasper support classes
/**
This is the main class for simulation of an HTTP sender (i.e. client).
@author Kenneth J. Turner, Kenneth A. Whyte
@version 1.4 (9th March 2006, KJT/KAW): initial version
1.5 (19th July 2010, KJT): minor tidying
*/
public class HTTPSender implements ProtocolEntity {
// Protocol state constants
private static final int IDLE = 0; // ready to send
private static final int GET_SENT = 1; // waiting GET resp.
private static final int HEAD_SENT = 2; // waiting HEAD resp.
private static final int POST_SENT = 3; // waiting POST resp.
private static final int PUT_SENT = 4; // waiting PUT resp.
private int state;
private PDU pduSent;
private PDU pduReceived;
private ProtocolEntity peer;
private Medium medium;
private String name;
private int index; // data/URL index
public HTTPSender(Medium m, String name) {
this.name = name;
medium = m;
initialise();
}
public String getName() {
return(name);
}
public Vector getServices() {
Vector list = new Vector();
String pduType, pduData;
if (pduReceived != null) {
pduType = pduReceived.type;
pduData = pduReceived.sdu;
}
else {
pduType = "";
pduData = "";
}
switch (state) {
case GET_SENT:
if (pduType.startsWith("200") || pduType.startsWith("400"))
state = IDLE;
else if (pduType.startsWith("301"))
list.addElement(pduSent.type + "(" + pduData + ") - get data for new URL");
break;
case HEAD_SENT:
if (pduType.startsWith("200") || pduType.startsWith("400"))
state = IDLE;
else if (pduType.startsWith("301"))
list.addElement(pduSent.type + "(" + pduData + ") - get header for new URL");
break;
case POST_SENT:
case PUT_SENT:
if (pduType.startsWith("200") || pduType.startsWith("400"))
state = IDLE;
break;
}
if (state == IDLE) {
list.addElement("GET(URL" + index + ") - get data for URL");
list.addElement("HEAD(URL" + index + ") - get header for URL");
list.addElement("POST(URL" + index + ",DATA" +
index + ") - append data to URL");
list.addElement("PUT(URL" + index + ",DATA" +
index + ") - send data to URL");
}
return(list);
}
public void initialise() {
state = IDLE;
index = 1;
pduSent = null;
pduReceived = null;
}
public Vector performService (String s) {
Vector events = new Vector();
int startIndex, midIndex, endIndex; // start/mid/end subscripts
String url = ""; // current URL
String data; // URL data
pduSent = null;
startIndex = s.indexOf ('(') + 1; // get URL start
endIndex = s.indexOf (')'); // get URL end
if (s.startsWith ("GET")) { // GET?
url = s.substring(startIndex, endIndex); // get URL
transmitPDU(new PDU("GET", url), peer);
state = GET_SENT; // GET now sent
}
else if (s.startsWith ("HEAD")) { // HEAD?
url = s.substring(startIndex, endIndex); // get URL
transmitPDU(new PDU("HEAD", url), peer);
state = HEAD_SENT; // HEAD now sent
}
else if (s.startsWith ("POST")) { // POST?
midIndex = s.indexOf (','); // get URL end
url = s.substring(startIndex, midIndex); // get URL
data = s.substring(midIndex + 1, endIndex); // get URL data
transmitPDU(new PDU("POST", url + "," + data), peer);
state = POST_SENT; // POST now sent
}
else if (s.startsWith ("PUT")) { // PUT?
midIndex = s.indexOf (','); // get URL end
url = s.substring(startIndex, midIndex); // get URL
data = s.substring(midIndex + 1, endIndex); // get URL data
transmitPDU(new PDU("PUT", url + "," + data), peer);
state = PUT_SENT; // PUT now sent
}
if (pduSent != null) {
startIndex = url.indexOf ("URL"); // get URL start
index = // extract/increment index
Integer.parseInt(url.substring(startIndex + 3)) + 1;
events.addElement(new ProtocolEvent(ProtocolEvent.TRANSMIT, pduSent));
events.addElement( new ProtocolEvent(ProtocolEvent.RECEIVE, pduSent));
}
return(events);
}
public Vector receivePDU(PDU pdu) {
pduReceived = pdu;
return(new Vector());
}
public void setPeer(ProtocolEntity peer) {
this.peer = peer;
}
public void transmitPDU(PDU pdu, ProtocolEntity dest) {
pdu.setSource(this);
pdu.setDestination(dest);
pduSent = pdu;
peer.receivePDU(pdu);
pduReceived = null;
}
}