/** * Tencent is pleased to support the open source community by making MSEC available. * * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. * * Licensed under the GNU General Public 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 * * https://opensource.org/licenses/GPL-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 org.msec.rpc; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.util.Hashtable; public class HttpRequestParser { private String _requestLine; private String _method; private String _uri; private String _cgi_path; private Hashtable<String, String> _requestHeaders; private Hashtable<String, String> _queryStrings; private StringBuffer _messagetBody; public HttpRequestParser() { _requestHeaders = new Hashtable<String, String>(); _queryStrings = new Hashtable<String, String>(); _messagetBody = new StringBuffer(); } /** * Parse HTTP request. */ public void parseRequest(String request) throws IOException, HttpFormatException { BufferedReader reader = new BufferedReader(new StringReader(request)); setRequestLine(reader.readLine()); // Request-Line parseRequestLine(); String header = reader.readLine(); while (header.length() > 0) { appendHeaderParameter(header); header = reader.readLine(); } String bodyLine = reader.readLine(); while (bodyLine != null) { appendMessageBody(bodyLine); bodyLine = reader.readLine(); } } public String getRequestLine() { return _requestLine; } public String getMethod() { return _method; } public String getURI() { return _uri; } public String getCgiPath() { return _cgi_path; } public void parseRequestLine() throws HttpFormatException { int pos = _requestLine.indexOf(' '); if (pos < 0) { throw new HttpFormatException("Invalid Request-Line: " + _requestLine); } _method = _requestLine.substring(0, pos); int pos2 = pos; while (pos2 < _requestLine.length() && _requestLine.charAt(pos2) == ' ') pos2++; if (pos2 >= _requestLine.length()) { throw new HttpFormatException("Invalid Request-Line: " + _requestLine); } int pos3 = _requestLine.indexOf(' ', pos2); if (pos3 < 0) { throw new HttpFormatException("Invalid Request-Line: " + _requestLine); } _uri = _requestLine.substring(pos2, pos3); parseQueryString(); } public void parseQueryString() { int pos = _uri.indexOf('?'); if (pos < 0) { _cgi_path = _uri; return; } _cgi_path = _uri.substring(0, pos); int nextPos = pos; do { nextPos = _uri.indexOf('&', pos+1); String part; if (nextPos >= 0) { part = _uri.substring(pos + 1, nextPos); } else { part = _uri.substring(pos + 1); } int idx = part.indexOf('='); if (idx >= 0) { _queryStrings.put(part.substring(0, idx), part.substring(idx+1)); } else { _queryStrings.put(part.substring(0, idx), ""); } pos = nextPos; } while (nextPos >= 0); } public String getQueryString(String key) { if (!_queryStrings.containsKey(key)) return null; return _queryStrings.get(key); } private void setRequestLine(String requestLine) throws HttpFormatException { if (requestLine == null || requestLine.length() == 0) { throw new HttpFormatException("Invalid Request-Line: " + requestLine); } _requestLine = requestLine; } private void appendHeaderParameter(String header) throws HttpFormatException { int idx = header.indexOf(":"); if (idx == -1) { throw new HttpFormatException("Invalid Header Parameter: " + header); } _requestHeaders.put(header.substring(0, idx), header.substring(idx + 1, header.length())); } /** * The message-body (if any) of an HTTP message is used to carry the * entity-body associated with the request or response. The message-body * differs from the entity-body only when a transfer-coding has been * applied, as indicated by the Transfer-Encoding header field (section * 14.41). * @return String with message-body */ public String getMessageBody() { return _messagetBody.toString(); } private void appendMessageBody(String bodyLine) { _messagetBody.append(bodyLine).append("\r\n"); } /** * For list of available headers refer to sections: 4.5, 5.3, 7.1 of RFC 2616 * @param headerName Name of header * @return String with the value of the header or null if not found. */ public String getHeaderParam(String headerName){ return _requestHeaders.get(headerName); } }