001/* 002 * Syncany, www.syncany.org 003 * Copyright (C) 2011-2016 Philipp C. Heckel <philipp.heckel@gmail.com> 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package org.syncany.operations.daemon.handlers; 019 020import java.io.File; 021import java.io.FileInputStream; 022import java.io.FileNotFoundException; 023import java.io.IOException; 024import java.util.logging.Level; 025import java.util.logging.Logger; 026 027import org.apache.commons.io.IOUtils; 028import org.syncany.config.LocalEventBus; 029import org.syncany.operations.daemon.WebServer; 030import org.syncany.operations.daemon.WebServer.RequestFormatType; 031import org.syncany.operations.daemon.messages.BadRequestResponse; 032import org.syncany.operations.daemon.messages.api.JsonMessageFactory; 033import org.syncany.operations.daemon.messages.api.Request; 034import org.syncany.operations.daemon.messages.api.XmlMessageFactory; 035 036import com.google.common.base.Joiner; 037 038import io.undertow.server.HttpHandler; 039import io.undertow.server.HttpServerExchange; 040 041/** 042 * InteralRestHandler handles the REST requests sent to the daemon. 043 * 044 * @author Philipp C. Heckel (philipp.heckel@gmail.com) 045 */ 046public class InternalRestHandler implements HttpHandler { 047 private static final Logger logger = Logger.getLogger(InternalRestHandler.class.getSimpleName()); 048 049 private final WebServer daemonWebServer; 050 private final LocalEventBus eventBus; 051 private final RequestFormatType requestFormatType; 052 053 public InternalRestHandler(WebServer daemonWebServer, RequestFormatType requestFormatType) { 054 this.daemonWebServer = daemonWebServer; 055 this.eventBus = LocalEventBus.getInstance(); 056 this.requestFormatType = requestFormatType; 057 } 058 059 @Override 060 public void handleRequest(final HttpServerExchange exchange) throws Exception { 061 handleRestRequest(exchange); 062 } 063 064 private void handleRestRequest(HttpServerExchange exchange) throws IOException { 065 logger.log(Level.INFO, "HTTP request received:" + exchange.getRelativePath()); 066 067 exchange.startBlocking(); 068 069 if (exchange.getRelativePath().startsWith("/file/")) { 070 handleFileRequest(exchange); 071 } 072 else { 073 handleNormalRequest(exchange); 074 } 075 } 076 077 private void handleNormalRequest(HttpServerExchange exchange) throws IOException { 078 String message = IOUtils.toString(exchange.getInputStream()); // TODO [high] Read entire file to memory. Dangerous! 079 logger.log(Level.INFO, "REST message received: " + message); 080 081 try { 082 Request request; 083 084 switch (requestFormatType) { 085 case JSON: 086 request = JsonMessageFactory.toRequest(message); 087 break; 088 089 case XML: 090 request = XmlMessageFactory.toRequest(message); 091 break; 092 093 default: 094 throw new Exception("Unknown request format. Valid formats are " + Joiner.on(", ").join(RequestFormatType.values())); 095 } 096 097 daemonWebServer.putRequestFormatType(request.getId(), requestFormatType); 098 daemonWebServer.putCacheRestRequest(request.getId(), exchange); 099 100 eventBus.post(request); 101 } 102 catch (Exception e) { 103 logger.log(Level.WARNING, "Invalid request received; cannot serialize to Request.", e); 104 eventBus.post(new BadRequestResponse(-1, "Invalid request.")); 105 } 106 } 107 108 private void handleFileRequest(HttpServerExchange exchange) throws FileNotFoundException, IOException { 109 String tempFileToken = exchange.getRelativePath().substring("/file/".length()); 110 File tempFile = daemonWebServer.getFileTokenTempFileFromCache(tempFileToken); 111 112 if (tempFile != null) { 113 logger.log(Level.INFO, "- Temp file: " + tempFileToken); 114 115 IOUtils.copy(new FileInputStream(tempFile), exchange.getOutputStream()); 116 exchange.endExchange(); 117 } 118 else { 119 logger.log(Level.WARNING, "Invalid request received; Cannot find file token " + tempFileToken); 120 eventBus.post(new BadRequestResponse(-1, "Invalid request.")); 121 } 122 } 123}