Advertisement
nolog1n

Untitled

Jan 19th, 2019
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.17 KB | None | 0 0
  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.io.OutputStreamWriter;
  5. import java.io.PrintWriter;
  6. import java.net.ServerSocket;
  7. import java.net.Socket;
  8. import java.util.List;
  9. import java.util.TreeMap;
  10. import java.util.stream.Collectors;
  11. import java.util.stream.IntStream;
  12.  
  13.  
  14. class WebserverThread extends Thread {
  15. // Синхронизация не нужна. У TemplateProcessor нет изменяемого состояния.
  16. private final TemplateProcessor templateProcessor;
  17.  
  18. private final LinkedDocumentCollection ldc;
  19.  
  20. private final Socket client;
  21.  
  22. public WebserverThread(TemplateProcessor templateProcessor, LinkedDocumentCollection ldc, Socket socket) {
  23. this.templateProcessor = templateProcessor;
  24. this.ldc = ldc;
  25. this.client = socket;
  26. }
  27.  
  28. public void communicate() throws IOException {
  29. BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
  30. PrintWriter out = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
  31.  
  32. try {
  33. String requestLine = in.readLine();
  34. if (requestLine == null)
  35. return;
  36. in.lines().takeWhile(l -> !l.equals("")).count();
  37.  
  38. System.out.println("=> Request header received");
  39.  
  40. HttpRequest request;
  41. try {
  42. request = new HttpRequest(requestLine);
  43. } catch (InvalidRequestException ex) {
  44. System.out.println("=> Bad request!");
  45. out.print(new HttpResponse(HttpStatus.BadRequest));
  46. return;
  47. }
  48.  
  49. if (request.getMethod() != HttpMethod.GET) {
  50. System.out.println("=> Invalid method!");
  51. out.print(new HttpResponse(HttpStatus.MethodNotAllowed));
  52. return;
  53. }
  54.  
  55. HttpResponse response;
  56. if (request.getPath().equals("/")) {
  57. System.out.println("=> Query for main page");
  58. response = handleMainPage();
  59. } else if (request.getPath().equals("/search")) {
  60. System.out.println("=> Search query");
  61. String query = request.getParameters().get("query");
  62. response = handleSearchRequest(query);
  63. } else {
  64. System.out.println("=> File query");
  65. String fileName = request.getPath().substring(1);
  66. response = handleFileRequest(fileName);
  67. }
  68. out.print(response);
  69. }
  70. finally {
  71. out.close();
  72. }
  73. }
  74.  
  75. private HttpResponse handleMainPage() {
  76. TreeMap<String, String> varass = new TreeMap<>();
  77. varass.put("%value", "");
  78. varass.put("%results", "");
  79. String body = templateProcessor.replace(varass);
  80. return new HttpResponse(HttpStatus.Ok, body);
  81. }
  82.  
  83. private HttpResponse handleSearchRequest(String query) {
  84. double pageRankDampingFactor = 0.85;
  85. double weightingFactor = 0.6;
  86.  
  87. TreeMap<String, String> varass = new TreeMap<>();
  88. varass.put("%value", query);
  89. varass.put("%results", "");
  90.  
  91. double[] relevance = null;
  92. List<String> pageNames = null;
  93.  
  94. // DocumentCollection.match изменяет состояние ldc в процессе исполнения, поэтому ставим блокировку перед входом в метод
  95. // Нам также нужен неизмененный список названий страниц, чтобы заполнить html-код
  96. // Здесь они копируются из ldc, и используются дальше, после снятия блокировки.
  97. // Альтернатива - не копировать их, а расширить блокировку до заполнения msgBuilder и читать их непосредственно через ldc.get(i)
  98. synchronized (ldc) {
  99. relevance = ldc.match(query, pageRankDampingFactor, weightingFactor);
  100. pageNames = IntStream.range(0, ldc.numDocuments()).boxed().map(i -> ldc.get(i).getTitle()).collect(Collectors.toList());
  101. }
  102.  
  103. StringBuilder msgBuilder = new StringBuilder();
  104. if (pageNames.size() > 0)
  105. msgBuilder.append("<tr><td><b>ID</b></td><td><b>Page</b></td><td><b>Relevance</b></td></tr>");
  106.  
  107. for(int i = 0; i < pageNames.size(); ++i) {
  108. msgBuilder.append("<tr>");
  109. msgBuilder.append("<td>").append(i + 1).append("</td>");
  110. msgBuilder.append("<td><a href=\"").append(pageNames.get(i)).append("\">").append(pageNames.get(i)).append("</a></td>");
  111. msgBuilder.append("<td>").append(relevance[i]).append("</td>");
  112. msgBuilder.append("</tr>");
  113. }
  114.  
  115.  
  116. varass.put("%results", msgBuilder.toString());
  117. String body = templateProcessor.replace(varass);
  118. return new HttpResponse(HttpStatus.Ok, body);
  119. }
  120.  
  121.  
  122. private HttpResponse handleFileRequest(String fileName) {
  123. if (fileName.contains("/"))
  124. return new HttpResponse(HttpStatus.Forbidden);
  125. String[] fileContents = Terminal.readFile(fileName);
  126. if (fileContents == null) {
  127. return new HttpResponse(HttpStatus.NotFound);
  128. }
  129. String body = fileContents[1];
  130. return new HttpResponse(HttpStatus.Ok, body);
  131. }
  132.  
  133.  
  134. @Override
  135. public void run() {
  136. try {
  137. communicate();
  138. }
  139. catch (IOException ex) {
  140. ex.printStackTrace();
  141. }
  142. finally {
  143. try {
  144. client.close();
  145. }
  146. catch (IOException ex) {
  147. ex.printStackTrace();
  148. }
  149. }
  150.  
  151. }
  152. }
  153.  
  154.  
  155. public class ConcurrentWebServer {
  156.  
  157. public static void main(String[] args) throws IOException {
  158. // Создаем один обработчик шаблонов
  159. TemplateProcessor tp = new TemplateProcessor("html/search.html");
  160.  
  161. // Создаем разделяемую коллекцию документов
  162. LinkedDocumentCollection prelim = new LinkedDocumentCollection();
  163. prelim.appendDocument(new LinkedDocument("B.txt", "", "", null, null, "link:A.txt link:E.txt", "B.txt"));
  164. LinkedDocumentCollection sharedLDC = prelim.crawl();
  165.  
  166. ServerSocket serverSocket = new ServerSocket(8000);
  167.  
  168. // Ожидаем новые соединения
  169. while(true) {
  170. try {
  171. Socket client = serverSocket.accept();
  172. // При новом входящем соединении создаём новый поток, передаём ему ссылки на разделяемые данные
  173. WebserverThread thread = new WebserverThread(tp, sharedLDC, client);
  174. // Запускаем поток
  175. thread.start();
  176. }
  177. catch (IOException ex) {
  178. ex.printStackTrace();
  179. System.exit(-1);
  180. }
  181. }
  182. }
  183.  
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement