/* * HTTPMulticastUDPSocket.java * * Created on 1 avril 2001, 17:16 */ package context.arch.comm.protocol; import context.arch.comm.protocol.MulticastUDPSocket; import context.arch.comm.CommunicationsMulticast; import context.arch.comm.CommunicationsObject; import java.net.InetAddress; import java.net.DatagramPacket; import java.net.UnknownHostException; import java.io.BufferedReader; import java.io.StringReader; import java.io.IOException; import java.util.StringTokenizer; /** * This object is able to connect to a multicast group and to send multicast * messages * @author Agathe */ public class HTTPMulticastUDPSocket extends MulticastUDPSocket implements CommunicationsMulticast { /** * Debug flag. Set to true to see debug messages. */ public static boolean DEBUG = false; /** * The protocol being used is HTTP */ public static final String PROTOCOL = "HTTP"; /** * HTTP GET request type */ public static final String GET = "GET"; /** * HTTP POST request type */ public static final String POST = "POST"; private CommunicationsObject commObject; /** Basic constructor for HTTPMulticastSocket that calls MulticastUDPSocket * * @param object Handle of the generic instantiating communications object * @see context.arch.comm.protocol.MulticastUDPSocket */ public HTTPMulticastUDPSocket(CommunicationsObject object ) { super(); commObject = object; } /** * Stub method that handles incoming HTTP multicast packets. It calls the equivalent * method in the CommunicationsObject and then closes the socket. * * @param packet DatagramPacket to receive HTTP data in * @see context.arch.comm.CommunicationsObject#handleIncomingRequest(java.net.DatagramPacket) */ public void handleIncomingRequest(DatagramPacket packet) { //commObject.println("\nHTTPMulticastUDPSocket handleIncomingRequest (packet)"); commObject.handleIncomingRequest(packet); } /** * Abstract method to call when stopping a CommunicationsServer object */ public void quit() { } /** * Abstract method to get the communications protocol being used * * @return the protocol being used */ public String getProtocol() { return null; } /** * This abstract method strips the protocol away from the received request * * @param socket The socket the request is being received on * @return the request with the protocol stripped away * @exception context.arch.comm.protocol.ProtocolException thrown if protocol can't be stripped away * @see #addReplyProtocol(String) * @see CommunicationsClient#addRequestProtocol(String,String) * @see CommunicationsClient#stripReplyProtocol(java.net.Socket) */ public RequestData stripProtocol(DatagramPacket packet) throws ProtocolException { //commObject.println("\nHTTPMulticastUDPSocket stripProtocol (packet)"); String method; // String version = ""; BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new StringReader(new String(packet.getData()))); //commObject.println("RequestData contained in the packet:"+packet.getData()); String get = bufferedReader.readLine(); StringTokenizer tokenizer = new StringTokenizer(get); int bytesRead = 0; int bytesReadThisTime = 0; char [] tempdata; method = tokenizer.nextToken(); //commObject.println("HTTPMulticast - method:"+method); if (method.equals("GET")) { String file= tokenizer.nextToken(); if (tokenizer.hasMoreTokens()) { // version = tokenizer.nextToken(); } //commObject.println("HTTPMulticastUDPSocketget :"+file +" - version:" + version); while ((get = bufferedReader.readLine()) != null) { if (get.trim().equals("")) { break; } } //commObject.println("HTTPServerSocket stripRequestProtocol:GET\n"+file); // Has to define another type to return.... maybe return new RequestData(GET,file,null); } else if (method.equals(POST)) { String file= tokenizer.nextToken(); if (tokenizer.hasMoreTokens()) { // version = tokenizer.nextToken(); } //commObject.println("HTTPMulticastUDPSocketmethod :"+method + " -version :"+version); String marker = "content-length:"; while (!(get.toLowerCase().startsWith(marker))) { get = bufferedReader.readLine(); } int length = 0; try { length = new Integer(get.substring(marker.length()).trim()).intValue(); } catch (NumberFormatException nfe) { System.out.println("HTTPMulticastUDPSocket RequestServerSocket run error: "+nfe); throw new ProtocolException(); } if (DEBUG) { System.out.println("HTTPMulticastUDPSocket Content-Length is: " + length); } while (!(get.trim().equals(""))) { get = bufferedReader.readLine(); } char[] postdata = new char[length]; tempdata = new char [length]; while (bytesRead < length) { if (bufferedReader.ready()){ int ix = bytesRead; // index to current end of tempdata bytesReadThisTime = bufferedReader.read(postdata, 0, length); // DS: check we've read what we should bytesRead += bytesReadThisTime; if (DEBUG) { System.out.println("read " + bytesReadThisTime + " more bytes, "+bytesRead); } for (int i = 0; i < bytesReadThisTime; i++) { tempdata[ix + i] = postdata[i]; } postdata = new char[length]; } } String readerData = new String(tempdata); StringReader reader = new StringReader(readerData); //commObject.println("After processing-HTTPMulticast stripProtocol - data:\n"+readerData); return new RequestData(RequestData.DECODE,file, reader); } else { System.out.println("HTTPMulticast stripProtocol: invalid protocol use"); throw new ProtocolException(); } } catch (IOException ioe) { System.out.println("HTTPMulticast stripProtocol IOException: "+ioe); throw new ProtocolException(); } } /** * This method adds the HTTP protocol for a POST request * (POST is the default) * * @param content The request to send * @return socket for the connection */ public String addProtocol(String data, String url) throws ProtocolException { return addProtocol (data, url, POST); } /** * This abstract method adds the protocol to a request to be sent * * @param data The request to add the protocol to * @param listener The recipient of the request (eg, an URL in HTTP). May be null. * @return the request with the protocol added * @exception context.arch.comm.protocol.ProtocolException thrown if protocol can't be added * @see #stripReplyProtocol(Socket) * @see context.arch.comm.CommunicationsServer#stripRequestProtocol(Socket) * @see context.arch.comm.CommunicationsServer#addReplyProtocol(String) */ public String addProtocol(String data,String url, String type) throws ProtocolException { int xmlLen = data.length(); String eol = "\r\n"; StringBuffer text = new StringBuffer(); String thisMachine; try { // get our machine name InetAddress thisInet = InetAddress.getLocalHost(); thisMachine = thisInet.getHostName(); } catch (UnknownHostException e) { thisMachine = "localhost"; } xmlLen += 2*eol.length(); // add length of end of lines at the end if (type.equals (POST)) { text.append(POST + " " + url + " HTTP/1.0" + eol); } else { text.append (GET + " " + url + " HTTP/1.0" + eol); } text.append("User-Agent: Context Client" + eol); text.append("Host: " + thisMachine + eol); if (type.equals (POST)) { text.append("Content-Type: text/xml" + eol); text.append("Content-Length: " + xmlLen + eol); text.append(eol); text.append(data + eol); } text.append(eol); //commObject.println("\nHTTPMulticastUDPSocket : addRequestProtocol\n" + " CONTENT:\n" + text.toString()); return text.toString(); } /** * This abstract method sends a request * * @param request The request to send * @return the reply to the request */ public void sendMessage(String message) { //commObject.println("HTTPMulticastUDPSocket sendMessage message:"); sendPacket(message); } }