View Javadoc
1 /* Reattore HTTP Server 2 3 Copyright (C) 2002 Michael Hope <michaelh@juju.net.nz> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 $Id: BasicHttpParser.java,v 1.17 2003/02/22 04:29:52 michaelh Exp $ 20 */ 21 22 package juju.reattore.protocol.http.impl; 23 24 import java.util.*; 25 import java.io.IOException; 26 27 import org.apache.commons.logging.*; 28 29 import juju.reattore.io.*; 30 import juju.reattore.io.impl.*; 31 import juju.reattore.protocol.http.*; 32 33 /*** Stateful HTTP parser that will parse blocks of bytes as they are 34 fed in. 35 36 @todo Does not handle chunked encoding. 37 */ 38 public class BasicHttpParser 39 implements HttpParser, StartLineParser.Callback, HeaderParser.Callback { 40 41 private static Log log = LogFactory.getLog(BasicHttpParser.class); 42 43 private PushbackByteSource in = new PushbackByteSource(); 44 45 private ByteSourceSink body; 46 47 private int contentLength; 48 private int bodyLength; 49 50 private boolean parseError; 51 52 private BaseHttpRequest current; 53 54 private HeaderParser headerParser = new HeaderParser(); 55 private StartLineParser startParser = new StartLineParser(); 56 57 private static final int IN_START = 0; 58 private static final int IN_HEADERS = 1; 59 private static final int IN_BODY = 2; 60 61 private int state = IN_START; 62 63 /*** Creates a new parser. 64 */ 65 public BasicHttpParser() { 66 headerParser.setCallback(this); 67 startParser.setCallback(this); 68 69 reset(); 70 } 71 72 private void reset() { 73 state = IN_START; 74 startParser.reset(); 75 headerParser.reset(); 76 77 contentLength = -1; 78 bodyLength = 0; 79 body = new ByteSourceSink(); 80 current = new BaseHttpRequest(); 81 82 current.setBody(body); 83 } 84 85 /*** @see StartLineParser.Callback */ 86 public void onStartLine(String method, String path, String query, 87 String version) { 88 89 current.setStartLine(method, path, query, version); 90 } 91 92 /*** @see HeaderParser.Callback */ 93 public void onHeader(String name, String value) { 94 current.addHeader(name, value); 95 } 96 97 /*** @see HttpParser 98 @todo Minor: Split out the body parser and make it more 99 efficient. 100 */ 101 public List add(ByteSource source) 102 throws ParseException, IOException { 103 104 List ret = new ArrayList(); 105 106 in.seed(source); 107 boolean done = false; 108 109 eof: 110 do { 111 switch (state) { 112 case IN_BODY: 113 /* In the body. Keep reading until all of the content 114 has been read. */ 115 int got = 0; 116 117 while (bodyLength < contentLength && ((got = in.get()) != PushbackByteSource.EOF)) { 118 body.put(got); 119 bodyLength++; 120 } 121 122 if (bodyLength >= contentLength) { 123 /* All done with the headers and the body. Record 124 and move on. */ 125 ret.add(current); 126 reset(); 127 state = IN_START; 128 } 129 if (got == PushbackByteSource.EOF) { 130 break eof; 131 } 132 break; 133 case IN_START: 134 if (startParser.add(in) == false) { 135 break eof; 136 } 137 else { 138 /* Already done through the callback */ 139 state = IN_HEADERS; 140 } 141 break; 142 case IN_HEADERS: 143 if (headerParser.add(in) == false) { 144 break eof; 145 } 146 else { 147 String len = current.getHeader(HttpConstants.CONTENT_LENGTH); 148 if (len != null) { 149 try { 150 contentLength = Integer.parseInt(len); 151 } 152 catch (NumberFormatException ex) { 153 throw new ParseException(); 154 } 155 } 156 state = IN_BODY; 157 } 158 break; 159 default: 160 assert false; 161 throw new ParseException(); 162 } 163 } while (true); 164 165 return ret; 166 } 167 }

This page was automatically generated by Maven