`

http - simple server & client

阅读更多

Simple http server & client implementation by pure j2se.

 

http - client:

package eric.j2se.net.http;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * <p>
 * A simple http client.
 * </p>
 * 
 * @author eric
 * @date Jan 6, 2014 4:29:54 PM
 */
public class SimpleHttpClient {
	/**
	 * send http request & get response,
	 * 
	 * @param host
	 *            hostname or ip
	 * @param path
	 *            path after host, format: "/xxx"
	 * @param port
	 * @return response string
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public static String httpRequest(String host, String path, int port) throws IOException, InterruptedException {
		Socket client = new Socket(host, port);
		StringBuffer requestInfo = new StringBuffer("");
		StringBuffer responseInfo = new StringBuffer("");

		// prepare request info,
		requestInfo.append("GET " + path + " HTTP/1.1\n");
		requestInfo.append("Host: " + host + "\n");
		requestInfo.append("Connection: Close\n");

		// send request,
		PrintWriter pw = new PrintWriter(client.getOutputStream(), true);
		pw.println(requestInfo.toString());
		System.out.println("****** request - start ******");
		System.out.println(requestInfo.toString());
		System.out.println("****** request - end ******");

		// get response info,
		LineNumberReader lnr = new LineNumberReader(new InputStreamReader(client.getInputStream()));
		String line;
		while ((line = lnr.readLine()) != null) {
			responseInfo.append(line + "\n");
		}
		System.out.println("****** response - start ******");
		System.out.println(responseInfo.toString());
		System.out.println("****** response - end ******");

		pw.close();
		lnr.close();
		client.close();
		return responseInfo.toString();
	}

	/****** test - start ******/
	/**
	 * test http request,
	 */
	public static void testHttpRequest() {
		try {
			httpRequest("localhost", "/index.html", 80);
			// sendRequest("www.google.com.hk", "/", 80);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {

	}
	/****** test - end ******/
}

 

 

http - server:

package eric.j2se.net.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

/**
 * <p>
 * A simple http server.
 * </p>
 * 
 * @author eric
 * @date Jan 9, 2014 10:10:48 PM
 */
public interface HttpServer {
	/**
	 * start server,
	 */
	void start();

	/**
	 * parse, get params,
	 * 
	 * @param is
	 * @return params
	 * @throws IOException
	 */
	Map<String, String> parse(InputStream is) throws IOException;

	/**
	 * read param from param string,
	 * 
	 * @param paramStr
	 *            params string, format: name1=value1&name2=value2\
	 * @param isBody
	 *            whether the params from body,
	 * 
	 * @return map of param key/value,
	 */
	Map<String, String> parseParam(String paramStr, boolean isBody);

	/**
	 * send response
	 * 
	 * @param os
	 * @param paramMap
	 */
	void response(OutputStream os, Map<String, String> paramMap);

	/**
	 * shutdown server,
	 * 
	 * @throws IOException
	 */
	void terminate() throws IOException;
}

 

package eric.j2se.net.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

/**
 * <p>
 * A simple http server implementation.
 * </p>
 * TODO ... add more feature
 * 
 * @author eric
 * @date Jan 10, 2014 2:53:50 AM
 */
public class SimpleHttpServer implements HttpServer {
	private ServerSocket server;

	public SimpleHttpServer(int port, int backlog, String host) throws UnknownHostException, IOException {
		server = new ServerSocket(port, backlog, InetAddress.getByName(host));
	}

	@Override
	public void start() {
		Socket socket = null;
		InputStream inStream = null;
		OutputStream outStream = null;

		Map<String, String> paramMap = null;

		while (true) {
			try {
				socket = server.accept();

				// get input
				inStream = socket.getInputStream();
				paramMap = parse(inStream);
				// paramMap = new HashMap();

				// write output
				outStream = socket.getOutputStream();
				response(outStream, paramMap);

				// close socket, this indicate the client that the response is finished,
				socket.close();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					if (inStream != null) {
						inStream.close();
					}
					if (outStream != null) {
						outStream.close();
					}
					if (socket != null) {
						socket.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	@Override
	public Map<String, String> parse(InputStream is) throws IOException {
		Map<String, String> paramMap = new HashMap<String, String>();
		LineNumberReader lr = new LineNumberReader(new InputStreamReader(is));
		String inputLine = null;
		String method = null;
		String httpVersion = null;
		String uri = null;

		// read request line
		inputLine = lr.readLine();
		String[] requestCols = inputLine.split("\\s");
		method = requestCols[0];
		uri = requestCols[1];
		httpVersion = requestCols[2];
		System.out.println("http version:\t" + httpVersion);

		// parse GET param
		if (uri.contains("?")) {
			paramMap.putAll(parseParam(uri.split("\\?", 2)[1], false));
		}

		// read header
		while (StringUtils.isNotBlank(inputLine = lr.readLine())) {
			System.out.println("post header line:\t" + inputLine);
		}

		// read body - POST method
		if (method.toUpperCase().equals("POST")) {
			StringBuffer bodySb = new StringBuffer();
			char[] bodyChars = new char[1024];
			int len;

			// ready() make sure it will not block,
			while (lr.ready() && (len = lr.read(bodyChars)) > 0) {
				bodySb.append(bodyChars, 0, len);
			}
			paramMap.putAll(parseParam(bodySb.toString(), true));

			System.out.println("post body:\t" + bodySb.toString());
		}

		return paramMap;
	}

	@Override
	public Map<String, String> parseParam(String paramStr, boolean isBody) {
		String[] paramPairs = paramStr.trim().split("&");
		Map<String, String> paramMap = new HashMap<String, String>();

		String[] paramKv;
		for (String paramPair : paramPairs) {
			if (paramPair.contains("=")) {
				paramKv = paramPair.split("=");
				if (isBody) {
					// replace '+' to ' ', because in body ' ' is replaced by '+' automatically when post,
					paramKv[1] = paramKv[1].replace("+", " ");
				}
				paramMap.put(paramKv[0], paramKv[1]);
			}
		}

		return paramMap;
	}

	@Override
	public void response(OutputStream os, Map<String, String> paramMap) {
		String name = StringUtils.isBlank(paramMap.get("name")) ? "xxx" : paramMap.get("name");

		PrintWriter pw = null;
		pw = new PrintWriter(os);
		pw.println("HTTP/1.1 200 OK");
		pw.println("Content-type: text/html; Charset=UTF-8");
		pw.println("");
		pw.println("<h1>Hi <span style='color: #FFF; background: #000;'>" + name + "</span> !</h1>");
		pw.println("<h4>current date: " + new Date() + "</h4>");
		pw.println("<p>you can provide your name via a param called <span style='color: #F00; background: yellow;'>\"name\"</span>, in both GET and POST method.</p>");
		pw.flush();
	}

	@Override
	public void terminate() throws IOException {
		server.close();
	}

	/****** test - start ******/
	public static void main(String[] args) {
		testHttpServer();
	}

	// test http server,
	public static void testHttpServer() {
		try {
			HttpServer server = new SimpleHttpServer(9090, 1, "localhost");
			server.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/****** test - end ******/
}

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics