Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- import java.io.PrintWriter;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.List;
- import java.util.TreeMap;
- import java.util.stream.Collectors;
- import java.util.stream.IntStream;
- class WebserverThread extends Thread {
- // Синхронизация не нужна. У TemplateProcessor нет изменяемого состояния.
- private final TemplateProcessor templateProcessor;
- private final LinkedDocumentCollection ldc;
- private final Socket client;
- public WebserverThread(TemplateProcessor templateProcessor, LinkedDocumentCollection ldc, Socket socket) {
- this.templateProcessor = templateProcessor;
- this.ldc = ldc;
- this.client = socket;
- }
- public void communicate() throws IOException {
- BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
- PrintWriter out = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
- try {
- String requestLine = in.readLine();
- if (requestLine == null)
- return;
- in.lines().takeWhile(l -> !l.equals("")).count();
- System.out.println("=> Request header received");
- HttpRequest request;
- try {
- request = new HttpRequest(requestLine);
- } catch (InvalidRequestException ex) {
- System.out.println("=> Bad request!");
- out.print(new HttpResponse(HttpStatus.BadRequest));
- return;
- }
- if (request.getMethod() != HttpMethod.GET) {
- System.out.println("=> Invalid method!");
- out.print(new HttpResponse(HttpStatus.MethodNotAllowed));
- return;
- }
- HttpResponse response;
- if (request.getPath().equals("/")) {
- System.out.println("=> Query for main page");
- response = handleMainPage();
- } else if (request.getPath().equals("/search")) {
- System.out.println("=> Search query");
- String query = request.getParameters().get("query");
- response = handleSearchRequest(query);
- } else {
- System.out.println("=> File query");
- String fileName = request.getPath().substring(1);
- response = handleFileRequest(fileName);
- }
- out.print(response);
- }
- finally {
- out.close();
- }
- }
- private HttpResponse handleMainPage() {
- TreeMap<String, String> varass = new TreeMap<>();
- varass.put("%value", "");
- varass.put("%results", "");
- String body = templateProcessor.replace(varass);
- return new HttpResponse(HttpStatus.Ok, body);
- }
- private HttpResponse handleSearchRequest(String query) {
- double pageRankDampingFactor = 0.85;
- double weightingFactor = 0.6;
- TreeMap<String, String> varass = new TreeMap<>();
- varass.put("%value", query);
- varass.put("%results", "");
- double[] relevance = null;
- List<String> pageNames = null;
- // DocumentCollection.match изменяет состояние ldc в процессе исполнения, поэтому ставим блокировку перед входом в метод
- // Нам также нужен неизмененный список названий страниц, чтобы заполнить html-код
- // Здесь они копируются из ldc, и используются дальше, после снятия блокировки.
- // Альтернатива - не копировать их, а расширить блокировку до заполнения msgBuilder и читать их непосредственно через ldc.get(i)
- synchronized (ldc) {
- relevance = ldc.match(query, pageRankDampingFactor, weightingFactor);
- pageNames = IntStream.range(0, ldc.numDocuments()).boxed().map(i -> ldc.get(i).getTitle()).collect(Collectors.toList());
- }
- StringBuilder msgBuilder = new StringBuilder();
- if (pageNames.size() > 0)
- msgBuilder.append("<tr><td><b>ID</b></td><td><b>Page</b></td><td><b>Relevance</b></td></tr>");
- for(int i = 0; i < pageNames.size(); ++i) {
- msgBuilder.append("<tr>");
- msgBuilder.append("<td>").append(i + 1).append("</td>");
- msgBuilder.append("<td><a href=\"").append(pageNames.get(i)).append("\">").append(pageNames.get(i)).append("</a></td>");
- msgBuilder.append("<td>").append(relevance[i]).append("</td>");
- msgBuilder.append("</tr>");
- }
- varass.put("%results", msgBuilder.toString());
- String body = templateProcessor.replace(varass);
- return new HttpResponse(HttpStatus.Ok, body);
- }
- private HttpResponse handleFileRequest(String fileName) {
- if (fileName.contains("/"))
- return new HttpResponse(HttpStatus.Forbidden);
- String[] fileContents = Terminal.readFile(fileName);
- if (fileContents == null) {
- return new HttpResponse(HttpStatus.NotFound);
- }
- String body = fileContents[1];
- return new HttpResponse(HttpStatus.Ok, body);
- }
- @Override
- public void run() {
- try {
- communicate();
- }
- catch (IOException ex) {
- ex.printStackTrace();
- }
- finally {
- try {
- client.close();
- }
- catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
- }
- public class ConcurrentWebServer {
- public static void main(String[] args) throws IOException {
- // Создаем один обработчик шаблонов
- TemplateProcessor tp = new TemplateProcessor("html/search.html");
- // Создаем разделяемую коллекцию документов
- LinkedDocumentCollection prelim = new LinkedDocumentCollection();
- prelim.appendDocument(new LinkedDocument("B.txt", "", "", null, null, "link:A.txt link:E.txt", "B.txt"));
- LinkedDocumentCollection sharedLDC = prelim.crawl();
- ServerSocket serverSocket = new ServerSocket(8000);
- // Ожидаем новые соединения
- while(true) {
- try {
- Socket client = serverSocket.accept();
- // При новом входящем соединении создаём новый поток, передаём ему ссылки на разделяемые данные
- WebserverThread thread = new WebserverThread(tp, sharedLDC, client);
- // Запускаем поток
- thread.start();
- }
- catch (IOException ex) {
- ex.printStackTrace();
- System.exit(-1);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement