Compare commits
	
		
			21 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 396672b02b | |||
| d25b867e90 | |||
| cd60e4c855 | |||
| ee72f188a2 | |||
| 30f5b40e1d | |||
| 3a103ae484 | |||
| 08321818ff | |||
| 14456e6539 | |||
| f27d14aac4 | |||
| 6ab2b08099 | |||
| 930869759b | |||
| d35c81ed21 | |||
| 139117b4d5 | |||
| b88273ec64 | |||
| 79cb8733e5 | |||
| 366c307e02 | |||
| 23ad509f33 | |||
| a6e495f74d | |||
| b3ec40ae65 | |||
| 87f0cb016d | |||
| 381e67bb39 | 
							
								
								
									
										2
									
								
								.hgtags
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								.hgtags
									
									
									
									
									
								
							@@ -7,3 +7,5 @@ c7b699105bd166e7a01aa0e678d34624680bf81e release-1.1.0
 | 
			
		||||
cfb1e028fd0627614aa01184893f9f29f20a347e release-1.1.0
 | 
			
		||||
cfb1e028fd0627614aa01184893f9f29f20a347e release-1.1.0
 | 
			
		||||
0000000000000000000000000000000000000000 release-1.1.0
 | 
			
		||||
0000000000000000000000000000000000000000 release-1.1.0
 | 
			
		||||
98da2ebf0d50dffe8b625457a639bc2f15519714 release-1.1.0
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							@@ -2,7 +2,7 @@
 | 
			
		||||
# Makefile for contented
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
VERSION:=1.1.0
 | 
			
		||||
VERSION:=1.2.0
 | 
			
		||||
 | 
			
		||||
SOURCES:=Makefile \
 | 
			
		||||
	static \
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								Server.go
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								Server.go
									
									
									
									
									
								
							@@ -5,6 +5,8 @@ import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
@@ -22,12 +24,21 @@ type ServerPublicProperties struct {
 | 
			
		||||
type ServerOptions struct {
 | 
			
		||||
	DataDirectory          string
 | 
			
		||||
	DBPath                 string
 | 
			
		||||
	DiskFilesWorldReadable bool
 | 
			
		||||
	BandwidthLimit         int64
 | 
			
		||||
	TrustXForwardedFor     bool
 | 
			
		||||
	EnableHomepage         bool
 | 
			
		||||
	ServerPublicProperties
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *ServerOptions) FileMode() os.FileMode {
 | 
			
		||||
	if this.DiskFilesWorldReadable {
 | 
			
		||||
		return 0644
 | 
			
		||||
	} else {
 | 
			
		||||
		return 0600
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Server struct {
 | 
			
		||||
	opts           ServerOptions
 | 
			
		||||
	db             *bolt.DB
 | 
			
		||||
@@ -90,8 +101,11 @@ func (this *Server) remoteIP(r *http.Request) string {
 | 
			
		||||
const (
 | 
			
		||||
	downloadUrlPrefix = `/get/`
 | 
			
		||||
	metadataUrlPrefix = `/info/`
 | 
			
		||||
	previewUrlPrefix  = `/p/`
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var rxThumbUrl = regexp.MustCompile(`^/thumb/(.)/(.*)$`)
 | 
			
		||||
 | 
			
		||||
func (this *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	w.Header().Set(`Server`, SERVER_HEADER)
 | 
			
		||||
	w.Header().Set(`Access-Control-Allow-Origin`, `*`) // Blanket allow CORS
 | 
			
		||||
@@ -110,6 +124,13 @@ func (this *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	} else if r.Method == "GET" && strings.HasPrefix(r.URL.Path, metadataUrlPrefix) {
 | 
			
		||||
		this.handleInformation(w, r.URL.Path[len(metadataUrlPrefix):])
 | 
			
		||||
 | 
			
		||||
	} else if r.Method == "GET" && strings.HasPrefix(r.URL.Path, previewUrlPrefix) {
 | 
			
		||||
		this.handlePreview(w, r.URL.Path[len(previewUrlPrefix):])
 | 
			
		||||
 | 
			
		||||
	} else if r.Method == "GET" && rxThumbUrl.MatchString(r.URL.Path) {
 | 
			
		||||
		parts := rxThumbUrl.FindStringSubmatch(r.URL.Path)
 | 
			
		||||
		this.handleThumb(w, r, parts[1][0], parts[2])
 | 
			
		||||
 | 
			
		||||
	} else if r.Method == "GET" && r.URL.Path == `/about` {
 | 
			
		||||
		this.handleAbout(w)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								TODO.txt
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								TODO.txt
									
									
									
									
									
								
							@@ -6,8 +6,9 @@ TODO
 | 
			
		||||
 | 
			
		||||
- Encrypted at rest (anti- provider snooping)
 | 
			
		||||
 | 
			
		||||
- Nicer preview page after uploading
 | 
			
		||||
 | 
			
		||||
- Gallery preview (multiple element hashid)
 | 
			
		||||
 | 
			
		||||
- Prevent selecting around the toggle buttons (firefox for android)
 | 
			
		||||
 | 
			
		||||
- Detect when pasting creates one large file and one ~150 byte file(?? why does this happen?)
 | 
			
		||||
 | 
			
		||||
- Detect when pasting an image URL, offer to download it (clientside?)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ You can use contented as a standalone upload server, or you can use the SDK to e
 | 
			
		||||
- Detect duplicate upload content and reuse storage
 | 
			
		||||
- Options to limit the upload filesize and the upload bandwidth
 | 
			
		||||
- Short URLs (using [url=http://hashids.org]Hashids[/url] algorithm)
 | 
			
		||||
- Image thumbnailing
 | 
			
		||||
 | 
			
		||||
=USAGE (SERVER)=
 | 
			
		||||
 | 
			
		||||
@@ -26,10 +27,12 @@ You can use contented as a standalone upload server, or you can use the SDK to e
 | 
			
		||||
        Directory for stored content (default "")
 | 
			
		||||
  -db string
 | 
			
		||||
        Path for metadata database (default "contented.db")
 | 
			
		||||
  -diskFilesWorldReadable
 | 
			
		||||
        Save files as 0644 instead of 0600
 | 
			
		||||
  -enableHomepage
 | 
			
		||||
        Enable homepage (disable for embedded use only) (default true)
 | 
			
		||||
  -listen string
 | 
			
		||||
         (default "127.0.0.1:80")
 | 
			
		||||
        IP/Port to bind server (default "127.0.0.1:80")
 | 
			
		||||
  -max int
 | 
			
		||||
        Maximum size of uploaded files in MiB (set zero for unlimited) (default 8)
 | 
			
		||||
  -speed int
 | 
			
		||||
@@ -48,6 +51,7 @@ The server responds on the following URLs:
 | 
			
		||||
 | 
			
		||||
- `/get/{ID}`: Download item content
 | 
			
		||||
- `/info/{ID}`: Get item content metadata (JSON)
 | 
			
		||||
- `/thumb/{Type}/{ID}`: Get item thumbnail image
 | 
			
		||||
- `/about`: Get server metadata (JSON)
 | 
			
		||||
 | 
			
		||||
=USAGE (EMBEDDING FOR WEB)=
 | 
			
		||||
@@ -60,6 +64,12 @@ contented.init("#target", function(/* String[] */ items) {});
 | 
			
		||||
 | 
			
		||||
=CHANGELOG=
 | 
			
		||||
 | 
			
		||||
2017-11-18: 1.2.0
 | 
			
		||||
- Feature: Thumbnail support
 | 
			
		||||
- Feature: File preview page
 | 
			
		||||
- Feature: Album mode (via URL `/p/{file1}-{file2}-...`)
 | 
			
		||||
- Feature: New `-diskFilesWorldReadable` option to save files with `0644` mode
 | 
			
		||||
 | 
			
		||||
2017-10-15: 1.1.0
 | 
			
		||||
- Feature: Drawing mode
 | 
			
		||||
- Feature: Ctrl+V image upload
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ func main() {
 | 
			
		||||
	maxUploadSpeed := flag.Int("speed", 0, "Maximum upload speed in bytes/sec (set zero for unlimited)")
 | 
			
		||||
	trustXForwardedFor := flag.Bool("trustXForwardedFor", false, "Trust X-Forwarded-For reverse proxy headers")
 | 
			
		||||
	enableHomepage := flag.Bool("enableHomepage", true, "Enable homepage (disable for embedded use only)")
 | 
			
		||||
	diskFilesWorldReadable := flag.Bool("diskFilesWorldReadable", false, "Save files as 0644 instead of 0600")
 | 
			
		||||
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
 | 
			
		||||
@@ -29,6 +30,7 @@ func main() {
 | 
			
		||||
		BandwidthLimit:         int64(*maxUploadSpeed),
 | 
			
		||||
		TrustXForwardedFor:     *trustXForwardedFor,
 | 
			
		||||
		EnableHomepage:         *enableHomepage,
 | 
			
		||||
		DiskFilesWorldReadable: *diskFilesWorldReadable,
 | 
			
		||||
		ServerPublicProperties: contented.ServerPublicProperties{
 | 
			
		||||
			AppTitle:       *appTitle,
 | 
			
		||||
			MaxUploadBytes: int64(*maxUploadMb) * 1024 * 1024,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										97
									
								
								preview.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								preview.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
package contented
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"html"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (this *Server) handlePreview(w http.ResponseWriter, fileIDList string) {
 | 
			
		||||
 | 
			
		||||
	fileIDs := strings.Split(fileIDList, `-`)
 | 
			
		||||
 | 
			
		||||
	tmpl := `<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>` + html.EscapeString(this.opts.ServerPublicProperties.AppTitle) + `</title>
 | 
			
		||||
		<meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
		<style type="text/css">
 | 
			
		||||
html, body {
 | 
			
		||||
	background: #333;
 | 
			
		||||
	color: #F0F0F0;
 | 
			
		||||
	font-family: sans-serif;
 | 
			
		||||
}
 | 
			
		||||
.entry {
 | 
			
		||||
	display: inline-block;
 | 
			
		||||
	margin: 4px;
 | 
			
		||||
	border-radius: 4px;
 | 
			
		||||
	max-width: 340px;
 | 
			
		||||
}
 | 
			
		||||
.thumbnail {
 | 
			
		||||
	line-height: 0;
 | 
			
		||||
	width: 340px;
 | 
			
		||||
	text-align: center;
 | 
			
		||||
}
 | 
			
		||||
.properties {
 | 
			
		||||
	background: #000;
 | 
			
		||||
	padding: 4px;
 | 
			
		||||
	word-break: break-word;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		</style>
 | 
			
		||||
	</head>
 | 
			
		||||
	<body>
 | 
			
		||||
		<div class="container">
 | 
			
		||||
	`
 | 
			
		||||
 | 
			
		||||
	for _, fileID := range fileIDs {
 | 
			
		||||
		m, err := this.Metadata(fileID)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if os.IsNotExist(err) {
 | 
			
		||||
				http.Error(w, "Not found", 404)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			log.Println(err.Error())
 | 
			
		||||
			http.Error(w, "Internal error", 500)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		tmpl += `
 | 
			
		||||
			<div class="entry">			
 | 
			
		||||
				<div class="thumbnail">
 | 
			
		||||
					<a href="` + html.EscapeString(`/get/`+fileID) + `"><img src="` + html.EscapeString(`/thumb/m/`+fileID) + `"></a>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="properties">
 | 
			
		||||
					<b>Name:</b> ` + html.EscapeString(m.Filename) + `<br>
 | 
			
		||||
					<b>Hash:</b> <span title="` + html.EscapeString(m.FileHash) + `">hover</span><br>
 | 
			
		||||
					<b>File type:</b> ` + html.EscapeString(m.MimeType) + `<br>
 | 
			
		||||
					<b>Size:</b> ` + html.EscapeString(fmt.Sprintf("%d", m.FileSize)) + `<br>
 | 
			
		||||
					<b>Uploader:</b> ` + html.EscapeString(m.UploadIP) + `<br>
 | 
			
		||||
					<b>Uploaded at:</b> ` + html.EscapeString(m.UploadTime.Format(time.RFC3339)) + `<br>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		`
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if this.opts.EnableHomepage {
 | 
			
		||||
		tmpl += `
 | 
			
		||||
			<div class="return">
 | 
			
		||||
				<button onclick="window.location.href='/'">Again...</button>
 | 
			
		||||
			</div>
 | 
			
		||||
		`
 | 
			
		||||
	}
 | 
			
		||||
	tmpl += `
 | 
			
		||||
		</div>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>`
 | 
			
		||||
 | 
			
		||||
	w.Header().Set(`Content-Type`, `text/html; charset=UTF-8`)
 | 
			
		||||
	w.Header().Set(`Content-Length`, fmt.Sprintf("%d", len(tmpl)))
 | 
			
		||||
	w.WriteHeader(200)
 | 
			
		||||
	w.Write([]byte(tmpl))
 | 
			
		||||
}
 | 
			
		||||
@@ -56,22 +56,7 @@ $.get("/about", function(ret) {
 | 
			
		||||
 | 
			
		||||
// Load upload widget
 | 
			
		||||
contented.init("#surrogate-area", function(items) {
 | 
			
		||||
    
 | 
			
		||||
    var $table = $("<table>");
 | 
			
		||||
    for (var i = 0; i < items.length; ++i) {
 | 
			
		||||
        $table.append($("<tr>").append([
 | 
			
		||||
            $("<td>").text(items[i]),
 | 
			
		||||
            $("<td>").html("<a target='_blank' href='" + contented.getDownloadURL(items[i]) + "'>get</a>"),
 | 
			
		||||
            $("<td>").html("<a target='_blank' href='" + contented.getInfoJSONURL(items[i]) + "'>info</a>"),
 | 
			
		||||
        ]))
 | 
			
		||||
    }
 | 
			
		||||
    $("#surrogate-area").html([
 | 
			
		||||
		$table,
 | 
			
		||||
		$("<button>").addClass("again").text("Again...").click(function() {
 | 
			
		||||
			window.location.href = window.location.href;
 | 
			
		||||
		}),
 | 
			
		||||
	]);
 | 
			
		||||
 | 
			
		||||
    window.location.href = contented.getMultiPreviewURL(items);
 | 
			
		||||
});
 | 
			
		||||
		</script>
 | 
			
		||||
	</body>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								static/nothumb_1024.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/nothumb_1024.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 8.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/nothumb_160.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/nothumb_160.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 2.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/nothumb_340.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/nothumb_340.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 3.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/nothumb_640.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/nothumb_640.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 5.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/nothumb_90.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/nothumb_90.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 1.5 KiB  | 
@@ -65,13 +65,27 @@ var contented = (function() {
 | 
			
		||||
		},
 | 
			
		||||
		
 | 
			
		||||
		"getPreviewURL": function(id) {
 | 
			
		||||
			return baseURL + "get/" + id; // n.b. there's no better preview URL yet
 | 
			
		||||
			return baseURL + "p/" + encodeURIComponent(id);
 | 
			
		||||
		},
 | 
			
		||||
		"getMultiPreviewURL": function(items) {
 | 
			
		||||
			return baseURL + "p/" + encodeURIComponent(items.join("-"));
 | 
			
		||||
		},
 | 
			
		||||
		"getDownloadURL": function(id) {
 | 
			
		||||
			return baseURL + "get/" + id;
 | 
			
		||||
			return baseURL + "get/" + encodeURIComponent(id);
 | 
			
		||||
		},
 | 
			
		||||
		"getInfoJSONURL": function(id) {
 | 
			
		||||
			return baseURL + "info/" + id;
 | 
			
		||||
			return baseURL + "info/" + encodeURIComponent(id);
 | 
			
		||||
		},
 | 
			
		||||
		"getThumbnailURL": function(thumbnailType, id) {
 | 
			
		||||
			return baseURL + "thumb/" + encodeURIComponent(thumbnailType) + "/" + encodeURIComponent(id);
 | 
			
		||||
		},
 | 
			
		||||
		"thumbnail": {
 | 
			
		||||
			"small_square": "s",
 | 
			
		||||
			"medium_square": "b",
 | 
			
		||||
			"medium": "t",
 | 
			
		||||
			"large": "m",
 | 
			
		||||
			"xlarge": "l",
 | 
			
		||||
			"xxlarge": "h"
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										78
									
								
								thumb.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								thumb.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
package contented
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
 | 
			
		||||
	"code.ivysaur.me/thumbnail"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func thumbnailer(t byte) (*thumbnail.Thumbnailer, error) {
 | 
			
		||||
	// Modelled on what imgur.com offers
 | 
			
		||||
	// @ref https://api.imgur.com/models/image#thumbs
 | 
			
		||||
 | 
			
		||||
	const (
 | 
			
		||||
		cacheSize = 1
 | 
			
		||||
		outputFmt = thumbnail.OUTPUT_JPG
 | 
			
		||||
		scaleFmt  = thumbnail.SCALEFMT_BILINEAR
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	switch t {
 | 
			
		||||
	case 's':
 | 
			
		||||
		return thumbnail.NewThumbnailerEx(90, 90, cacheSize, outputFmt, thumbnail.ASPECT_CROP_TO_DIMENSIONS, scaleFmt), nil
 | 
			
		||||
	case 'b':
 | 
			
		||||
		return thumbnail.NewThumbnailerEx(160, 160, cacheSize, outputFmt, thumbnail.ASPECT_CROP_TO_DIMENSIONS, scaleFmt), nil
 | 
			
		||||
	case 't':
 | 
			
		||||
		return thumbnail.NewThumbnailerEx(160, 160, cacheSize, outputFmt, thumbnail.ASPECT_RESPECT_MAX_DIMENSION_ONLY, scaleFmt), nil
 | 
			
		||||
	case 'm':
 | 
			
		||||
		return thumbnail.NewThumbnailerEx(340, 340, cacheSize, outputFmt, thumbnail.ASPECT_RESPECT_MAX_DIMENSION_ONLY, scaleFmt), nil
 | 
			
		||||
	case 'l':
 | 
			
		||||
		return thumbnail.NewThumbnailerEx(640, 640, cacheSize, outputFmt, thumbnail.ASPECT_RESPECT_MAX_DIMENSION_ONLY, scaleFmt), nil
 | 
			
		||||
	case 'h':
 | 
			
		||||
		return thumbnail.NewThumbnailerEx(1024, 1024, cacheSize, outputFmt, thumbnail.ASPECT_RESPECT_MAX_DIMENSION_ONLY, scaleFmt), nil
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, errors.New("Unsupported thumbnail type (should be s/b/t/m/l/h)")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Server) handleThumb(w http.ResponseWriter, r *http.Request, thumbnailType byte, fileId string) {
 | 
			
		||||
	t, err := thumbnailer(thumbnailType)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Printf("%s Thumbnail failed: %s\n", this.remoteIP(r), err.Error())
 | 
			
		||||
		http.Error(w, err.Error(), 400)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = this.handleThumbInternal(w, t, fileId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Printf("%s Thumbnail failed: %s\n", this.remoteIP(r), err.Error())
 | 
			
		||||
 | 
			
		||||
		w.Header().Set(`Location`, fmt.Sprintf(`/nothumb_%d.png`, t.Height()))
 | 
			
		||||
		w.WriteHeader(302)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Server) handleThumbInternal(w http.ResponseWriter, t *thumbnail.Thumbnailer, fileId string) error {
 | 
			
		||||
 | 
			
		||||
	// Load metadata
 | 
			
		||||
	m, err := this.Metadata(fileId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	filePath := filepath.Join(this.opts.DataDirectory, m.FileHash)
 | 
			
		||||
	thumb, err := t.RenderFile_NoCache_MimeType(filePath, m.MimeType)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	w.Header().Set(`Content-Length`, fmt.Sprintf("%d", len(thumb)))
 | 
			
		||||
	w.Header().Set(`Content-Type`, `image/jpeg`)
 | 
			
		||||
	w.WriteHeader(200)
 | 
			
		||||
	w.Write(thumb)
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
@@ -91,7 +91,7 @@ func (this *Server) handleUploadFile(src multipart.File, hdr *multipart.FileHead
 | 
			
		||||
 | 
			
		||||
	// Save file to disk
 | 
			
		||||
	fileHash := hex.EncodeToString(hasher.Sum(nil))
 | 
			
		||||
	dest, err := os.OpenFile(filepath.Join(this.opts.DataDirectory, fileHash), os.O_CREATE|os.O_WRONLY, 0600)
 | 
			
		||||
	dest, err := os.OpenFile(filepath.Join(this.opts.DataDirectory, fileHash), os.O_CREATE|os.O_WRONLY, this.opts.FileMode())
 | 
			
		||||
	shouldSave := true
 | 
			
		||||
	if err != nil && os.IsExist(err) {
 | 
			
		||||
		// hash matches existing upload
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user