func()

in uploadhandler.go [82:195]


func (h UploadHandler) ServeHTTP(w http.ResponseWriter, request *http.Request) {
	if request.Body != nil {
		defer request.Body.Close()
	}

	if !helpers.AssertHttpMethod(request, w, "POST") {
		io.Copy(ioutil.Discard, request.Body) //discard any remaining body
		return
	}

	username, validationErr := helpers.ValidateLogin(request, h.config)
	if validationErr != nil {
		log.Printf("ERROR UploadHandler could not validate request: %s", validationErr)
		response := helpers.GenericErrorResponse{
			Status: "forbidden",
			Detail: validationErr.Error(),
		}
		helpers.WriteJsonContent(response, w, 403)
		return
	}

	values, queryErr := helpers.GetQueryParams(request.RequestURI)
	if queryErr != nil {
		log.Print("ERROR UploadHandler could not parse own url: ", queryErr)
		response := helpers.GenericErrorResponse{
			Status: "server_error",
			Detail: "invalid url",
		}
		helpers.WriteJsonContent(response, w, 400)
		return
	}
	uploadId := values.Get("uploadId")
	fileName := values.Get("fileName")

	if uploadId == "" {
		response := helpers.GenericErrorResponse{
			Status: "invalid_request",
			Detail: "you must specify the uploadId query parameter",
		}
		helpers.WriteJsonContent(response, w, 400)
		return
	}
	uploadSlotUuid, uuidErr := uuid.Parse(uploadId)
	if uuidErr != nil {
		response := helpers.GenericErrorResponse{
			Status: "invalid_request",
			Detail: "uploadId must be a uuid",
		}
		helpers.WriteJsonContent(response, w, 400)
		return
	}

	if fileName == "" {
		response := helpers.GenericErrorResponse{
			Status: "invalid_request",
			Detail: "you must specify the fileName query parameter",
		}
		helpers.WriteJsonContent(response, w, 400)
		return
	}

	maybeRangeHeader, rangeErr := helpers.ExtractRange(request)
	if rangeErr != nil {
		log.Printf("ERROR UploadHandler could not parse range parameter '%s': %s", request.Header.Get("Range"), rangeErr)
		response := helpers.GenericErrorResponse{
			Status: "invalid_request",
			Detail: rangeErr.Error(),
		}
		helpers.WriteJsonContent(response, w, 400)
		return
	}

	uploadSlot, slotErr := models.UploadSlotForId(uploadSlotUuid, h.redisClient)
	if slotErr != nil {
		log.Printf("ERROR UploadHandler could not get upload slot for '%s': %s", uploadSlotUuid, slotErr)
		response := helpers.GenericErrorResponse{
			Status: "db_error",
			Detail: "could not get upload slot",
		}
		helpers.WriteJsonContent(response, w, 500)
		return
	}

	if uploadSlot == nil {
		log.Printf("WARNING UploadHandler no upload slot for '%s', this might just mean it's expire", uploadSlotUuid)
		response := helpers.GenericErrorResponse{
			Status: "not_found",
			Detail: "upload slot does not exist",
		}
		helpers.WriteJsonContent(response, w, 404)
		return
	}

	//get a sanitised, absolute path to write the file
	targetFilename := getTargetFilename(h.config.StoragePrefix.LocalPath, uploadSlot.UploadPathRelative, fileName)

	log.Printf("INFO UploadHandler upload request from %s to %s", username, targetFilename)

	bytesWritten, writeErr := writeOutData(targetFilename, maybeRangeHeader, request.Body)
	if writeErr != nil {
		response := helpers.GenericErrorResponse{
			Status: "write_error",
			Detail: writeErr.Error(),
		}
		helpers.WriteJsonContent(response, w, 500)
		return
	}

	response := map[string]interface{}{
		"status":        "ok",
		"bytes_written": bytesWritten,
	}
	helpers.WriteJsonContent(response, w, 200)
}