/* * Copyright (C) 2010 Stanford University * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package edu.stanford.junction.addon; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.HashMap; /* import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletInputStream; import javax.servlet.ServletOutputStream; */ // temporary to avoid errors, without including HttpServlet as dependency class ServletInputStream extends InputStream { @Override public int read() throws IOException { // TODO Auto-generated method stub return 0; } } class ServletOutputStream extends OutputStream { @Override public void write(int b) throws IOException { // TODO Auto-generated method stub } public void print(String s) {} } class HttpServletRequest { public String getRequestURI() { return null; } public String getContentType() { return null; } public ServletInputStream getInputStream () { return null; } } class HttpServletResponse { public void setContentType(String type) {} public ServletOutputStream getOutputStream () { return null; } } class HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse resp) {} protected void doGet(HttpServletRequest req, HttpServletResponse resp) {} } public class HttpBridge extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; // static makes the same hashmap available // to all connecting threads. // remember that a thread is created every time // a client connects to our socket. static HashMap<String,HttpBridgePair> bridge = new HashMap<String,HttpBridgePair>(); @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) { String uri = req.getRequestURI(); HttpBridgePair pair; if (!bridge.containsKey(uri)) { pair = new HttpBridgePair(); bridge.put(uri, pair); } else { pair = bridge.get(uri); } if (pair.hasPoster()) { // throw error return; } pair.setPoster(req, resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { String uri = req.getRequestURI(); HttpBridgePair pair; if (!bridge.containsKey(uri)) { pair = new HttpBridgePair(); bridge.put(uri, pair); } else { pair = bridge.get(uri); } if (pair.hasGetter()) { // throw error return; } pair.setGetter(req, resp); bridge.remove(uri); } } class HttpBridgePair { final private int BUFFER_SIZE = 2048; // bytes private HTTPClientConnection mPoster; private HTTPClientConnection mGetter; public boolean hasGetter() { return (mGetter != null); } public boolean hasPoster() { return (mPoster != null); } public synchronized void setPoster(HttpServletRequest req, HttpServletResponse resp) { /* the req object has an input stream; use getInputStream() to get it. Also get the content length as: getContentLength() and type as getContentType(). */ mPoster = new HTTPClientConnection(req,resp); System.out.println("Set Poster"); if(hasGetter()) { System.out.println("Poster notifying..."); this.notify(); } else { while (null == mGetter){ try { System.out.println("Poster waiting..."); this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println("Poster done waiting"); // only one side bridges connection: bridgeConnections(); } public synchronized void setGetter(HttpServletRequest req, HttpServletResponse resp) { System.out.println("Set Getter"); mGetter = new HTTPClientConnection(req,resp); if(hasPoster()) { System.out.println("Getter notifying..."); this.notify(); } else { while (null == mPoster){ try { System.out.println("Getter waiting..."); this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println("Getter done waiting"); } /** * Does the work of actually bridging our connections, * given a GET and POST request. */ private void bridgeConnections() { // bridge poster.req.getInputStream() // and // getter.resp.getOutputStream() //need to get header //send other header //get InputStream //send InputStream try{ String postType = mPoster.request.getContentType(); //int postLength = mPoster.request.getContentLength(); ServletInputStream in = mPoster.request.getInputStream(); ServletOutputStream out = mGetter.response.getOutputStream(); if(postType.indexOf("multipart/form-data") == -1){ //mGetter.response.setContentType("application/pdf"); int i; byte[] buf = new byte[BUFFER_SIZE]; while(-1 != (i = in.read(buf))) { out.write(buf,0,i); } } else{ StringBuffer line = new StringBuffer(); StringBuffer preamble = new StringBuffer(); int i = in.read(); while(i != -1){ if((char)i == '\n'){ String s = line.toString(); String CONTENT_TYPE = "Content-Type: "; if(s.indexOf(CONTENT_TYPE) != -1){ String type = s.substring(CONTENT_TYPE.length()); if(!type.equals("multipart/form-data")){ mGetter.response.setContentType(type); preamble.append((char)i); break; } } line = new StringBuffer(); } line.append((char)i); preamble.append((char)i); i = in.read(); } out.print(preamble.toString()); byte[] buf = new byte[BUFFER_SIZE]; while(-1 != (i = in.read(buf))) { out.write(buf,0,i); } } in.close(); out.close(); } catch (Exception e) { //print some type of error here. } } class HTTPClientConnection { public HttpServletRequest request; public HttpServletResponse response; public HTTPClientConnection(HttpServletRequest req, HttpServletResponse resp) { this.request = req; this.response = resp; } } }