sunlabs.brazil.handler.PushHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sunlabs.brazil Show documentation
Show all versions of sunlabs.brazil Show documentation
Extremely small footprint Java HTTP stack.
The newest version!
/*
* PushHandler.java
*
* Brazil project web application toolkit,
* export version: 2.3
* Copyright (c) 1999-2006 Sun Microsystems, Inc.
*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License Version
* 1.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is included as the file "license.terms",
* and also available at http://www.sun.com/
*
* The Original Code is from:
* Brazil project web application toolkit release 2.3.
* The Initial Developer of the Original Code is: suhler.
* Portions created by suhler are Copyright (C) Sun Microsystems, Inc.
* All Rights Reserved.
*
* Contributor(s): cstevens, suhler.
*
* Version: 2.2
* Created by suhler on 99/08/04
* Last modified by suhler on 06/11/13 15:04:09
*
* Version Histories:
*
* 2.2 06/11/13-15:04:09 (suhler)
* move MatchString to package "util" from "handler"
*
* 2.1 02/10/01-16:36:25 (suhler)
* version change
*
* 1.12 02/07/24-10:45:12 (suhler)
* doc updates
*
* 1.11 01/07/20-11:32:10 (suhler)
* MatchUrl -> MatchString
*
* 1.10 01/07/17-14:15:52 (suhler)
* use MatchUrl
*
* 1.9 00/12/11-13:28:16 (suhler)
* add class=props for automatic property extraction
*
* 1.8 00/05/31-13:47:07 (suhler)
* doc cleanup
*
* 1.7 00/05/24-11:25:37 (suhler)
* added docs
*
* 1.6 00/04/20-11:48:11 (cstevens)
* copyright.
*
* 1.5 00/03/10-17:02:14 (cstevens)
* Removing unused member variables
*
* 1.4 99/10/27-13:19:49 (suhler)
* Merged changes between child workspace "/home/suhler/brazil/naws" and
* parent workspace "/net/mack.eng/export/ws/brazil/naws".
*
* 1.3 99/10/26-18:52:30 (cstevens)
* case
*
* 1.2.1.2 99/10/20-14:42:08 (suhler)
* make methods public
*
* 1.2.1.1 99/10/18-10:25:26 (suhler)
* rewrote to use binary data
*
* 1.2 99/09/15-14:40:36 (cstevens)
* Rewritign http server to make it easier to proxy requests.
*
* 1.2 99/08/04-18:43:18 (Codemgr)
* SunPro Code Manager data about conflicts, renames, etc...
* Name history : 1 0 handlers/PushHandler.java
*
* 1.1 99/08/04-18:43:17 (suhler)
* date and time created 99/08/04 18:43:17 by suhler
*
*/
package sunlabs.brazil.handler;
import java.io.IOException;
import sunlabs.brazil.util.MatchString;
import sunlabs.brazil.server.Handler;
import sunlabs.brazil.server.Request;
import sunlabs.brazil.server.Server;
/**
* Skeleton Handler for uploading files using multipart/form-data.
* Application specific functionality is added by overriding
* {@link #processData}.
*
NOTE: Most applications will want to use the
* {@link sunlabs.brazil.template.MultipartSetTemplate} to deal with
* multipart/form data.
*
* Properties:
*
* - prefix, suffix, glob, match
*
- Specify the URL that triggers this handler.
* (See {@link MatchString}).
*
*
* @author Stephen Uhler
* @version 2.2, 06/11/13
*/
public class PushHandler implements Handler {
MatchString isMine; // check for matching url
public boolean
init(Server server, String prefix) {
isMine = new MatchString(prefix, server.props);
return true;
}
/**
* Make sure this is one of our requests.
* IF OK, save file to proper spot.
*/
public boolean
respond(Request request) throws IOException {
String type = (String) request.headers.get("content-type");
if (!isMine.match(request.url) ||
!type.startsWith("multipart/form-data")) {
return false;
}
/*
* screen out bad requests
*/
if (request.postData == null) {
request.sendError(400, "No content to put");
return true;
}
if (request.headers.get("Content-Range") != null) {
request.sendError(501, "Can't handle partial puts");
return true;
}
return processData(request);
}
/**
* process the data - this doesn't currently do anything useful.
*/
public boolean processData(Request request) {
Split s = new Split(request.postData);
while (s.nextPart()) {
System.out.println(s.name() + ": {" + s.content() + "}");
}
return false;
}
/**
* Split multipart data into its constituent pieces. Use byte[] so we can
* handle (potentially) large amounts of binary data.
* This acts as an iterator, stepping through the parts, extracting the appropriate
* info for eacxh part.
*/
public static class Split {
byte[] bytes;
int bndryEnd; // end of the initial boundary line
int partStart; // start index of this part
int partEnd; // index to the end of this part
int contentStart; // start of the content
/**
* create a new multipart form thingy
*/
public Split(byte[] bytes) {
partEnd = 0;
this.bytes = bytes;
bndryEnd = indexOf(bytes, 0, bytes.length, "\r\n");
partStart=0;
contentStart=0;
}
/**
* Return true if there is a next part
*/
public boolean
nextPart() {
partStart = partEnd + bndryEnd+2;
if (partStart >= bytes.length) {
return false;
}
partEnd = indexOf(bytes, partStart, bytes.length, bytes, 0, bndryEnd);
if (partEnd < 0) {
return false;
}
partEnd -=2; // back over \r\n
contentStart = indexOf(bytes, partStart, bytes.length, "\r\n\r\n") + 4;
return true;
}
/**
* Get the content as a string
*/
public String
content() {
return new String(bytes, contentStart, partEnd-contentStart);
}
/**
* Return the content length
*/
public int
length() {
return partEnd - contentStart;
}
/**
* return the index into the start of the data for this part
*/
public int
start() {
return contentStart;
}
/**
* Return the header as a string
*/
public String header() {
return (new String(bytes, partStart, contentStart-partStart));
}
/**
* get the part name
*/
public String name() {
int start = indexOf(bytes, partStart, contentStart, "name=\"") + 6;
int end = indexOf(bytes, start, contentStart, "\"");
if (start>=6 && end >=0) {
return (new String(bytes, start, end-start));
} else {
return null;
}
}
}
/**
* Find the index of dst in src or -1 if not found >
* This is the byte array equivalent to string.indexOf()
*/
public static int
indexOf(byte[] src, int srcStart, int srcEnd, byte[] dst, int dstStart, int dstEnd) {
int len = dstEnd - dstStart; // len of to look for
srcEnd -= len;
for (;srcStart < srcEnd; srcStart++) {
boolean ok=true;
for(int i=0; ok && i