2017-05-06 13:43:24 +02:00
package router
import (
2017-05-07 02:48:24 +02:00
"encoding/hex"
2017-05-06 13:43:24 +02:00
"errors"
2017-05-07 15:55:34 +02:00
"fmt"
"io"
"io/ioutil"
"mime/multipart"
2017-05-07 10:25:09 +02:00
"net/http"
2017-05-07 02:48:24 +02:00
"net/url"
2017-05-07 15:55:34 +02:00
"os"
2017-05-07 19:47:43 +02:00
"regexp"
2017-05-07 06:26:09 +02:00
"strconv"
2017-05-07 02:48:24 +02:00
"strings"
2017-05-07 10:25:09 +02:00
2017-05-10 20:05:22 +02:00
"github.com/ewhal/nyaa/cache"
2017-05-07 15:19:36 +02:00
"github.com/ewhal/nyaa/config"
2017-05-07 11:08:44 +02:00
"github.com/ewhal/nyaa/service/captcha"
2017-05-06 13:43:24 +02:00
"github.com/ewhal/nyaa/util"
"github.com/ewhal/nyaa/util/metainfo"
2017-05-07 11:08:44 +02:00
"github.com/microcosm-cc/bluemonday"
2017-05-06 13:43:24 +02:00
"github.com/zeebo/bencode"
)
// UploadForm serializing HTTP form for torrent upload
type UploadForm struct {
2017-05-07 19:47:43 +02:00
Name string
Magnet string
Category string
2017-05-10 22:03:14 +02:00
Remake bool
2017-05-07 19:47:43 +02:00
Description string
2017-05-10 23:53:25 +02:00
Status int
2017-05-07 11:08:44 +02:00
captcha . Captcha
2017-05-07 13:48:28 +02:00
2017-05-07 15:55:34 +02:00
Infohash string
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
CategoryID int
SubCategoryID int
2017-05-07 13:48:28 +02:00
Filesize int64
2017-05-07 15:55:34 +02:00
Filepath string
2017-05-06 13:43:24 +02:00
}
// TODO: these should be in another package (?)
2017-05-10 22:03:14 +02:00
// form names
2017-05-06 13:43:24 +02:00
const UploadFormName = "name"
const UploadFormTorrent = "torrent"
const UploadFormMagnet = "magnet"
const UploadFormCategory = "c"
2017-05-10 22:03:14 +02:00
const UploadFormRemake = "remake"
2017-05-06 13:43:24 +02:00
const UploadFormDescription = "desc"
2017-05-10 23:53:25 +02:00
const UploadFormStatus = "status"
2017-05-06 13:43:24 +02:00
2017-05-07 13:38:46 +02:00
// error indicating that you can't send both a magnet link and torrent
var ErrTorrentPlusMagnet = errors . New ( "upload either a torrent file or magnet link, not both" )
2017-05-06 13:43:24 +02:00
// error indicating a torrent is private
var ErrPrivateTorrent = errors . New ( "torrent is private" )
2017-05-07 12:20:08 +02:00
// error indicating a problem with its trackers
2017-05-07 15:19:36 +02:00
var ErrTrackerProblem = errors . New ( "torrent does not have any (working) trackers: https://" + config . WebAddress + "/faq#trackers" )
2017-05-07 12:20:08 +02:00
2017-05-06 13:43:24 +02:00
// error indicating a torrent's name is invalid
var ErrInvalidTorrentName = errors . New ( "torrent name is invalid" )
// error indicating a torrent's description is invalid
var ErrInvalidTorrentDescription = errors . New ( "torrent description is invalid" )
2017-05-07 06:26:09 +02:00
// error indicating a torrent's category is invalid
var ErrInvalidTorrentCategory = errors . New ( "torrent category is invalid" )
2017-05-07 07:18:41 +02:00
var p = bluemonday . UGCPolicy ( )
2017-05-06 13:43:24 +02:00
/ * *
UploadForm . ExtractInfo takes an http request and computes all fields for this form
* /
func ( f * UploadForm ) ExtractInfo ( r * http . Request ) error {
f . Name = r . FormValue ( UploadFormName )
f . Category = r . FormValue ( UploadFormCategory )
f . Description = r . FormValue ( UploadFormDescription )
2017-05-10 23:53:25 +02:00
f . Status , _ = strconv . Atoi ( r . FormValue ( UploadFormStatus ) )
2017-05-06 13:43:24 +02:00
f . Magnet = r . FormValue ( UploadFormMagnet )
2017-05-10 22:03:14 +02:00
f . Remake = r . FormValue ( UploadFormRemake ) == "on"
2017-05-07 11:08:44 +02:00
f . Captcha = captcha . Extract ( r )
2017-05-06 13:43:24 +02:00
2017-05-07 19:47:43 +02:00
if ! captcha . Authenticate ( f . Captcha ) {
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
// TODO: Prettier passing of mistyped Captcha errors
2017-05-07 19:47:43 +02:00
return errors . New ( captcha . ErrInvalidCaptcha . Error ( ) )
}
2017-05-07 19:41:07 +02:00
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
// trim whitespace
2017-05-06 13:43:24 +02:00
f . Name = util . TrimWhitespaces ( f . Name )
2017-05-07 07:18:41 +02:00
f . Description = p . Sanitize ( util . TrimWhitespaces ( f . Description ) )
2017-05-06 13:43:24 +02:00
f . Magnet = util . TrimWhitespaces ( f . Magnet )
2017-05-10 20:05:22 +02:00
cache . Clear ( )
2017-05-06 13:43:24 +02:00
2017-05-07 06:26:09 +02:00
catsSplit := strings . Split ( f . Category , "_" )
// need this to prevent out of index panics
if len ( catsSplit ) == 2 {
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
CatID , err := strconv . Atoi ( catsSplit [ 0 ] )
2017-05-07 06:26:09 +02:00
if err != nil {
return ErrInvalidTorrentCategory
}
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
SubCatID , err := strconv . Atoi ( catsSplit [ 1 ] )
2017-05-07 06:26:09 +02:00
if err != nil {
return ErrInvalidTorrentCategory
}
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
f . CategoryID = CatID
f . SubCategoryID = SubCatID
2017-05-07 06:26:09 +02:00
} else {
return ErrInvalidTorrentCategory
2017-05-06 13:43:24 +02:00
}
2017-05-07 13:38:46 +02:00
// first: parse torrent file (if any) to fill missing information
tfile , _ , err := r . FormFile ( UploadFormTorrent )
if err == nil {
2017-05-06 13:43:24 +02:00
var torrent metainfo . TorrentFile
2017-05-07 15:55:34 +02:00
2017-05-06 13:43:24 +02:00
// decode torrent
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
_ , seekErr := tfile . Seek ( 0 , io . SeekStart )
if seekErr != nil {
return seekErr
}
2017-05-06 13:43:24 +02:00
err = bencode . NewDecoder ( tfile ) . Decode ( & torrent )
if err != nil {
return metainfo . ErrInvalidTorrentFile
}
2017-05-07 13:38:46 +02:00
// check a few things
2017-05-06 13:43:24 +02:00
if torrent . IsPrivate ( ) {
return ErrPrivateTorrent
}
2017-05-07 12:20:08 +02:00
trackers := torrent . GetAllAnnounceURLS ( )
if ! CheckTrackers ( trackers ) {
return ErrTrackerProblem
}
2017-05-07 13:38:46 +02:00
// Name
if len ( f . Name ) == 0 {
f . Name = torrent . TorrentName ( )
}
// Magnet link: if a file is provided it should be empty
if len ( f . Magnet ) != 0 {
return ErrTorrentPlusMagnet
}
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
binInfohash , err := torrent . Infohash ( )
if err != nil {
return err
}
2017-05-07 13:38:46 +02:00
f . Infohash = strings . ToUpper ( hex . EncodeToString ( binInfohash [ : ] ) )
2017-05-07 19:47:43 +02:00
f . Magnet = util . InfoHashToMagnet ( f . Infohash , f . Name , trackers ... )
2017-05-07 13:48:28 +02:00
// extract filesize
f . Filesize = int64 ( torrent . TotalSize ( ) )
2017-05-07 02:48:24 +02:00
} else {
2017-05-07 13:38:46 +02:00
// No torrent file provided
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
magnetURL , parseErr := url . Parse ( f . Magnet )
2017-05-07 02:48:24 +02:00
if parseErr != nil {
return metainfo . ErrInvalidTorrentFile
}
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
exactTopic := magnetURL . Query ( ) . Get ( "xt" )
2017-05-07 02:48:24 +02:00
if ! strings . HasPrefix ( exactTopic , "urn:btih:" ) {
return metainfo . ErrInvalidTorrentFile
}
2017-05-07 13:38:46 +02:00
f . Infohash = strings . ToUpper ( strings . TrimPrefix ( exactTopic , "urn:btih:" ) )
matched , err := regexp . MatchString ( "^[0-9A-F]{40}$" , f . Infohash )
if err != nil || ! matched {
return metainfo . ErrInvalidTorrentFile
}
2017-05-07 13:48:28 +02:00
f . Filesize = 0
2017-05-07 15:55:34 +02:00
f . Filepath = ""
2017-05-07 13:38:46 +02:00
}
// then actually check that we have everything we need
if len ( f . Name ) == 0 {
return ErrInvalidTorrentName
2017-05-06 13:43:24 +02:00
}
2017-05-07 02:48:24 +02:00
2017-05-07 15:55:34 +02:00
// after data has been checked & extracted, write it to disk
if len ( config . TorrentFileStorage ) > 0 {
2017-05-07 19:47:43 +02:00
err := WriteTorrentToDisk ( tfile , f . Infohash + ".torrent" , & f . Filepath )
2017-05-07 15:55:34 +02:00
if err != nil {
return err
}
} else {
f . Filepath = ""
}
2017-05-06 13:43:24 +02:00
return nil
}
2017-05-07 15:55:34 +02:00
func WriteTorrentToDisk ( file multipart . File , name string , fullpath * string ) error {
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
_ , seekErr := file . Seek ( 0 , io . SeekStart )
if seekErr != nil {
return seekErr
}
2017-05-07 15:55:34 +02:00
b , err := ioutil . ReadAll ( file )
if err != nil {
return err
}
* fullpath = fmt . Sprintf ( "%s%c%s" , config . TorrentFileStorage , os . PathSeparator , name )
return ioutil . WriteFile ( * fullpath , b , 0644 )
}
2017-05-07 12:20:08 +02:00
func CheckTrackers ( trackers [ ] string ) bool {
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
// TODO: move to runtime configuration
var deadTrackers = [ ] string { // substring matches!
"://open.nyaatorrents.info:6544" ,
"://tracker.openbittorrent.com:80" ,
"://tracker.publicbt.com:80" ,
"://stats.anisource.net:2710" ,
"://exodus.desync.com" ,
"://open.demonii.com:1337" ,
"://tracker.istole.it:80" ,
"://tracker.ccc.de:80" ,
"://bt2.careland.com.cn:6969" ,
"://announce.torrentsmd.com:8080" }
2017-05-07 12:20:08 +02:00
var numGood int
for _ , t := range trackers {
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
good := true
for _ , check := range deadTrackers {
2017-05-07 12:20:08 +02:00
if strings . Contains ( t , check ) {
good = false
}
}
if good {
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
numGood ++
2017-05-07 12:20:08 +02:00
}
}
return numGood > 0
}
2017-05-06 13:43:24 +02:00
// NewUploadForm creates a new upload form given parameters as list
func NewUploadForm ( params ... string ) ( uploadForm UploadForm ) {
if len ( params ) > 1 {
uploadForm . Category = params [ 0 ]
} else {
uploadForm . Category = "3_12"
}
if len ( params ) > 2 {
uploadForm . Description = params [ 1 ]
} else {
uploadForm . Description = "Description"
}
return
}