View Javadoc

1   /**********************************************
2    * Copyright (C) 2010 Lukas Laag
3    * This file is part of svgreal.
4    * 
5    * svgreal is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    * 
10   * svgreal is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License
16   * along with svgreal.  If not, see http://www.gnu.org/licenses/
17   **********************************************/
18  /**********************************************
19   * Copyright (C) 2011 Lukas Laag
20   * This file is part of svgreal.
21   * 
22   * svgreal is free software: you can redistribute it and/or modify
23   * it under the terms of the GNU General Public License as published by
24   * the Free Software Foundation, either version 3 of the License, or
25   * (at your option) any later version.
26   * 
27   * svgreal is distributed in the hope that it will be useful,
28   * but WITHOUT ANY WARRANTY; without even the implied warranty of
29   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30   * GNU General Public License for more details.
31   * 
32   * You should have received a copy of the GNU General Public License
33   * along with svgreal.  If not, see http://www.gnu.org/licenses/
34   **********************************************/
35  /**********************************************
36   * Copyright (C) 2010 Lukas Laag
37   * This file is part of svgreal.
38   * 
39   * svgreal is free software: you can redistribute it and/or modify
40   * it under the terms of the GNU General Public License as published by
41   * the Free Software Foundation, either version 3 of the License, or
42   * (at your option) any later version.
43   * 
44   * svgreal is distributed in the hope that it will be useful,
45   * but WITHOUT ANY WARRANTY; without even the implied warranty of
46   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
47   * GNU General Public License for more details.
48   * 
49   * You should have received a copy of the GNU General Public License
50   * along with svgreal.  If not, see http://www.gnu.org/licenses/
51   **********************************************/
52  package org.vectomatic.svg.edit.server;
53  
54  import java.io.IOException;
55  import java.io.InputStream;
56  import java.io.OutputStream;
57  import java.net.InetAddress;
58  import java.net.URL;
59  import java.net.UnknownHostException;
60  
61  import javax.servlet.ServletConfig;
62  import javax.servlet.ServletException;
63  import javax.servlet.http.HttpServlet;
64  import javax.servlet.http.HttpServletRequest;
65  import javax.servlet.http.HttpServletResponse;
66  
67  import org.apache.log4j.Logger;
68  import org.vectomatic.svg.edit.client.load.FetchUtils;
69  
70  /**
71   * Servlet to fetch resources from domains outside
72   * the vectomatic domain.
73   */
74  public class FetchServlet extends HttpServlet {
75  	private static Logger logger = Logger.getLogger(FetchServlet.class);
76  	private static final long serialVersionUID = 1L;
77  	private static final int MAX_SIZE = 5 * 1024 * 1024;
78  	private static final String HTTP_PROTOCOL = "http";
79  	private String hostname;
80  
81      /**
82       * Default constructor. 
83       */
84      public FetchServlet() {
85      }
86      
87      @Override
88      public void init(ServletConfig config) throws ServletException {
89      	try {
90      	    InetAddress addr = InetAddress.getLocalHost();
91      	    hostname = addr.getHostName();
92      	} catch (UnknownHostException e) {
93  			logger.error("Cannot get host name", e);
94      	}
95      }
96  
97  	/**
98  	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
99  	 */
100     @Override
101 	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
102 		URL url = new URL(request.getParameter(FetchUtils.FETCH_URL_PARAM));
103 		String contentType = request.getParameter(FetchUtils.FETCH_TYPE_PARAM);
104 		logger.info("Fetching: " + url.toExternalForm() + " contentType: " + contentType);
105 		// Reject all non HTTP urls
106 		if (!HTTP_PROTOCOL.equals(url.getProtocol())) {
107 			logger.error("Unsupported protocol: " + url.toExternalForm());
108 			response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unsupported protocol: " + url.getProtocol());
109 			return;
110 		} else {
111 			String host = url.getHost();
112 			if (host.startsWith("localhost") || host.startsWith(hostname) || host.startsWith("127.0.0.1")) {
113 				logger.error("Access not permitted: " + url.toExternalForm());
114 				response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access not permitted: " + url);
115 				return;
116 			}
117 			InputStream istream = null;
118 			OutputStream ostream = null;
119 			try {
120 				// Copy the requested stream. Stop if it exceeds MAX_SIZE
121 				istream = url.openStream();
122 			} catch(IOException e) {
123 				logger.error("Not found: " + url.toExternalForm());
124 				response.sendError(HttpServletResponse.SC_NOT_FOUND, "Not found: " + url.getProtocol());
125 				return;
126 			}
127 			try {
128 				if (contentType != null) {
129 					response.setContentType(contentType);
130 				}
131 				ostream = response.getOutputStream();
132 
133 				byte[] buffer = new byte[4096];
134 				int length, totalLength = 0;
135 				while ((totalLength <= MAX_SIZE) && ((length = istream.read(buffer)) != -1)) {
136 					ostream.write(buffer, 0, length);
137 					totalLength += length;
138 				}
139 				if (totalLength > MAX_SIZE) {
140 					logger.error("Size limit exceeded: " + url.toExternalForm());
141 					return;
142 				}
143 			} catch(Throwable t) {
144 				logger.error("Load error: " + url.toExternalForm() + " " + t.getMessage());
145 			} finally {
146 				if (istream != null) {
147 					istream.close();
148 				}
149 				if (ostream != null) {
150 					ostream.close();
151 				}
152 			}
153 		}
154 	}
155 }