HTTP.java 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. package de.tudarmstadt.informatik.hostage.protocol;
  2. import java.security.SecureRandom;
  3. import java.text.SimpleDateFormat;
  4. import java.util.ArrayList;
  5. import java.util.Calendar;
  6. import java.util.List;
  7. import java.util.Locale;
  8. import java.util.TimeZone;
  9. import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
  10. import de.tudarmstadt.informatik.hostage.wrapper.Packet;
  11. /**
  12. * HTTP protocol.
  13. * Implementation of RFC document 1945.
  14. * It can handle the following requests: GET, HEAD, TRACE, POST, DELETE.
  15. * For all other requests '400 Bad Request' will be replied.
  16. * @author Wulf Pfeiffer
  17. */
  18. public class HTTP implements Protocol {
  19. @Override
  20. public int getDefaultPort() {
  21. return 80;
  22. }
  23. @Override
  24. public TALK_FIRST whoTalksFirst() {
  25. return TALK_FIRST.CLIENT;
  26. }
  27. @Override
  28. public List<Packet> processMessage(Packet requestPacket) {
  29. String request = null;
  30. if (requestPacket != null) {
  31. request = requestPacket.toString();
  32. }
  33. List<Packet> responsePackets = new ArrayList<Packet>();
  34. this.request = request;
  35. if(!request.contains(httpVersion)){
  36. responsePackets.add(buildPacket(STATUS_CODE_505, ""));
  37. } else if(request.contains(GET)) {
  38. responsePackets.add(buildPacket(STATUS_CODE_200, GET));
  39. } else if(request.contains(HEAD)) {
  40. responsePackets.add(buildPacket(STATUS_CODE_200, HEAD));
  41. } else if(request.contains(TRACE)){
  42. responsePackets.add(buildPacket(STATUS_CODE_200, TRACE));
  43. } else if(request.contains(OPTIONS)){
  44. responsePackets.add(buildPacket(STATUS_CODE_400, OPTIONS));
  45. } else if(request.contains(POST)){
  46. responsePackets.add(buildPacket(STATUS_CODE_200, POST));
  47. } else if(request.contains(PUT)){
  48. responsePackets.add(buildPacket(STATUS_CODE_400, PUT));
  49. } else if(request.contains(DELETE)){
  50. responsePackets.add(buildPacket(STATUS_CODE_200, DELETE));
  51. } else if(request.contains(CONNECT)){
  52. responsePackets.add(buildPacket(STATUS_CODE_400, CONNECT));
  53. } else {
  54. responsePackets.add(buildPacket(STATUS_CODE_400, ""));
  55. }
  56. return responsePackets;
  57. }
  58. @Override
  59. public boolean isClosed() {
  60. return true;
  61. }
  62. @Override
  63. public boolean isSecure() {
  64. return false;
  65. }
  66. @Override
  67. public Class<String> getType() {
  68. return String.class;
  69. }
  70. @Override
  71. public String toString() {
  72. return "HTTP";
  73. }
  74. /**
  75. * Builds a html response that can be sent
  76. * @param code response code that was determined
  77. * @param type request type that was sent by the client
  78. * @return the html response
  79. */
  80. private Packet buildPacket(String code, String type) {
  81. String document = "";
  82. if (type.equals(GET)) {
  83. document = htmlDocument;
  84. } else if (type.equals(HEAD) || type.equals(DELETE)) {
  85. document = "";
  86. } else if (type.equals(TRACE)) {
  87. document = request;
  88. } else {
  89. document = errorHtmlPrefix + " " + code + errorHtmlSuffix;
  90. }
  91. return new Packet(httpVersion + " " + code + headerPrefix + document.length() + headerSuffix + document);
  92. }
  93. /**
  94. * Get the current time in html header format.
  95. * @return the formatted server time.
  96. */
  97. private static String getServerTime() {
  98. Calendar calendar = Calendar.getInstance();
  99. SimpleDateFormat dateFormat = new SimpleDateFormat(
  100. "EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
  101. dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
  102. return dateFormat.format(calendar.getTime());
  103. }
  104. /** Whole request that was sent by the client */
  105. private String request = "";
  106. //version stuff
  107. private static String[][][] possibleHttpVersions = {
  108. {{"Apache/2.0."},{"28","32","35","36","39","40","42","43","44","45","46","47","48","49","50","51","52","53","54","55","58","59","61","63","64","65"}},
  109. {{"Apache/2.2."},{"0","2","3","4","6","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25"}},
  110. {{"Apache/2.3."},{"4","5","6","8","10","11","12","14","15","16"}},
  111. {{"Apache/2.4."},{"1","2","3","4","6"}}
  112. };
  113. private static String initServerVersion() {
  114. SecureRandom rndm = new SecureRandom();
  115. int majorVersion = rndm.nextInt(possibleHttpVersions.length);
  116. return possibleHttpVersions[majorVersion][0][0] + possibleHttpVersions[majorVersion][1][rndm.nextInt(possibleHttpVersions[majorVersion][1].length)];
  117. }
  118. private String httpVersion = "HTTP/1.1";
  119. private static String serverVersion = initServerVersion();
  120. private static String htmlDocumentContent = HelperUtils.getRandomString(32, false);
  121. //request codes
  122. private static final String OPTIONS = "OPTIONS";
  123. private static final String GET = "GET";
  124. private static final String HEAD = "HEAD";
  125. private static final String POST = "POST";
  126. private static final String PUT = "PUT";
  127. private static final String DELETE = "DELETE";
  128. private static final String TRACE = "TRACE";
  129. private static final String CONNECT = "CONNECT";
  130. private static final String STATUS_CODE_200 = "200 OK\r\n";
  131. private static final String STATUS_CODE_400 = "400 Bad Request\r\n";
  132. private static final String STATUS_CODE_505 = "505 HTTP Version not supported\r\n";
  133. //html header pre and suffix
  134. private String headerPrefix =
  135. "Date: " + getServerTime() + "\r\n" +
  136. "Server: " + serverVersion + " \r\n" +
  137. "Vary: Accept-Encoding\r\n" +
  138. "Content-Length: ";
  139. private String headerSuffix =
  140. "\r\n" +
  141. "Keep-Alive: timeout=5, max=100\r\n" +
  142. "Connection: Keep-Alive\r\n" +
  143. "Content-Type: text/html\r\n" +
  144. "\r\n";
  145. //html website
  146. private String htmlDocument =
  147. "<!doctype html>\n" +
  148. "<html lang=\"en\">\n" +
  149. "<head>\n" +
  150. "<meta charset=\"UTF-8\">\n" +
  151. "<title>" + htmlDocumentContent + "</title>\n" +
  152. "<body>" + htmlDocumentContent + "</body>\n" +
  153. "</head>\n" +
  154. "</html>";
  155. //html error pre and suffix
  156. private String errorHtmlPrefix =
  157. "<!doctype html>\n" +
  158. "<html lang=\"en\">\n" +
  159. "<head>\n" +
  160. "<meta charset=\"UTF-8\">\n" +
  161. "<title>";
  162. private String errorHtmlSuffix =
  163. "</title>\n" +
  164. "</head>\n" +
  165. "</html>";
  166. /**
  167. * Sets the html document content for HTTP and HTTPS.
  168. *
  169. * @param htmlDocumentContent
  170. */
  171. public static void setHtmlDocumentContent(String htmlDocumentContent) {
  172. HTTP.htmlDocumentContent = htmlDocumentContent;
  173. }
  174. }