1 // This file is part of OpenTSDB.
2 // Copyright (C) 2010-2012  The OpenTSDB Authors.
3 //
4 // This program is free software: you can redistribute it and/or modify it
5 // under the terms of the GNU Lesser General Public License as published by
6 // the Free Software Foundation, either version 2.1 of the License, or (at your
7 // option) any later version.  This program is distributed in the hope that it
8 // will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
9 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
10 // General Public License for more details.  You should have received a copy
11 // of the GNU Lesser General Public License along with this program.  If not,
12 // see <http://www.gnu.org/licenses/>.
13 package net.opentsdb.tsd;
14 
15 import java.io.IOException;
16 
17 import net.opentsdb.core.TSDB;
18 
19 /** Implements the "/s" endpoint to serve static files. */
20 final class StaticFileRpc implements HttpRpc {
21 
22   /**
23    * Constructor.
24    */
StaticFileRpc()25   public StaticFileRpc() {
26   }
27 
execute(final TSDB tsdb, final HttpQuery query)28   public void execute(final TSDB tsdb, final HttpQuery query)
29     throws IOException {
30     final String uri = query.request().getUri();
31     if ("/favicon.ico".equals(uri)) {
32       query.sendFile(tsdb.getConfig().getDirectoryName("tsd.http.staticroot")
33           + "/favicon.ico", 31536000 /*=1yr*/);
34       return;
35     }
36     if (uri.length() < 3) {  // Must be at least 3 because of the "/s/".
37       throw new BadRequestException("URI too short <code>" + uri + "</code>");
38     }
39     // Cheap security check to avoid directory traversal attacks.
40     // TODO(tsuna): This is certainly not sufficient.
41     if (uri.indexOf("..", 3) > 0) {
42       throw new BadRequestException("Malformed URI <code>" + uri + "</code>");
43     }
44     final int questionmark = uri.indexOf('?', 3);
45     final int pathend = questionmark > 0 ? questionmark : uri.length();
46     query.sendFile(tsdb.getConfig().getDirectoryName("tsd.http.staticroot")
47                  + uri.substring(2, pathend),  // Drop the "/s"
48                    uri.contains("nocache") ? 0 : 31536000 /*=1yr*/);
49   }
50 }
51