// ** This class was generated with DemFGen (vers:06/04/2009) package http.gen; import edu.neu.ccs.demeterf.demfgen.lib.*; import java.net.Socket; import java.net.ServerSocket; import java.io.IOException; import java.io.BufferedReader; import java.io.PrintWriter; import java.io.InputStreamReader; import java.io.InputStream; /** Representation of HTTPReq */ public class HTTPReq{ public final HTTPHead head; public final List keys; public final ident body; /** Construct a(n) HTTPReq Instance */ public HTTPReq(HTTPHead head, List keys, ident body){ this.head = head; this.keys = keys; this.body = body; } /** Is the given object Equal to this HTTPReq? */ public boolean equals(Object o){ if(!(o instanceof HTTPReq))return false; if(o == this)return true; HTTPReq oo = (HTTPReq)o; return (((Object)head).equals(oo.head))&&(((Object)keys).equals(oo.keys))&&(((Object)body).equals(oo.body)); } /** Field Class for HTTPReq.head */ public static class head extends edu.neu.ccs.demeterf.control.Fields.any{} /** Field Class for HTTPReq.keys */ public static class keys extends edu.neu.ccs.demeterf.control.Fields.any{} /** Field Class for HTTPReq.body */ public static class body extends edu.neu.ccs.demeterf.control.Fields.any{} /** Create an HTTP Request with a given Header, MessageHeaders, and Body */ public static HTTPReq create(HTTPHead req, List hds, String body){ return new HTTPReq(req, hds.append(new MsgHead("Content-Length",""+body.length())), new ident(body)); } /** Create an HTTP Get Request for the given (relative) URL. Then use * {@link HTTPReq.send Send} for a Request/Response pair. */ public static HTTPReq Get(String url) throws ParseException { return create(HTTPHead.Get(URL.parse(url)), List.create(), ""); } /** Create an HTTP Get Request for the given relative URL, to be sent to the * given Host. Use this method for raw Socket/Connection sends, but use * {@link HTTPReq.send Send} for a Request/Response pair. */ public static HTTPReq Get(String url, String host) throws ParseException { return create(HTTPHead.Get(URL.parse(url)), hostHeader(host), ""); } /** Create an HTTP Head Request for the given (relative) URL. Then use * {@link HTTPReq.send Send} for a Request/Response pair. */ public static HTTPReq Head(String url) throws ParseException { return create(HTTPHead.Get(URL.parse(url)), List.create(), ""); } /** Create an HTTP Head Request for the given relative URL, to be sent to the * given Host. Use this method for raw Socket/Connection sends, but use * {@link HTTPReq.send Send} for a Request/Response pair. */ public static HTTPReq Head(String url, String host) throws ParseException { return create(HTTPHead.Head(URL.parse(url)), hostHeader(host), ""); } /** Create an HTTP Post Request to the given (relative) URL. Then use * {@link HTTPReq.send Send} for a Request/Response pair. */ public static HTTPReq Post(String url, String body) throws ParseException { return create(HTTPHead.Post(URL.parse(url)), List.create(), body); } /** Create an HTTP Post Request to the given relative URL, to be sent to the * given Host. Use this method for raw Socket/Connection sends, but use * {@link HTTPReq.send Send} for a Request Response Pair. */ public static HTTPReq Post(String url, String host, String body) throws ParseException { return create(HTTPHead.Post(URL.parse(url)), hostHeader(host), body); } private static List hostHeader(String h) { return List.create(new MsgHead(new ident("Host"), new ident(h))); } /** Add the given Message Headers to this Request */ HTTPReq addHeaders(List hs){ return create(head,hs.append(keys),""+body); } /** Request Types */ public static enum ReqType{ GET, POST, HEAD, OTHER }; /** Return this Request's type */ public ReqType getType(){ return head.getType(); } /** Return the URL arguments (key/value) for this request. The URL arguments * follow the base URL after a '?'. * E.g.: /foo/bar?bazzle=13&wizwoz='hello' */ public Map urlArgs(){ return head.url.urlArgs(); } /** Return the Body arguments (key/value) from this request. The Body arguments * are on a single line of the body, like URLArgs, but without the '?' */ public Map bodyArgs(){ return splitArgs(""+body); } /** Return the relative URL, without any URL arguments */ public String trimmedUrl(){ return head.url.trimArgs(); } /** Handle this Request with the given Handler */ public HTTPResp handle(ReqHandler h){ return head.handle(this,h); } /** Send this Request to the given Server/Port, and return its Response */ public HTTPResp send(String server, int port) throws IOException { Socket sock = new Socket(server, port); addHeaders(hostHeader(server+":"+port)).toSocket(sock); HTTPResp res = HTTPResp.fromSocket(sock); sock.close(); return res; } /** Write this Request to the given Socket */ public void toSocket(Socket s){ try{ PrintWriter out = new PrintWriter(s.getOutputStream()); out.print(this.toString()); out.flush(); s.shutdownOutput(); }catch(Exception e){ throw new RuntimeException(e); } } /** Read a request from a Socket */ public static HTTPReq fromSocket(Socket s){ try{ HTTPReq req = fromInputStream(s.getInputStream()); s.shutdownInput(); return req; }catch(Exception e){ throw new RuntimeException(e); } } /** Read a Request from an InputStream */ public static HTTPReq fromInputStream(InputStream inpt){ try{ BufferedReader in = new BufferedReader(new InputStreamReader(inpt)); HTTPHead h = HTTPHead.parse(in.readLine()); return new HTTPReq(h, parseMsgHeads(in), parseBody(in)); }catch(Exception e){ throw new RuntimeException(e); } } /** Parse a List of Message Headers */ static List parseMsgHeads(BufferedReader in) throws Exception{ String line; if(!in.ready() || (line = in.readLine()).length()==0) return List.create(); int colon = line.indexOf(":"); return parseMsgHeads(in).push(new MsgHead(new ident(line.substring(0,colon)), new ident(line.substring(colon+2)))); } /** Parse the Body of a Request */ static ident parseBody(BufferedReader in) throws Exception{ StringBuffer sb = new StringBuffer(); char[] buff = new char[1024]; int many = 0; if(in.ready()) do{ many = in.read(buff); sb.append(buff,0,many); }while(in.ready() && many == 1024); return new ident(sb.toString()); } /** Return the Body of this Request */ public String getBody(){ return ""+body; } /** Return the Headers of this Request as a Map */ public Map getHeaders(){ return getHeaders(keys); } /** Return the Headers of this Request as a Map */ static Map getHeaders(List hds){ return hds.fold(new List.Fold>(){ public Map fold(MsgHead h, Map m){ return m.put(""+h.key,""+h.value); } }, Map.create()); } /** Split an argument String into key/value Map */ static Map splitArgs(String s){ return List.create(s.split("&")).fold(new List.Fold>(){ public Map fold(String p, Map m){ String[] kv = p.split("="); if(kv.length < 2)return m; return m.put(kv[0],kv[1]); } }, Map.create()); } /** DGP method from Class PrintToString */ public String toString(){ return http.gen.PrintToString.PrintToStringM(this); } }