/* * Copyright (c) Martin Schoeberl, martin@jopdesign.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Martin Schoeberl * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ package ejip.examples; import com.jopdesign.sys.Const; import java.io.IOException; import util.Serial; import util.Timer; import ejip.*; import sdcard.*; /** * Simple HTTP server. Uses the SD card file system. */ public class HTTPServer extends TcpHandler { public static final int CMD = 0; public static final int CONT_CMD = 1; public static final int CONT_REPLY = 2; public static final int QUIT = 3; public static final int MAX_CMDLEN = 4*1024; private static final int BUFFER_LEN = 1024; static Ejip ejip; static Net net; static LinkLayer ipLink; static Serial ser; private int state = CMD; private StringBuffer sb = new StringBuffer(); private StringBuffer cmd = new StringBuffer(); private FileInputStream currentFile; private byte[] buffer = new byte[BUFFER_LEN]; public Packet request(Packet p) { Ip.getData(p, Tcp.DATA, sb); System.out.println("serving HTTP request"); // ignore messages unless we continue to send the message if ((sb.length() == 0) && (state != CONT_REPLY)) { return null; } switch(state) { case CMD: cmd.delete(0, cmd.length()); state = CONT_CMD; /* fall through */ case CONT_CMD: cmd.append(sb); if (cmd.indexOf("\r\n\r\n") >= 0) { //System.out.println("--------------------------------"); //System.out.print(cmd); //System.out.println("--------------------------------"); // parse command and send first reply if (cmd.charAt(0)=='G' && cmd.charAt(1)=='E' && cmd.charAt(2)=='T' && cmd.charAt(3)==' ') { if (cmd.charAt(4)=='/') { sb.delete(0, sb.length()); if (cmd.charAt(5)==' ') { sb.append("index.htm"); } else { int i = 5; while (cmd.charAt(i) != ' ') { sb.append(cmd.charAt(i)); i++; } } try { currentFile = new FileInputStream(sb); sb.delete(0, sb.length()); sb.append("HTTP/1.0 200 OK\r\nContent-Length: "); sb.append(currentFile.available()); sb.append("\r\n\r\n"); Ip.setData(p, Tcp.DATA, sb); state = CONT_REPLY; } catch (IOException exc) { Ip.setData(p, Tcp.DATA, "HTTP/1.0 404 File not found\r\nContent-Length: 3\r\n\r\n404"); state = QUIT; } } else { Ip.setData(p, Tcp.DATA, "HTTP/1.0 404 File not found\r\nContent-Length: 3\r\n\r\n404"); state = QUIT; } } else { Ip.setData(p, Tcp.DATA, "HTTP/1.0 501 I can only handle GET\r\nContent-Length: 3\r\n\r\n501"); state = QUIT; } } else { if (cmd.length() > MAX_CMDLEN) { state = QUIT; } // just ack what we have return null; } break; case CONT_REPLY: // read from file int r = currentFile.read(buffer); // hand over packet Ip.setData(p, Tcp.DATA, buffer, r); // check for EOF if (r == buffer.length) { state = CONT_REPLY; } else { currentFile.close(); state = QUIT; } break; case QUIT: // ignore any messages when idle return null; } return p; } public Packet established(Packet p) { state = CMD; return null; } public boolean finished() { return state == QUIT; } /** * Start network and enter forever loop. */ public static void main(String[] args) { ejip = new Ejip(100, 1500); // // start TCP/IP // net = new Net(ejip); // // use second serial line for simulation // with JopSim and on the project usbser // ser = new Serial(Const.IO_UART_BG_MODEM_BASE); int ip = Ejip.makeIp(192, 168, 1, 2); ipLink = new Slip(ejip, ser, ip); // create http server HTTPServer server = new HTTPServer(); // register http server net.getTcp().addHandler(80, server); forever(); } private static void forever() { for (;;) { for (int i=0; i<1000; ++i) { ser.loop(); // timeout in slip depends on loop time! ipLink.run(); ser.loop(); net.run(); } Timer.wd(); System.out.print("*"); } } }