diff --git a/src/github.com/turt2live/matrix-media-repo/client/r0/download.go b/src/github.com/turt2live/matrix-media-repo/client/r0/download.go
index e42f2bd6a063d9e6e558dfbfdc5c15eb568b76fc..3627022fb6bc3584f9969d6552cea836dc739de5 100644
--- a/src/github.com/turt2live/matrix-media-repo/client/r0/download.go
+++ b/src/github.com/turt2live/matrix-media-repo/client/r0/download.go
@@ -1,9 +1,11 @@
 package r0
 
 import (
+	"database/sql"
 	"net/http"
 
 	"github.com/gorilla/mux"
+	"github.com/turt2live/matrix-media-repo/client"
 	"github.com/turt2live/matrix-media-repo/config"
 	"github.com/turt2live/matrix-media-repo/storage"
 )
@@ -17,10 +19,10 @@ import (
 //   Body: <byte[]>
 
 type DownloadMediaResponse struct {
-	Server string
-	MediaID string
+	ContentType string
 	Filename string
-	Host string
+	SizeBytes int64
+	Location string
 }
 
 func DownloadMedia(w http.ResponseWriter, r *http.Request, db storage.Database, c config.MediaRepoConfig) interface{} {
@@ -30,9 +32,23 @@ func DownloadMedia(w http.ResponseWriter, r *http.Request, db storage.Database,
 	mediaId := params["mediaId"]
 	filename := params["filename"]
 
+	media, err := db.GetMedia(r.Context(), server, mediaId)
+	if err != nil {
+		if err == sql.ErrNoRows {
+			// TODO: Try remote fetch
+			return client.NotFoundError()
+		}
+		return client.InternalServerError(err.Error())
+	}
+
 	if filename == "" {
-		filename = "testasdasdasd.jpg"
+		filename = media.UploadName
 	}
 
-	return &DownloadMediaResponse{server, mediaId, filename, r.Host}
+	return &DownloadMediaResponse{
+		ContentType: media.ContentType,
+		Filename:    filename,
+		SizeBytes:   media.SizeBytes,
+		Location:    media.Location,
+	}
 }
diff --git a/src/github.com/turt2live/matrix-media-repo/client/responses.go b/src/github.com/turt2live/matrix-media-repo/client/responses.go
index 1101041074b838643dfac43660d0898e5e8b5f63..31c7f9d24131316d3490692f1675a7bbb5b8fcd8 100644
--- a/src/github.com/turt2live/matrix-media-repo/client/responses.go
+++ b/src/github.com/turt2live/matrix-media-repo/client/responses.go
@@ -7,4 +7,8 @@ type ErrorResponse struct {
 
 func InternalServerError(message string) *ErrorResponse {
 	return &ErrorResponse{"M_UNKNOWN", message}
+}
+
+func NotFoundError() *ErrorResponse {
+	return &ErrorResponse{"M_NOT_FOUND", "Not found"}
 }
\ No newline at end of file
diff --git a/src/github.com/turt2live/matrix-media-repo/media_repo.go b/src/github.com/turt2live/matrix-media-repo/media_repo.go
index f7e45cd7f060694a078542c3a075db8a722603aa..647d647ae01d6202bb83d29d87d8a7dc8e4f2500 100644
--- a/src/github.com/turt2live/matrix-media-repo/media_repo.go
+++ b/src/github.com/turt2live/matrix-media-repo/media_repo.go
@@ -4,6 +4,7 @@ import (
 	json "encoding/json"
 	"io"
 	"net/http"
+	"os"
 
 	"github.com/gorilla/mux"
 	"github.com/turt2live/matrix-media-repo/client"
@@ -12,6 +13,8 @@ import (
 	"github.com/turt2live/matrix-media-repo/storage"
 )
 
+const UnkErrJson = `{"code":"M_UNKNOWN","message":"Unexpected error processing response"}`
+
 type Handler struct {
 	h func(http.ResponseWriter, *http.Request, storage.Database, config.MediaRepoConfig) interface{}
 	opts HandlerOpts
@@ -44,17 +47,15 @@ func main() {
 	thumbnailHandler := Handler{r0.ThumbnailMedia, hOpts}
 
 	rtr.Handle("/_matrix/client/r0/media/upload", uploadHandler).Methods("POST")
-	rtr.Handle("/_matrix/client/r0/media/download/{server:[a-zA-Z0-9.]+}/{mediaId:[a-zA-Z0-9]+}", downloadHandler).Methods("GET")
-	rtr.Handle("/_matrix/client/r0/media/download/{server:[a-zA-Z0-9.]+}/{mediaId:[a-zA-Z0-9]+}/{filename:[a-zA-Z0-9._-]+}", downloadHandler).Methods("GET")
-	rtr.Handle("/_matrix/client/r0/media/thumbnail/{server:[a-zA-Z0-9.]+}/{mediaId:[a-zA-Z0-9]+}", thumbnailHandler).Methods("GET")
+	rtr.Handle("/_matrix/client/r0/media/download/{server:[a-zA-Z0-9.:-_]+}/{mediaId:[a-zA-Z0-9]+}", downloadHandler).Methods("GET")
+	rtr.Handle("/_matrix/client/r0/media/download/{server:[a-zA-Z0-9.:-_]+}/{mediaId:[a-zA-Z0-9]+}/{filename:[a-zA-Z0-9._-]+}", downloadHandler).Methods("GET")
+	rtr.Handle("/_matrix/client/r0/media/thumbnail/{server:[a-zA-Z0-9.:-_]+}/{mediaId:[a-zA-Z0-9]+}", thumbnailHandler).Methods("GET")
 
 	http.Handle("/", rtr)
 	http.ListenAndServe(":8000", nil)
 }
 
 func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	w.Header().Set("Content-Type", "application/json")
-
 	res := h.h(w, r, h.opts.db, h.opts.config)
 	if res == nil {
 		res = &EmptyResponse{}
@@ -62,7 +63,8 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 	b, err := json.Marshal(res)
 	if err != nil {
-		http.Error(w, `{"code":"M_UNKNOWN","message":"Unexpected error processing response"}`, http.StatusInternalServerError)
+		w.Header().Set("Content-Type", "application/json")
+		http.Error(w, UnkErrJson, http.StatusInternalServerError)
 		return
 	}
 	jsonStr := string(b)
@@ -70,13 +72,32 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	switch result := res.(type) {
 	case *client.ErrorResponse:
 		switch result.Code {
+		case "M_NOT_FOUND":
+			w.Header().Set("Content-Type", "application/json")
+			http.Error(w, jsonStr, http.StatusNotFound)
+			break
 		//case "M_UNKNOWN":
 		default:
+			w.Header().Set("Content-Type", "application/json")
 			http.Error(w, jsonStr, http.StatusInternalServerError)
 			break
 		}
 		break
+	case *r0.DownloadMediaResponse:
+		w.Header().Set("Content-Type", result.ContentType)
+		w.Header().Set("Content-Disposition", "inline; filename=\"" + result.Filename +"\"")
+		f, err := os.Open(result.Location)
+		if err != nil {
+			w.Header().Set("Content-Type", "application/json")
+			http.Error(w, UnkErrJson, http.StatusInternalServerError)
+			break
+		}
+		defer f.Close()
+		io.Copy(w, f)
+		break
 	default:
+		w.Header().Set("Content-Type", "application/json")
 		io.WriteString(w, jsonStr)
+		break
 	}
 }
\ No newline at end of file
diff --git a/src/github.com/turt2live/matrix-media-repo/storage/storage.go b/src/github.com/turt2live/matrix-media-repo/storage/storage.go
index 421ff55b305f2b1f9100a109ddb40d195d4f1dd4..640ada52564b311d2475a6767863a261ad31e38a 100644
--- a/src/github.com/turt2live/matrix-media-repo/storage/storage.go
+++ b/src/github.com/turt2live/matrix-media-repo/storage/storage.go
@@ -99,4 +99,20 @@ func (d *Database) GetSizeOfFolderBytes(ctx context.Context, folderPath string)
 	r := &folderSize{}
 	err := d.statements.selectSizeOfFolder.QueryRowContext(ctx, folderPath).Scan(&r.Size)
 	return r.Size, err
+}
+
+func (d *Database) GetMedia(ctx context.Context, origin string, mediaId string) (types.Media, error) {
+	m := &types.Media{}
+	err := d.statements.selectMedia.QueryRowContext(ctx, origin, mediaId).Scan(
+		&m.Origin,
+		&m.MediaId,
+		&m.UploadName,
+		&m.ContentType,
+		&m.UserId,
+		&m.Sha256Hash,
+		&m.SizeBytes,
+		&m.Location,
+		&m.CreationTs,
+	)
+	return *m, err
 }
\ No newline at end of file