HttpPrintStream is now using the HttpHeader object instead of having internal variables aalso added some additional test classes

This commit is contained in:
Ziver Koc 2020-09-16 01:01:32 +02:00
parent 8a72e2bc01
commit ad3cd8a8e8
13 changed files with 604 additions and 250 deletions

View file

@ -29,49 +29,69 @@ import zutil.converter.Converter;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
public class HttpHeader { public class HttpHeader {
private boolean request = true; private boolean isRequest = true;
private String type = "GET";
private String url = "/"; /** Specifies the protocol that should be used */
private HashMap<String, String> urlAttributes; private String protocol = "HTTP";
/** The protocol version specified in the header */
private float protocolVersion = 1.0f; private float protocolVersion = 1.0f;
private int statusCode = 200;
/** HTTP type specified in a HTTP request, e.g GET POST DELETE PUT etc */
private String requestType = "GET";
/** String containing the target URL */
private String requestUrl = "/";
/** Map containing all the properties from the URL */
private Map<String, String> requestUrlAttributes = new HashMap<>();
/** Status code specified in a HTTP response message */
private int responseStatusCode = 200;
/** An Map of all header fields */
private Map<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
/** An Map of all cookies */
private Map<String, String> cookies = new HashMap<>();
private InputStream in; private InputStream in;
// Parameters
private HashMap<String, String> headers;
private HashMap<String, String> cookies;
public HttpHeader() { }
public HttpHeader() {
urlAttributes = new HashMap<>();
headers = new HashMap<>();
cookies = new HashMap<>();
}
/** /**
* @return true if this header represents a server response * @return true if this header represents a server response
*/ */
public boolean isResponse() { public boolean isResponse() {
return !request; return !isRequest;
} }
/** /**
* @return true if this header represents a client request * @return true if this header represents a client request
*/ */
public boolean isRequest() { public boolean isRequest() {
return request; return isRequest;
} }
/** public void setIsRequest(boolean request) {
* @return the HTTP message type( ex. GET,POST...) this.isRequest = request;
*/
public String getRequestType() {
return type;
} }
/**
* @return the protocol specified in the header. e.g. HTTP, HTTPS, RTSP etc.
*/
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
/** /**
* @return the protocol version from this header * @return the protocol version from this header
*/ */
@ -79,51 +99,87 @@ public class HttpHeader {
return protocolVersion; return protocolVersion;
} }
public void setProtocolVersion(float version) {
this.protocolVersion = version;
}
/**
* @return the HTTP message type( ex. GET,POST...)
*/
public String getRequestType() {
return requestType;
}
public void setRequestType(String type) {
this.requestType = type;
}
/** /**
* @return the HTTP Return Code from a Server * @return the HTTP Return Code from a Server
*/ */
public int getStatusCode() { public int getResponseStatusCode() {
return statusCode; return responseStatusCode;
} }
public void setResponseStatusCode(int code) {
this.responseStatusCode = code;
}
/** /**
* @return the URL that the client sent the server * @return the URL that the client sent the server
*/ */
public String getRequestURL() { public String getRequestURL() {
return url; return requestUrl;
}
public void setRequestURL(String url) {
this.requestUrl = url.trim().replaceAll("//", "/");
} }
/** /**
* @return parses out the page name from the request url and returns it. * @return parses out the page name from the request url and returns it.
*/ */
public String getRequestPage() { public String getRequestPage() {
if (url != null) { if (requestUrl != null) {
int start = 0; int start = 0;
if (url.charAt(0) == '/') if (requestUrl.charAt(0) == '/')
start = 1; start = 1;
int end = url.indexOf('?'); int end = requestUrl.indexOf('?');
if (end < 0) if (end < 0)
end = url.length(); end = requestUrl.length();
return url.substring(start, end); return requestUrl.substring(start, end);
} }
return null; return null;
} }
/** /**
* @return a Iterator with all defined url keys * @return a Iterator with all defined url keys
*/ */
public Iterator<String> getURLAttributeKeys() { public Iterator<String> getURLAttributeKeys() {
return urlAttributes.keySet().iterator(); return requestUrlAttributes.keySet().iterator();
} }
/** /**
* @return the URL attribute value of the given name. null if there is no such attribute * @return the URL attribute value of the given name. null if there is no such attribute
*/ */
public String getURLAttribute(String name) { public String getURLAttribute(String name) {
return urlAttributes.get(name); return requestUrlAttributes.get(name);
} }
protected Map<String, String> getURLAttributeMap() {
return requestUrlAttributes;
}
public void setURLAttribute(String key, String value) {
this.requestUrlAttributes.put(key, value);
}
/** /**
* @return a Iterator with all defined headers * @return a Iterator with all defined headers
*/ */
@ -138,6 +194,19 @@ public class HttpHeader {
return headers.get(name.toUpperCase()); return headers.get(name.toUpperCase());
} }
protected Map<String, String> getHeaderMap() {
return headers;
}
public void setHeader(String key, String value) {
this.headers.put(key, value);
}
public void setHeaders(Map headerSrc) {
this.headers.putAll(headerSrc);
}
/** /**
* @return a Iterator with all defined cookies * @return a Iterator with all defined cookies
*/ */
@ -152,6 +221,19 @@ public class HttpHeader {
return cookies.get(name); return cookies.get(name);
} }
protected Map<String, String> getCookieMap() {
return cookies;
}
public void setCookie(String key, String value) {
this.cookies.put(key, value);
}
public void setCookies(Map cookieSrc) {
this.cookies.putAll(cookieSrc);
}
/** /**
* @return a Reader that contains the body of the http request. * @return a Reader that contains the body of the http request.
*/ */
@ -159,61 +241,20 @@ public class HttpHeader {
return in; return in;
} }
public void setIsRequest(boolean request) {
this.request = request;
}
public void setRequestType(String type) {
this.type = type;
}
public void setProtocolVersion(float version) {
this.protocolVersion = version;
}
public void setStatusCode(int code) {
this.statusCode = code;
}
public void setRequestURL(String url) {
this.url = url.trim().replaceAll("//", "/");
}
public void setHeader(String key, String value) {
this.headers.put(key.toUpperCase(), value);
}
protected void setInputStream(InputStream in) { protected void setInputStream(InputStream in) {
this.in = in; this.in = in;
} }
protected HashMap<String, String> getHeaderMap() {
return headers;
}
protected HashMap<String, String> getCookieMap() {
return cookies;
}
protected HashMap<String, String> getUrlAttributeMap() {
return urlAttributes;
}
public String toString() { public String toString() {
StringBuilder tmp = new StringBuilder(); StringBuilder tmp = new StringBuilder();
tmp.append("{Type: ").append(type); tmp.append("{Type: ").append(requestType);
tmp.append(", HTTP_version: HTTP/").append(protocolVersion); tmp.append(", HTTP_version: ").append(protocol).append("/").append(protocolVersion);
if (url == null) tmp.append(", URL: \"").append((String) requestUrl).append('\"');
tmp.append(", URL: null");
else
tmp.append(", URL: \"").append(url).append('\"');
tmp.append(", URL_attr: ").append(toStringAttributes()); tmp.append(", URL_attr: ").append(toStringAttributes());
tmp.append(", Headers: ").append(toStringHeaders()); tmp.append(", Headers: ").append(toStringHeaders());
tmp.append(", Cookies: ").append(toStringCookies()); tmp.append(", Cookies: ").append(toStringCookies());
tmp.append('}'); tmp.append('}');
return tmp.toString(); return tmp.toString();
} }
@ -224,7 +265,40 @@ public class HttpHeader {
return Converter.toString(cookies); return Converter.toString(cookies);
} }
public String toStringAttributes() { public String toStringAttributes() {
return Converter.toString(urlAttributes); return Converter.toString(requestUrlAttributes);
} }
public String getResponseStatusString() {
return getResponseStatusString(responseStatusCode);
}
public static String getResponseStatusString(int type) {
switch (type) {
case 100:
return "Continue";
case 200:
return "OK";
case 301:
return "Moved Permanently";
case 304:
return "Not Modified";
case 307:
return "Temporary Redirect";
case 400:
return "Bad Request";
case 401:
return "Unauthorized";
case 403:
return "Forbidden";
case 404:
return "Not Found";
case 500:
return "Internal Server Error";
case 501:
return "Not Implemented";
default:
return "";
}
}
} }

View file

@ -107,7 +107,7 @@ public class HttpHeaderParser {
if (statusLine.startsWith("HTTP/")) { if (statusLine.startsWith("HTTP/")) {
header.setIsRequest(false); header.setIsRequest(false);
header.setProtocolVersion(Float.parseFloat(statusLine.substring(5, 8))); header.setProtocolVersion(Float.parseFloat(statusLine.substring(5, 8)));
header.setStatusCode(Integer.parseInt(statusLine.substring(9, statusLine.indexOf(' ', 9)))); header.setResponseStatusCode(Integer.parseInt(statusLine.substring(9, statusLine.indexOf(' ', 9))));
} }
// Client Request // Client Request
else if (statusLine.contains("HTTP/")) { else if (statusLine.contains("HTTP/")) {
@ -121,7 +121,7 @@ public class HttpHeaderParser {
if (index > -1) { if (index > -1) {
header.setRequestURL(statusLine.substring(0, index)); header.setRequestURL(statusLine.substring(0, index));
statusLine = statusLine.substring(index + 1); statusLine = statusLine.substring(index + 1);
parseURLParameters(header.getUrlAttributeMap(), statusLine); parseURLParameters(header.getURLAttributeMap(), statusLine);
} else { } else {
header.setRequestURL(statusLine); header.setRequestURL(statusLine);
} }
@ -201,7 +201,7 @@ public class HttpHeaderParser {
* @param urlAttributes is the String containing all the attributes * @param urlAttributes is the String containing all the attributes
*/ */
public static void parseURLParameters(HttpHeader header, String urlAttributes) { public static void parseURLParameters(HttpHeader header, String urlAttributes) {
parseURLParameters(header.getUrlAttributeMap(), urlAttributes); parseURLParameters(header.getURLAttributeMap(), urlAttributes);
} }
/** /**

View file

@ -45,47 +45,19 @@ public class HttpPrintStream extends OutputStream {
RESPONSE RESPONSE
} }
/**
* The actual output stream private HttpHeader header = new HttpHeader();
*/
private PrintStream out;
/**
* This defines the type of message that will be generated
*/
private final HttpMessageType messageType;
/**
* Specifies the protocol that should be used
*/
private String protocol = "HTTP";
/**
* Specifies the protocol version that should be used
*/
private String protocolVersion = "1.0";
/**
* The status code of the message, ONLY for response
*/
private Integer responseStatusCode = 200;
/**
* The request type of the message ONLY for request
*/
private String requestType;
/**
* The requesting url ONLY for request
*/
private String requestUrl;
/**
* An Map of all the header values
*/
private HashMap<String, String> headers = new HashMap<>();
/**
* An Map of all the cookies
*/
private HashMap<String, String> cookies = new HashMap<>();
/** /**
* The header data buffer, buffering is enabled if this variable is not null * The header data buffer, buffering is enabled if this variable is not null
*/ */
private StringBuffer buffer = null; private StringBuffer buffer = null;
/**
* The actual output stream
*/
private PrintStream out;
/** /**
* Creates an new instance of HttpPrintStream with * Creates an new instance of HttpPrintStream with
@ -106,7 +78,7 @@ public class HttpPrintStream extends OutputStream {
*/ */
public HttpPrintStream(OutputStream out, HttpMessageType type) { public HttpPrintStream(OutputStream out, HttpMessageType type) {
this.out = new PrintStream(out); this.out = new PrintStream(out);
this.messageType = type; header.setIsRequest(type == HttpMessageType.REQUEST);
} }
@ -129,8 +101,8 @@ public class HttpPrintStream extends OutputStream {
/** /**
* Set the http version that will be used in the http header * Set the http version that will be used in the http header
*/ */
public void setProtocolVersion(String version) { public void setProtocolVersion(float version) {
this.protocolVersion = version; header.setProtocolVersion(version);
} }
/** /**
@ -141,9 +113,9 @@ public class HttpPrintStream extends OutputStream {
* @throws IllegalStateException if the header has already been sent * @throws IllegalStateException if the header has already been sent
*/ */
public void setCookie(String key, String value) { public void setCookie(String key, String value) {
if (cookies == null) headerSentCheck();
throw new IllegalStateException("Header already sent");
cookies.put(key, value); header.setCookie(key, value);
} }
/** /**
@ -154,9 +126,9 @@ public class HttpPrintStream extends OutputStream {
* @throws IllegalStateException if the header has already been sent * @throws IllegalStateException if the header has already been sent
*/ */
public void setHeader(String key, String value) { public void setHeader(String key, String value) {
if (headers == null) headerSentCheck();
throw new IllegalStateException("Header already sent");
headers.put(key, value); header.setHeader(key, value);
} }
/** /**
@ -165,12 +137,12 @@ public class HttpPrintStream extends OutputStream {
* @param code the code from 100 up to 599 * @param code the code from 100 up to 599
* @throws IllegalStateException if the header has already been sent or the message type is wrong * @throws IllegalStateException if the header has already been sent or the message type is wrong
*/ */
public void setStatusCode(int code) { public void setResponseStatusCode(int code) {
if (messageType != HttpMessageType.RESPONSE) if (!header.isResponse())
throw new IllegalStateException("Status Code is only available with HTTP requests"); throw new IllegalStateException("Status Code is only available with HTTP requests");
if (responseStatusCode == null) headerSentCheck();
throw new IllegalStateException("Header already sent.");
responseStatusCode = code; header.setResponseStatusCode(code);
} }
/** /**
@ -180,11 +152,11 @@ public class HttpPrintStream extends OutputStream {
* @throws IllegalStateException if the header has already been sent or the message type is wrong * @throws IllegalStateException if the header has already been sent or the message type is wrong
*/ */
public void setRequestType(String req_type) { public void setRequestType(String req_type) {
if (messageType != HttpMessageType.REQUEST) if (!header.isRequest())
throw new IllegalStateException("Request Message Type is only available with HTTP requests"); throw new IllegalStateException("Request Message Type is only available with HTTP requests");
if (req_type == null) headerSentCheck();
throw new IllegalStateException("Header already sent.");
this.requestType = req_type; header.setRequestType(req_type);
} }
/** /**
@ -194,19 +166,19 @@ public class HttpPrintStream extends OutputStream {
* @throws IllegalStateException if the header has already been sent or the message type is wrong * @throws IllegalStateException if the header has already been sent or the message type is wrong
*/ */
public void setRequestURL(String req_url) { public void setRequestURL(String req_url) {
if (messageType != HttpMessageType.REQUEST) if (!header.isRequest())
throw new IllegalStateException("Request URL is only available with a HTTP request"); throw new IllegalStateException("Request URL is only available with a HTTP request");
if (req_url == null) headerSentCheck();
throw new IllegalStateException("Header already sent.");
this.requestUrl = req_url; header.setRequestURL(req_url);
} }
protected void setHeaders(HashMap<String, String> map) { protected void setHeaders(HashMap<String, String> map) {
headers = map; header.setHeaders(map);
} }
protected void setCookies(HashMap<String, String> map) { protected void setCookies(HashMap<String, String> map) {
cookies = map; header.setCookies(map);
} }
@ -246,42 +218,40 @@ public class HttpPrintStream extends OutputStream {
* Method will directly print the provided String, if any headers are set then they will firstly be sent and cleared proceeded by the given String. * Method will directly print the provided String, if any headers are set then they will firstly be sent and cleared proceeded by the given String.
*/ */
private void printForced(String s) { private void printForced(String s) {
if (responseStatusCode != null) { if (header != null) {
if (messageType == HttpMessageType.REQUEST) if (header.isRequest())
out.print(requestType + " " + requestUrl + " " + protocol + "/" + protocolVersion); out.print(header.getRequestType() + " " + header.getRequestURL() + " " + header.getProtocol() + "/" + header.getProtocolVersion());
else else
out.print("HTTP/" + protocolVersion + " " + responseStatusCode + " " + getStatusString(responseStatusCode)); out.print(header.getProtocol() + "/" + header.getProtocolVersion() + " " + header.getResponseStatusCode() + " " + header.getResponseStatusString());
out.println(); out.println();
responseStatusCode = null;
requestType = null;
requestUrl = null;
}
if (headers != null) { // Send headers
for (String key : headers.keySet()) {
out.println(key + ": " + headers.get(key)); for (String key : header.getHeaderMap().keySet()) {
out.println(key + ": " + header.getHeader(key));
} }
headers = null;
}
if (cookies != null) { // Send cookies
if (!cookies.isEmpty()) {
if (messageType == HttpMessageType.REQUEST) { if (!header.getCookieMap().isEmpty()) {
out.print("Cookie: "); if (header.isRequest()) {
for (String key : cookies.keySet()) { out.print("Cookie:");
out.print(key + "=" + cookies.get(key) + "; "); for (String key : header.getCookieMap().keySet()) {
out.print(" " + key + "=" + header.getCookie(key) + ";");
} }
out.println(); out.println();
} else { } else {
for (String key : cookies.keySet()) { for (String key : header.getCookieMap().keySet()) {
out.print("Set-Cookie: " + key + "=" + cookies.get(key) + ";"); out.print("Set-Cookie: " + key + "=" + header.getCookie(key) + ";");
out.println(); out.println();
} }
} }
} }
out.println(); out.println();
cookies = null;
header = null;
} }
out.print(s); out.print(s);
} }
@ -296,7 +266,12 @@ public class HttpPrintStream extends OutputStream {
* @return true if headers has been sent. The setHeader, setStatusCode, setCookie method will throw IllegalStateException * @return true if headers has been sent. The setHeader, setStatusCode, setCookie method will throw IllegalStateException
*/ */
public boolean isHeaderSent() { public boolean isHeaderSent() {
return responseStatusCode == null && headers == null && cookies == null; return header == null;
}
public void headerSentCheck() {
if (isHeaderSent())
throw new IllegalStateException("Header already sent.");
} }
@ -319,7 +294,7 @@ public class HttpPrintStream extends OutputStream {
if (isBufferEnabled()) { if (isBufferEnabled()) {
printForced(buffer.toString()); printForced(buffer.toString());
buffer.delete(0, buffer.length()); buffer.delete(0, buffer.length());
} else if (responseStatusCode != null || headers != null || cookies != null) { } else if (!isHeaderSent()) {
printOrBuffer(""); printOrBuffer("");
} }
} }
@ -342,59 +317,13 @@ public class HttpPrintStream extends OutputStream {
out.write(buf, off, len); out.write(buf, off, len);
} }
private String getStatusString(int type) {
switch (type) {
case 100:
return "Continue";
case 200:
return "OK";
case 301:
return "Moved Permanently";
case 304:
return "Not Modified";
case 307:
return "Temporary Redirect";
case 400:
return "Bad Request";
case 401:
return "Unauthorized";
case 403:
return "Forbidden";
case 404:
return "Not Found";
case 500:
return "Internal Server Error";
case 501:
return "Not Implemented";
default:
return "";
}
}
public String toString() { public String toString() {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
str.append("{http_type: ").append(messageType); if (!isHeaderSent())
if (responseStatusCode != null) { str.append(header);
if (messageType == HttpMessageType.REQUEST) { else
str.append(", req_type: ").append(requestType); str.append("{HEADER ALREADY SENT}");
if (requestUrl == null)
str.append(", req_url: null");
else
str.append(", req_url: \"").append(requestUrl).append('\"');
} else if (messageType == HttpMessageType.RESPONSE) {
str.append(", status_code: ").append(responseStatusCode);
str.append(", status_str: ").append(getStatusString(responseStatusCode));
}
if (headers != null) {
str.append(", Headers: ").append(Converter.toString(headers));
}
if (cookies != null) {
str.append(", Cookies: ").append(Converter.toString(cookies));
}
} else
str.append(", HEADER ALREADY SENT ");
str.append('}');
return str.toString(); return str.toString();
} }

View file

@ -210,22 +210,22 @@ public class HttpServer extends ThreadedTCPNetworkServer{
} }
//**************************** RESPONSE ************************************ //**************************** RESPONSE ************************************
out.setProtocolVersion("1.0"); out.setProtocolVersion(1.0f);
out.setStatusCode(200); out.setResponseStatusCode(200);
out.setHeader("Server", SERVER_NAME); out.setHeader("Server", SERVER_NAME);
out.setHeader("Content-Type", "text/html"); out.setHeader("Content-Type", "text/html");
if (header.getRequestURL() != null && pages.containsKey(header.getRequestURL())) { if (header.getRequestURL() != null && pages.containsKey(header.getRequestURL())) {
HttpPage page = pages.get(header.getRequestURL()); HttpPage page = pages.get(header.getRequestURL());
page.respond(out, header, session, header.getCookieMap(), header.getUrlAttributeMap()); page.respond(out, header, session, header.getCookieMap(), header.getURLAttributeMap());
if (LogUtil.isLoggable(page.getClass(), Level.FINER)) if (LogUtil.isLoggable(page.getClass(), Level.FINER))
logRequest(header, session, time); logRequest(header, session, time);
} else if (header.getRequestURL() != null && defaultPage != null) { } else if (header.getRequestURL() != null && defaultPage != null) {
defaultPage.respond(out, header, session, header.getCookieMap(), header.getUrlAttributeMap()); defaultPage.respond(out, header, session, header.getCookieMap(), header.getURLAttributeMap());
if (LogUtil.isLoggable(defaultPage.getClass(), Level.FINER)) if (LogUtil.isLoggable(defaultPage.getClass(), Level.FINER))
logRequest(header, session, time); logRequest(header, session, time);
} else { } else {
out.setStatusCode(404); out.setResponseStatusCode(404);
out.println("404 Page Not Found: " + header.getRequestURL()); out.println("404 Page Not Found: " + header.getRequestURL());
logger.warning("Page not defined: " + header.getRequestURL()); logger.warning("Page not defined: " + header.getRequestURL());
} }
@ -233,18 +233,15 @@ public class HttpServer extends ThreadedTCPNetworkServer{
} catch (Exception e) { } catch (Exception e) {
logRequest(header, session, time); logRequest(header, session, time);
logger.log(Level.SEVERE, "500 Internal Server Error", e); logger.log(Level.SEVERE, "500 Internal Server Error", e);
try {
if (!out.isHeaderSent()) if (!out.isHeaderSent())
out.setStatusCode(500); out.setResponseStatusCode(500);
if (e.getMessage() != null) if (e.getMessage() != null)
out.println("500 Internal Server Error: " + e.getMessage()); out.println("500 Internal Server Error: " + e.getMessage());
else if (e.getCause() != null) { else if (e.getCause() != null) {
out.println("500 Internal Server Error: " + e.getCause().getMessage()); out.println("500 Internal Server Error: " + e.getCause().getMessage());
} else { } else {
out.println("500 Internal Server Error: " + e); out.println("500 Internal Server Error: " + e);
}
}catch(IOException ioe){
logger.log(Level.SEVERE, null, ioe);
} }
} }
finally { finally {

View file

@ -69,12 +69,12 @@ public class HttpDigestAuthPage implements HttpPage{
if (headers.getHeader(HTTP_CLIENT_HEADER) == null || !session.containsKey(AUTH_NONCE)) { if (headers.getHeader(HTTP_CLIENT_HEADER) == null || !session.containsKey(AUTH_NONCE)) {
session.put(AUTH_NONCE, generateNonce()); session.put(AUTH_NONCE, generateNonce());
out.setStatusCode(401); out.setResponseStatusCode(401);
out.setHeader(HTTP_AUTH_HEADER, generateAuthHeader((String) session.get(AUTH_NONCE))); out.setHeader(HTTP_AUTH_HEADER, generateAuthHeader((String) session.get(AUTH_NONCE)));
out.println("401 Unauthorized"); out.println("401 Unauthorized");
} }
else if ( ! headers.getHeader(HTTP_CLIENT_HEADER).startsWith(AUTH_TYPE)){ else if ( ! headers.getHeader(HTTP_CLIENT_HEADER).startsWith(AUTH_TYPE)){
out.setStatusCode(501); out.setResponseStatusCode(501);
out.println("501 Not Implemented"); out.println("501 Not Implemented");
} }
else{ else{
@ -91,7 +91,7 @@ public class HttpDigestAuthPage implements HttpPage{
targetPage.respond(out, headers, session, cookie, request); targetPage.respond(out, headers, session, cookie, request);
} }
else{ else{
out.setStatusCode(403); out.setResponseStatusCode(403);
out.println("403 Forbidden"); out.println("403 Forbidden");
} }
} }

View file

@ -122,12 +122,12 @@ public class HttpFilePage implements HttpPage{
}catch (FileNotFoundException | SecurityException e){ }catch (FileNotFoundException | SecurityException e){
if(!out.isHeaderSent()) if(!out.isHeaderSent())
out.setStatusCode(404); out.setResponseStatusCode(404);
log.log(Level.WARNING, e.getMessage()); log.log(Level.WARNING, e.getMessage());
out.println("404 Page Not Found: " + headers.getRequestURL()); out.println("404 Page Not Found: " + headers.getRequestURL());
} catch (IOException e){ } catch (IOException e){
if(!out.isHeaderSent()) if(!out.isHeaderSent())
out.setStatusCode(500); out.setResponseStatusCode(500);
log.log(Level.WARNING, null, e); log.log(Level.WARNING, null, e);
out.println("500 Internal Server Error: "+e.getMessage() ); out.println("500 Internal Server Error: "+e.getMessage() );
} }
@ -140,7 +140,7 @@ public class HttpFilePage implements HttpPage{
if (eTag != null && headers.getHeader("If-None-Match") != null && if (eTag != null && headers.getHeader("If-None-Match") != null &&
eTag.equals(StringUtil.trimQuotes(headers.getHeader("If-None-Match")))){ // File has not changed eTag.equals(StringUtil.trimQuotes(headers.getHeader("If-None-Match")))){ // File has not changed
out.setStatusCode(304); out.setResponseStatusCode(304);
} else { } else {
deliverFile(file, out); deliverFile(file, out);
} }

View file

@ -32,7 +32,7 @@ public class HttpRedirectPage implements HttpPage{
Map<String, String> cookie, Map<String, String> cookie,
Map<String, String> request) throws IOException { Map<String, String> request) throws IOException {
out.setStatusCode((permanent ? 301 : 307)); out.setResponseStatusCode((permanent ? 301 : 307));
out.setHeader("Location", redirectUrl); out.setHeader("Location", redirectUrl);
out.print( out.print(
"<!DOCTYPE HTML>\n" + "<!DOCTYPE HTML>\n" +

View file

@ -187,7 +187,7 @@ public class SSDPServer extends ThreadedUDPNetwork implements ThreadedUDPNetwork
// Generate the SSDP response // Generate the SSDP response
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
HttpPrintStream http = new HttpPrintStream( buffer ); HttpPrintStream http = new HttpPrintStream( buffer );
http.setStatusCode(200); http.setResponseStatusCode(200);
http.setHeader("Location", services.get(st).getLocation() ); http.setHeader("Location", services.get(st).getLocation() );
http.setHeader("USN", services.get(st).getUSN() ); http.setHeader("USN", services.get(st).getUSN() );
http.setHeader("Server", SERVER_INFO ); http.setHeader("Server", SERVER_INFO );

View file

@ -37,7 +37,7 @@ import java.util.UUID;
/** /**
* This class contains information about a service from * This class contains information about a service from
* or through the SSDP protocol * or through the SSDP protocol
* *
* @author Ziver * @author Ziver
*/ */
public class StandardSSDPInfo implements SSDPServiceInfo, SSDPCustomInfo{ public class StandardSSDPInfo implements SSDPServiceInfo, SSDPCustomInfo{
@ -138,11 +138,8 @@ public class StandardSSDPInfo implements SSDPServiceInfo, SSDPCustomInfo{
} }
@Override @Override
public void writeHeaders(HttpPrintStream http) { public void writeHeaders(HttpPrintStream http) {
try { for (String key : headers.keySet()) {
for (String key : headers.keySet()) http.setHeader(key, headers.get(key));
http.setHeader(key, headers.get(key));
}catch(IOException e){
e.printStackTrace();
} }
} }
@Override @Override

View file

@ -0,0 +1,158 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package zutil.net.http;
import org.junit.Test;
import static org.junit.Assert.*;
public class HttpHeaderTest {
@Test
public void setIsRequest() {
HttpHeader header = new HttpHeader();
assertTrue(header.isRequest());
assertFalse(header.isResponse());
header.setIsRequest(false);
assertFalse(header.isRequest());
assertTrue(header.isResponse());
}
@Test
public void setProtocol() {
HttpHeader header = new HttpHeader();
assertEquals("HTTP", header.getProtocol());
header.setProtocol("RTSP");
assertEquals("RTSP", header.getProtocol());
}
@Test
public void setProtocolVersion() {
HttpHeader header = new HttpHeader();
assertEquals(1.0f, header.getProtocolVersion(), 0);
header.setProtocolVersion(1.1f);
assertEquals(1.1f, header.getProtocolVersion(), 0);
}
@Test
public void setRequestType() {
HttpHeader header = new HttpHeader();
assertEquals("GET", header.getRequestType());
header.setRequestType("POST");
assertEquals("POST", header.getRequestType());
}
@Test
public void setResponseStatusCode() {
HttpHeader header = new HttpHeader();
assertEquals(200, header.getResponseStatusCode());
header.setResponseStatusCode(400);
assertEquals(400, header.getResponseStatusCode());
}
@Test
public void setRequestURL() {
HttpHeader header = new HttpHeader();
assertEquals("/", header.getRequestURL());
header.setRequestURL("/page/test");
assertEquals("/page/test", header.getRequestURL());
header.setRequestURL(" /page/1test ");
assertEquals("/page/1test", header.getRequestURL());
header.setRequestURL("/page//2test ");
assertEquals("/page/2test", header.getRequestURL());
}
@Test
public void getRequestPage() {
HttpHeader header = new HttpHeader();
header.setRequestURL("/page/test?param=a&dd=tt");
assertEquals("page/test", header.getRequestPage());
}
@Test
public void setURLAttribute() {
HttpHeader header = new HttpHeader();
assertNull(header.getURLAttribute("param1"));
header.setURLAttribute("param1", "value1");
assertEquals("value1", header.getURLAttribute("param1"));
assertNull(header.getURLAttribute("Param1"));
}
@Test
public void setHeader() {
HttpHeader header = new HttpHeader();
assertNull(header.getHeader("param1"));
header.setHeader("param1", "value1");
header.setHeader("param2", "value2");
assertEquals("value1", header.getHeader("param1"));
assertEquals("value1", header.getHeader("PARAM1"));
assertEquals("value2", header.getHeader("param2"));
assertEquals("value2", header.getHeader("Param2"));
header.setHeader("param2", "value3");
assertEquals("value3", header.getHeader("param2"));
}
@Test
public void setCookie() {
HttpHeader header = new HttpHeader();
assertNull(header.getCookie("param1"));
header.setCookie("param1", "value1");
header.setCookie("param2", "value2");
assertEquals("value1", header.getCookie("param1"));
assertEquals("value2", header.getCookie("param2"));
assertNull("value2", header.getCookie("Param2"));
header.setCookie("param2", "value3");
assertEquals("value3", header.getCookie("param2"));
}
@Test
public void getResponseStatusString() {
HttpHeader header = new HttpHeader();
assertEquals("OK", header.getResponseStatusString());
header.setResponseStatusCode(400);
assertEquals("Bad Request", header.getResponseStatusString());
}
}

View file

@ -0,0 +1,198 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package zutil.net.http;
import org.junit.Test;
import zutil.io.StringOutputStream;
import zutil.net.http.HttpPrintStream.HttpMessageType;
import static org.junit.Assert.*;
public class HttpPrintStreamTest {
@Test
public void requestDefaultOutput() {
StringOutputStream out = new StringOutputStream();
HttpPrintStream httpOut = new HttpPrintStream(out, HttpMessageType.REQUEST);
httpOut.flush();
assertEquals(
"GET / HTTP/1.0" + System.lineSeparator() +
System.lineSeparator(),
out.toString()
);
}
@Test
public void requestSetType() {
StringOutputStream out = new StringOutputStream();
HttpPrintStream httpOut = new HttpPrintStream(out, HttpMessageType.REQUEST);
httpOut.setRequestType("POST");
httpOut.flush();
assertEquals(
"POST / HTTP/1.0" + System.lineSeparator() +
System.lineSeparator(),
out.toString()
);
}
@Test
public void requestSetUrl() {
StringOutputStream out = new StringOutputStream();
HttpPrintStream httpOut = new HttpPrintStream(out, HttpMessageType.REQUEST);
httpOut.setRequestURL("/test/path/to/page?param=aa&tt=aa");
httpOut.flush();
assertEquals(
"GET /test/path/to/page?param=aa&tt=aa HTTP/1.0" + System.lineSeparator() +
System.lineSeparator(),
out.toString()
);
}
@Test
public void requestSetCookie() {
StringOutputStream out = new StringOutputStream();
HttpPrintStream httpOut = new HttpPrintStream(out, HttpMessageType.REQUEST);
httpOut.setCookie("Test", "value");
httpOut.flush();
assertEquals(
"GET / HTTP/1.0" + System.lineSeparator() +
"Cookie: Test=value;" + System.lineSeparator() +
System.lineSeparator(),
out.toString()
);
}
@Test
public void requestSetCookieMultiple() {
StringOutputStream out = new StringOutputStream();
HttpPrintStream httpOut = new HttpPrintStream(out, HttpMessageType.REQUEST);
httpOut.setCookie("Test1", "value1");
httpOut.setCookie("Test2", "value2");
httpOut.flush();
assertEquals(
"GET / HTTP/1.0" + System.lineSeparator() +
"Cookie: Test1=value1; Test2=value2;" + System.lineSeparator() +
System.lineSeparator(),
out.toString()
);
}
@Test
public void responseDefaultOutput() {
StringOutputStream out = new StringOutputStream();
HttpPrintStream httpOut = new HttpPrintStream(out, HttpMessageType.RESPONSE);
httpOut.flush();
assertEquals(
"HTTP/1.0 200 OK" + System.lineSeparator() +
System.lineSeparator(),
out.toString()
);
}
@Test
public void responseStatusCode() {
StringOutputStream out = new StringOutputStream();
HttpPrintStream httpOut = new HttpPrintStream(out, HttpMessageType.RESPONSE);
httpOut.setResponseStatusCode(400);
httpOut.flush();
assertEquals(
"HTTP/1.0 400 Bad Request" + System.lineSeparator() +
System.lineSeparator(),
out.toString()
);
}
@Test
public void responseSetCookie() {
StringOutputStream out = new StringOutputStream();
HttpPrintStream httpOut = new HttpPrintStream(out, HttpMessageType.RESPONSE);
httpOut.setCookie("Test", "value");
httpOut.flush();
assertEquals(
"HTTP/1.0 200 OK" + System.lineSeparator() +
"Set-Cookie: Test=value;" + System.lineSeparator() +
System.lineSeparator(),
out.toString()
);
}
@Test
public void responseSetCookieMultiple() {
StringOutputStream out = new StringOutputStream();
HttpPrintStream httpOut = new HttpPrintStream(out, HttpMessageType.RESPONSE);
httpOut.setCookie("Test1", "value1");
httpOut.setCookie("Test2", "value2");
httpOut.flush();
assertEquals(
"HTTP/1.0 200 OK" + System.lineSeparator() +
"Set-Cookie: Test1=value1;" + System.lineSeparator() +
"Set-Cookie: Test2=value2;" + System.lineSeparator() +
System.lineSeparator(),
out.toString()
);
}
@Test
public void setHeader() {
StringOutputStream out = new StringOutputStream();
HttpPrintStream httpOut = new HttpPrintStream(out);
httpOut.setHeader("Test1", "value1");
httpOut.setHeader("Test2", "value2");
httpOut.flush();
assertEquals(
"HTTP/1.0 200 OK" + System.lineSeparator() +
"Test1: value1" + System.lineSeparator() +
"Test2: value2" + System.lineSeparator() +
System.lineSeparator(),
out.toString()
);
}
// TODO @Test
public void enableBuffering() {
}
}

View file

@ -20,8 +20,9 @@ public class HttpTestUtil {
public static HttpHeader makeRequest(HttpPage page, HttpHeader headers) throws IOException { public static HttpHeader makeRequest(HttpPage page, HttpHeader headers) throws IOException {
StringOutputStream buff = new StringOutputStream(); StringOutputStream buff = new StringOutputStream();
HttpPrintStream out = new HttpPrintStream(buff); HttpPrintStream out = new HttpPrintStream(buff);
page.respond(
out, headers, session, new HashMap(), new HashMap()); page.respond(out, headers, session, new HashMap(), new HashMap());
out.flush(); out.flush();
HttpHeaderParser parser = new HttpHeaderParser(buff.toString()); HttpHeaderParser parser = new HttpHeaderParser(buff.toString());
return parser.read(); return parser.read();

View file

@ -36,7 +36,7 @@ public class HttpDigestAuthPageTest {
public void cleanRequest() throws IOException { public void cleanRequest() throws IOException {
HttpHeader rspHeader = HttpTestUtil.makeRequest(page); HttpHeader rspHeader = HttpTestUtil.makeRequest(page);
assertEquals(401, rspHeader.getStatusCode()); assertEquals(401, rspHeader.getResponseStatusCode());
assertNotNull(rspHeader.getHeader("WWW-Authenticate")); assertNotNull(rspHeader.getHeader("WWW-Authenticate"));
assertEquals("Digest", parseAuthType(rspHeader)); assertEquals("Digest", parseAuthType(rspHeader));
Map<String,String> authHeader = parseAuthHeader(rspHeader); Map<String,String> authHeader = parseAuthHeader(rspHeader);
@ -49,21 +49,21 @@ public class HttpDigestAuthPageTest {
@Test @Test
public void authenticate() throws IOException { public void authenticate() throws IOException {
HttpHeader rspHeader = authenticate(PAGE_USERNAME, PAGE_PASSWORD); HttpHeader rspHeader = authenticate(PAGE_USERNAME, PAGE_PASSWORD);
assertEquals(200, rspHeader.getStatusCode()); assertEquals(200, rspHeader.getResponseStatusCode());
assertThat(IOUtil.readContentAsString(rspHeader.getInputStream()), assertThat(IOUtil.readContentAsString(rspHeader.getInputStream()),
containsString(PAGE_CONTENT)); containsString(PAGE_CONTENT));
} }
@Test @Test
public void wrongUsername() throws IOException { public void wrongUsername() throws IOException {
HttpHeader rspHeader = authenticate(PAGE_USERNAME+"wrong", PAGE_PASSWORD); HttpHeader rspHeader = authenticate(PAGE_USERNAME+"wrong", PAGE_PASSWORD);
assertEquals(403, rspHeader.getStatusCode()); assertEquals(403, rspHeader.getResponseStatusCode());
assertThat(IOUtil.readContentAsString(rspHeader.getInputStream()), assertThat(IOUtil.readContentAsString(rspHeader.getInputStream()),
not(containsString(PAGE_CONTENT))); not(containsString(PAGE_CONTENT)));
} }
@Test @Test
public void wrongPassword() throws IOException { public void wrongPassword() throws IOException {
HttpHeader rspHeader = authenticate(PAGE_USERNAME, PAGE_PASSWORD+"wrong"); HttpHeader rspHeader = authenticate(PAGE_USERNAME, PAGE_PASSWORD+"wrong");
assertEquals(403, rspHeader.getStatusCode()); assertEquals(403, rspHeader.getResponseStatusCode());
assertThat(IOUtil.readContentAsString(rspHeader.getInputStream()), assertThat(IOUtil.readContentAsString(rspHeader.getInputStream()),
not(containsString(PAGE_CONTENT))); not(containsString(PAGE_CONTENT)));
} }