mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 11:42:24 -05:00 
			
		
		
		
	[feature] update config types to use bytesize.Size (#828)
* update config size types to use bytesize.Size
* submit unchecked-out file ... 🤦
* fix bytesize config var decoding
* bump bytesize version
* update kim's libraries in readme
* update envparse.sh to output more useful errors
* improve envparse.sh
* remove reliance on jq
* instead, use uint64 for bytesize flag types
* remove redundant type
* fix viper unmarshaling
* Update envparsing.sh
* fix envparsing test
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tobi <31960611+tsmethurst@users.noreply.github.com>
	
	
This commit is contained in:
		
					parent
					
						
							
								f0bf69d4d0
							
						
					
				
			
			
				commit
				
					
						1d999712e6
					
				
			
		
					 30 changed files with 223 additions and 169 deletions
				
			
		|  | @ -219,6 +219,8 @@ The following libraries and frameworks are used by GoToSocial, with gratitude  | ||||||
| - [go-playground/validator](https://github.com/go-playground/validator); struct validation. [MIT License](https://spdx.org/licenses/MIT.html). | - [go-playground/validator](https://github.com/go-playground/validator); struct validation. [MIT License](https://spdx.org/licenses/MIT.html). | ||||||
| - [gorilla/websocket](https://github.com/gorilla/websocket); Websocket connectivity. [BSD-2-Clause License](https://spdx.org/licenses/BSD-2-Clause.html). | - [gorilla/websocket](https://github.com/gorilla/websocket); Websocket connectivity. [BSD-2-Clause License](https://spdx.org/licenses/BSD-2-Clause.html). | ||||||
| - [gruf/go-debug](https://codeberg.org/gruf/go-debug); profiling support in debug builds. [MIT License](https://spdx.org/licenses/MIT.html). | - [gruf/go-debug](https://codeberg.org/gruf/go-debug); profiling support in debug builds. [MIT License](https://spdx.org/licenses/MIT.html). | ||||||
|  | - [gruf/go-bytesize](https://codeberg.org/gruf/go-bytesize); byte size parsing / formatting. [MIT License](https://spdx.org/licenses/MIT.html). | ||||||
|  | - [gruf/go-cache](https://codeberg.org/gruf/go-cache); object caching. [MIT License](https://spdx.org/licenses/MIT.html). | ||||||
| - [gruf/go-kv](https://codeberg.org/gruf/go-kv); key-value field formatting. [MIT License](https://spdx.org/licenses/MIT.html). | - [gruf/go-kv](https://codeberg.org/gruf/go-kv); key-value field formatting. [MIT License](https://spdx.org/licenses/MIT.html). | ||||||
| - [gruf/go-mutexes](https://codeberg.org/gruf/go-mutexes); mutex map. [MIT License](https://spdx.org/licenses/MIT.html). | - [gruf/go-mutexes](https://codeberg.org/gruf/go-mutexes); mutex map. [MIT License](https://spdx.org/licenses/MIT.html). | ||||||
| - [gruf/go-runners](https://codeberg.org/gruf/go-runners); worker pool library. [MIT License](https://spdx.org/licenses/MIT.html). | - [gruf/go-runners](https://codeberg.org/gruf/go-runners); worker pool library. [MIT License](https://spdx.org/licenses/MIT.html). | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
										
									
									
									
								
							|  | @ -4,7 +4,7 @@ go 1.19 | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
| 	codeberg.org/gruf/go-atomics v1.1.0 | 	codeberg.org/gruf/go-atomics v1.1.0 | ||||||
| 	codeberg.org/gruf/go-bytesize v0.2.1 | 	codeberg.org/gruf/go-bytesize v1.0.0 | ||||||
| 	codeberg.org/gruf/go-byteutil v1.0.2 | 	codeberg.org/gruf/go-byteutil v1.0.2 | ||||||
| 	codeberg.org/gruf/go-cache/v2 v2.1.4 | 	codeberg.org/gruf/go-cache/v2 v2.1.4 | ||||||
| 	codeberg.org/gruf/go-debug v1.2.0 | 	codeberg.org/gruf/go-debug v1.2.0 | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								go.sum
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
										
									
									
									
								
							|  | @ -64,8 +64,8 @@ codeberg.org/gruf/go-bitutil v1.0.1/go.mod h1:3ezHnADoiRJs9jgn65AEZ3HY7dsabAYLmm | ||||||
| codeberg.org/gruf/go-bytes v1.0.0/go.mod h1:1v/ibfaosfXSZtRdW2rWaVrDXMc9E3bsi/M9Ekx39cg= | codeberg.org/gruf/go-bytes v1.0.0/go.mod h1:1v/ibfaosfXSZtRdW2rWaVrDXMc9E3bsi/M9Ekx39cg= | ||||||
| codeberg.org/gruf/go-bytes v1.0.2 h1:malqE42Ni+h1nnYWBUAJaDDtEzF4aeN4uPN8DfMNNvo= | codeberg.org/gruf/go-bytes v1.0.2 h1:malqE42Ni+h1nnYWBUAJaDDtEzF4aeN4uPN8DfMNNvo= | ||||||
| codeberg.org/gruf/go-bytes v1.0.2/go.mod h1:1v/ibfaosfXSZtRdW2rWaVrDXMc9E3bsi/M9Ekx39cg= | codeberg.org/gruf/go-bytes v1.0.2/go.mod h1:1v/ibfaosfXSZtRdW2rWaVrDXMc9E3bsi/M9Ekx39cg= | ||||||
| codeberg.org/gruf/go-bytesize v0.2.1 h1:nbAta3FCYe3Q18osqg8Ylk/naOopdqEKiKMpo6KTpAA= | codeberg.org/gruf/go-bytesize v1.0.0 h1:/Mcv4prniJLkPEqZ+LZ5/D/e27rNrZZEMmty9jpIvlc= | ||||||
| codeberg.org/gruf/go-bytesize v0.2.1/go.mod h1:n/GU8HzL9f3UNp/mUKyr1qVmTlj7+xacpp0OHfkvLPs= | codeberg.org/gruf/go-bytesize v1.0.0/go.mod h1:n/GU8HzL9f3UNp/mUKyr1qVmTlj7+xacpp0OHfkvLPs= | ||||||
| codeberg.org/gruf/go-byteutil v1.0.0/go.mod h1:cWM3tgMCroSzqoBXUXMhvxTxYJp+TbCr6ioISRY5vSU= | codeberg.org/gruf/go-byteutil v1.0.0/go.mod h1:cWM3tgMCroSzqoBXUXMhvxTxYJp+TbCr6ioISRY5vSU= | ||||||
| codeberg.org/gruf/go-byteutil v1.0.2 h1:OesVyK5VKWeWdeDR00zRJ+Oy8hjXx1pBhn7WVvcZWVE= | codeberg.org/gruf/go-byteutil v1.0.2 h1:OesVyK5VKWeWdeDR00zRJ+Oy8hjXx1pBhn7WVvcZWVE= | ||||||
| codeberg.org/gruf/go-byteutil v1.0.2/go.mod h1:cWM3tgMCroSzqoBXUXMhvxTxYJp+TbCr6ioISRY5vSU= | codeberg.org/gruf/go-byteutil v1.0.2/go.mod h1:cWM3tgMCroSzqoBXUXMhvxTxYJp+TbCr6ioISRY5vSU= | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ package config | ||||||
| import ( | import ( | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 
 | 
 | ||||||
|  | 	"codeberg.org/gruf/go-bytesize" | ||||||
| 	"github.com/mitchellh/mapstructure" | 	"github.com/mitchellh/mapstructure" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -76,13 +77,13 @@ type Configuration struct { | ||||||
| 	AccountsReasonRequired   bool `name:"accounts-reason-required" usage:"Do new account signups require a reason to be submitted on registration?"` | 	AccountsReasonRequired   bool `name:"accounts-reason-required" usage:"Do new account signups require a reason to be submitted on registration?"` | ||||||
| 	AccountsAllowCustomCSS   bool `name:"accounts-allow-custom-css" usage:"Allow accounts to enable custom CSS for their profile pages and statuses."` | 	AccountsAllowCustomCSS   bool `name:"accounts-allow-custom-css" usage:"Allow accounts to enable custom CSS for their profile pages and statuses."` | ||||||
| 
 | 
 | ||||||
| 	MediaImageMaxSize        int `name:"media-image-max-size" usage:"Max size of accepted images in bytes"` | 	MediaImageMaxSize        bytesize.Size `name:"media-image-max-size" usage:"Max size of accepted images in bytes"` | ||||||
| 	MediaVideoMaxSize        int `name:"media-video-max-size" usage:"Max size of accepted videos in bytes"` | 	MediaVideoMaxSize        bytesize.Size `name:"media-video-max-size" usage:"Max size of accepted videos in bytes"` | ||||||
| 	MediaDescriptionMinChars int           `name:"media-description-min-chars" usage:"Min required chars for an image description"` | 	MediaDescriptionMinChars int           `name:"media-description-min-chars" usage:"Min required chars for an image description"` | ||||||
| 	MediaDescriptionMaxChars int           `name:"media-description-max-chars" usage:"Max permitted chars for an image description"` | 	MediaDescriptionMaxChars int           `name:"media-description-max-chars" usage:"Max permitted chars for an image description"` | ||||||
| 	MediaRemoteCacheDays     int           `name:"media-remote-cache-days" usage:"Number of days to locally cache media from remote instances. If set to 0, remote media will be kept indefinitely."` | 	MediaRemoteCacheDays     int           `name:"media-remote-cache-days" usage:"Number of days to locally cache media from remote instances. If set to 0, remote media will be kept indefinitely."` | ||||||
| 	MediaEmojiLocalMaxSize   int `name:"media-emoji-local-max-size" usage:"Max size in bytes of emojis uploaded to this instance via the admin API."` | 	MediaEmojiLocalMaxSize   bytesize.Size `name:"media-emoji-local-max-size" usage:"Max size in bytes of emojis uploaded to this instance via the admin API."` | ||||||
| 	MediaEmojiRemoteMaxSize  int `name:"media-emoji-remote-max-size" usage:"Max size in bytes of emojis to download from other instances."` | 	MediaEmojiRemoteMaxSize  bytesize.Size `name:"media-emoji-remote-max-size" usage:"Max size in bytes of emojis to download from other instances."` | ||||||
| 
 | 
 | ||||||
| 	StorageBackend       string `name:"storage-backend" usage:"Storage backend to use for media attachments"` | 	StorageBackend       string `name:"storage-backend" usage:"Storage backend to use for media attachments"` | ||||||
| 	StorageLocalBasePath string `name:"storage-local-base-path" usage:"Full path to an already-created directory where gts should store/retrieve media files. Subfolders will be created within this dir."` | 	StorageLocalBasePath string `name:"storage-local-base-path" usage:"Full path to an already-created directory where gts should store/retrieve media files. Subfolders will be created within this dir."` | ||||||
|  |  | ||||||
|  | @ -72,13 +72,13 @@ func AddServerFlags(cmd *cobra.Command) { | ||||||
| 		cmd.Flags().Bool(AccountsAllowCustomCSSFlag(), cfg.AccountsAllowCustomCSS, fieldtag("AccountsAllowCustomCSS", "usage")) | 		cmd.Flags().Bool(AccountsAllowCustomCSSFlag(), cfg.AccountsAllowCustomCSS, fieldtag("AccountsAllowCustomCSS", "usage")) | ||||||
| 
 | 
 | ||||||
| 		// Media | 		// Media | ||||||
| 		cmd.Flags().Int(MediaImageMaxSizeFlag(), cfg.MediaImageMaxSize, fieldtag("MediaImageMaxSize", "usage")) | 		cmd.Flags().Uint64(MediaImageMaxSizeFlag(), uint64(cfg.MediaImageMaxSize), fieldtag("MediaImageMaxSize", "usage")) | ||||||
| 		cmd.Flags().Int(MediaVideoMaxSizeFlag(), cfg.MediaVideoMaxSize, fieldtag("MediaVideoMaxSize", "usage")) | 		cmd.Flags().Uint64(MediaVideoMaxSizeFlag(), uint64(cfg.MediaVideoMaxSize), fieldtag("MediaVideoMaxSize", "usage")) | ||||||
| 		cmd.Flags().Int(MediaDescriptionMinCharsFlag(), cfg.MediaDescriptionMinChars, fieldtag("MediaDescriptionMinChars", "usage")) | 		cmd.Flags().Int(MediaDescriptionMinCharsFlag(), cfg.MediaDescriptionMinChars, fieldtag("MediaDescriptionMinChars", "usage")) | ||||||
| 		cmd.Flags().Int(MediaDescriptionMaxCharsFlag(), cfg.MediaDescriptionMaxChars, fieldtag("MediaDescriptionMaxChars", "usage")) | 		cmd.Flags().Int(MediaDescriptionMaxCharsFlag(), cfg.MediaDescriptionMaxChars, fieldtag("MediaDescriptionMaxChars", "usage")) | ||||||
| 		cmd.Flags().Int(MediaRemoteCacheDaysFlag(), cfg.MediaRemoteCacheDays, fieldtag("MediaRemoteCacheDays", "usage")) | 		cmd.Flags().Int(MediaRemoteCacheDaysFlag(), cfg.MediaRemoteCacheDays, fieldtag("MediaRemoteCacheDays", "usage")) | ||||||
| 		cmd.Flags().Int(MediaEmojiLocalMaxSizeFlag(), cfg.MediaEmojiLocalMaxSize, fieldtag("MediaEmojiLocalMaxSize", "usage")) | 		cmd.Flags().Uint64(MediaEmojiLocalMaxSizeFlag(), uint64(cfg.MediaEmojiLocalMaxSize), fieldtag("MediaEmojiLocalMaxSize", "usage")) | ||||||
| 		cmd.Flags().Int(MediaEmojiRemoteMaxSizeFlag(), cfg.MediaEmojiRemoteMaxSize, fieldtag("MediaEmojiRemoteMaxSize", "usage")) | 		cmd.Flags().Uint64(MediaEmojiRemoteMaxSizeFlag(), uint64(cfg.MediaEmojiRemoteMaxSize), fieldtag("MediaEmojiRemoteMaxSize", "usage")) | ||||||
| 
 | 
 | ||||||
| 		// Storage | 		// Storage | ||||||
| 		cmd.Flags().String(StorageBackendFlag(), cfg.StorageBackend, fieldtag("StorageBackend", "usage")) | 		cmd.Flags().String(StorageBackendFlag(), cfg.StorageBackend, fieldtag("StorageBackend", "usage")) | ||||||
|  |  | ||||||
|  | @ -100,7 +100,7 @@ func main() { | ||||||
| 			fmt.Fprintf(output, "func Set%[1]s(v %[2]s) { global.Set%[1]s(v) }\n\n", field.Name, field.Type.String()) | 			fmt.Fprintf(output, "func Set%[1]s(v %[2]s) { global.Set%[1]s(v) }\n\n", field.Name, field.Type.String()) | ||||||
| 		} | 		} | ||||||
| 		_ = output.Close() | 		_ = output.Close() | ||||||
| 		_ = exec.Command("gofmt", "-w", out).Run() | 		_ = exec.Command("gofumports", "-w", out).Run() | ||||||
| 
 | 
 | ||||||
| 	// The plain here is that eventually we might be able | 	// The plain here is that eventually we might be able | ||||||
| 	// to generate an example configuration from struct tags | 	// to generate an example configuration from struct tags | ||||||
|  |  | ||||||
|  | @ -18,7 +18,9 @@ | ||||||
| 
 | 
 | ||||||
| package config | package config | ||||||
| 
 | 
 | ||||||
| import "github.com/spf13/cobra" | import ( | ||||||
|  | 	"github.com/spf13/cobra" | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| var global *ConfigState | var global *ConfigState | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -18,6 +18,8 @@ | ||||||
| */ | */ | ||||||
| package config | package config | ||||||
| 
 | 
 | ||||||
|  | import "codeberg.org/gruf/go-bytesize" | ||||||
|  | 
 | ||||||
| // GetLogLevel safely fetches the Configuration value for state's 'LogLevel' field | // GetLogLevel safely fetches the Configuration value for state's 'LogLevel' field | ||||||
| func (st *ConfigState) GetLogLevel() (v string) { | func (st *ConfigState) GetLogLevel() (v string) { | ||||||
| 	st.mutex.Lock() | 	st.mutex.Lock() | ||||||
|  | @ -719,7 +721,7 @@ func GetAccountsAllowCustomCSS() bool { return global.GetAccountsAllowCustomCSS( | ||||||
| func SetAccountsAllowCustomCSS(v bool) { global.SetAccountsAllowCustomCSS(v) } | func SetAccountsAllowCustomCSS(v bool) { global.SetAccountsAllowCustomCSS(v) } | ||||||
| 
 | 
 | ||||||
| // GetMediaImageMaxSize safely fetches the Configuration value for state's 'MediaImageMaxSize' field | // GetMediaImageMaxSize safely fetches the Configuration value for state's 'MediaImageMaxSize' field | ||||||
| func (st *ConfigState) GetMediaImageMaxSize() (v int) { | func (st *ConfigState) GetMediaImageMaxSize() (v bytesize.Size) { | ||||||
| 	st.mutex.Lock() | 	st.mutex.Lock() | ||||||
| 	v = st.config.MediaImageMaxSize | 	v = st.config.MediaImageMaxSize | ||||||
| 	st.mutex.Unlock() | 	st.mutex.Unlock() | ||||||
|  | @ -727,7 +729,7 @@ func (st *ConfigState) GetMediaImageMaxSize() (v int) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SetMediaImageMaxSize safely sets the Configuration value for state's 'MediaImageMaxSize' field | // SetMediaImageMaxSize safely sets the Configuration value for state's 'MediaImageMaxSize' field | ||||||
| func (st *ConfigState) SetMediaImageMaxSize(v int) { | func (st *ConfigState) SetMediaImageMaxSize(v bytesize.Size) { | ||||||
| 	st.mutex.Lock() | 	st.mutex.Lock() | ||||||
| 	defer st.mutex.Unlock() | 	defer st.mutex.Unlock() | ||||||
| 	st.config.MediaImageMaxSize = v | 	st.config.MediaImageMaxSize = v | ||||||
|  | @ -738,13 +740,13 @@ func (st *ConfigState) SetMediaImageMaxSize(v int) { | ||||||
| func MediaImageMaxSizeFlag() string { return "media-image-max-size" } | func MediaImageMaxSizeFlag() string { return "media-image-max-size" } | ||||||
| 
 | 
 | ||||||
| // GetMediaImageMaxSize safely fetches the value for global configuration 'MediaImageMaxSize' field | // GetMediaImageMaxSize safely fetches the value for global configuration 'MediaImageMaxSize' field | ||||||
| func GetMediaImageMaxSize() int { return global.GetMediaImageMaxSize() } | func GetMediaImageMaxSize() bytesize.Size { return global.GetMediaImageMaxSize() } | ||||||
| 
 | 
 | ||||||
| // SetMediaImageMaxSize safely sets the value for global configuration 'MediaImageMaxSize' field | // SetMediaImageMaxSize safely sets the value for global configuration 'MediaImageMaxSize' field | ||||||
| func SetMediaImageMaxSize(v int) { global.SetMediaImageMaxSize(v) } | func SetMediaImageMaxSize(v bytesize.Size) { global.SetMediaImageMaxSize(v) } | ||||||
| 
 | 
 | ||||||
| // GetMediaVideoMaxSize safely fetches the Configuration value for state's 'MediaVideoMaxSize' field | // GetMediaVideoMaxSize safely fetches the Configuration value for state's 'MediaVideoMaxSize' field | ||||||
| func (st *ConfigState) GetMediaVideoMaxSize() (v int) { | func (st *ConfigState) GetMediaVideoMaxSize() (v bytesize.Size) { | ||||||
| 	st.mutex.Lock() | 	st.mutex.Lock() | ||||||
| 	v = st.config.MediaVideoMaxSize | 	v = st.config.MediaVideoMaxSize | ||||||
| 	st.mutex.Unlock() | 	st.mutex.Unlock() | ||||||
|  | @ -752,7 +754,7 @@ func (st *ConfigState) GetMediaVideoMaxSize() (v int) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SetMediaVideoMaxSize safely sets the Configuration value for state's 'MediaVideoMaxSize' field | // SetMediaVideoMaxSize safely sets the Configuration value for state's 'MediaVideoMaxSize' field | ||||||
| func (st *ConfigState) SetMediaVideoMaxSize(v int) { | func (st *ConfigState) SetMediaVideoMaxSize(v bytesize.Size) { | ||||||
| 	st.mutex.Lock() | 	st.mutex.Lock() | ||||||
| 	defer st.mutex.Unlock() | 	defer st.mutex.Unlock() | ||||||
| 	st.config.MediaVideoMaxSize = v | 	st.config.MediaVideoMaxSize = v | ||||||
|  | @ -763,10 +765,10 @@ func (st *ConfigState) SetMediaVideoMaxSize(v int) { | ||||||
| func MediaVideoMaxSizeFlag() string { return "media-video-max-size" } | func MediaVideoMaxSizeFlag() string { return "media-video-max-size" } | ||||||
| 
 | 
 | ||||||
| // GetMediaVideoMaxSize safely fetches the value for global configuration 'MediaVideoMaxSize' field | // GetMediaVideoMaxSize safely fetches the value for global configuration 'MediaVideoMaxSize' field | ||||||
| func GetMediaVideoMaxSize() int { return global.GetMediaVideoMaxSize() } | func GetMediaVideoMaxSize() bytesize.Size { return global.GetMediaVideoMaxSize() } | ||||||
| 
 | 
 | ||||||
| // SetMediaVideoMaxSize safely sets the value for global configuration 'MediaVideoMaxSize' field | // SetMediaVideoMaxSize safely sets the value for global configuration 'MediaVideoMaxSize' field | ||||||
| func SetMediaVideoMaxSize(v int) { global.SetMediaVideoMaxSize(v) } | func SetMediaVideoMaxSize(v bytesize.Size) { global.SetMediaVideoMaxSize(v) } | ||||||
| 
 | 
 | ||||||
| // GetMediaDescriptionMinChars safely fetches the Configuration value for state's 'MediaDescriptionMinChars' field | // GetMediaDescriptionMinChars safely fetches the Configuration value for state's 'MediaDescriptionMinChars' field | ||||||
| func (st *ConfigState) GetMediaDescriptionMinChars() (v int) { | func (st *ConfigState) GetMediaDescriptionMinChars() (v int) { | ||||||
|  | @ -844,7 +846,7 @@ func GetMediaRemoteCacheDays() int { return global.GetMediaRemoteCacheDays() } | ||||||
| func SetMediaRemoteCacheDays(v int) { global.SetMediaRemoteCacheDays(v) } | func SetMediaRemoteCacheDays(v int) { global.SetMediaRemoteCacheDays(v) } | ||||||
| 
 | 
 | ||||||
| // GetMediaEmojiLocalMaxSize safely fetches the Configuration value for state's 'MediaEmojiLocalMaxSize' field | // GetMediaEmojiLocalMaxSize safely fetches the Configuration value for state's 'MediaEmojiLocalMaxSize' field | ||||||
| func (st *ConfigState) GetMediaEmojiLocalMaxSize() (v int) { | func (st *ConfigState) GetMediaEmojiLocalMaxSize() (v bytesize.Size) { | ||||||
| 	st.mutex.Lock() | 	st.mutex.Lock() | ||||||
| 	v = st.config.MediaEmojiLocalMaxSize | 	v = st.config.MediaEmojiLocalMaxSize | ||||||
| 	st.mutex.Unlock() | 	st.mutex.Unlock() | ||||||
|  | @ -852,7 +854,7 @@ func (st *ConfigState) GetMediaEmojiLocalMaxSize() (v int) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SetMediaEmojiLocalMaxSize safely sets the Configuration value for state's 'MediaEmojiLocalMaxSize' field | // SetMediaEmojiLocalMaxSize safely sets the Configuration value for state's 'MediaEmojiLocalMaxSize' field | ||||||
| func (st *ConfigState) SetMediaEmojiLocalMaxSize(v int) { | func (st *ConfigState) SetMediaEmojiLocalMaxSize(v bytesize.Size) { | ||||||
| 	st.mutex.Lock() | 	st.mutex.Lock() | ||||||
| 	defer st.mutex.Unlock() | 	defer st.mutex.Unlock() | ||||||
| 	st.config.MediaEmojiLocalMaxSize = v | 	st.config.MediaEmojiLocalMaxSize = v | ||||||
|  | @ -863,13 +865,13 @@ func (st *ConfigState) SetMediaEmojiLocalMaxSize(v int) { | ||||||
| func MediaEmojiLocalMaxSizeFlag() string { return "media-emoji-local-max-size" } | func MediaEmojiLocalMaxSizeFlag() string { return "media-emoji-local-max-size" } | ||||||
| 
 | 
 | ||||||
| // GetMediaEmojiLocalMaxSize safely fetches the value for global configuration 'MediaEmojiLocalMaxSize' field | // GetMediaEmojiLocalMaxSize safely fetches the value for global configuration 'MediaEmojiLocalMaxSize' field | ||||||
| func GetMediaEmojiLocalMaxSize() int { return global.GetMediaEmojiLocalMaxSize() } | func GetMediaEmojiLocalMaxSize() bytesize.Size { return global.GetMediaEmojiLocalMaxSize() } | ||||||
| 
 | 
 | ||||||
| // SetMediaEmojiLocalMaxSize safely sets the value for global configuration 'MediaEmojiLocalMaxSize' field | // SetMediaEmojiLocalMaxSize safely sets the value for global configuration 'MediaEmojiLocalMaxSize' field | ||||||
| func SetMediaEmojiLocalMaxSize(v int) { global.SetMediaEmojiLocalMaxSize(v) } | func SetMediaEmojiLocalMaxSize(v bytesize.Size) { global.SetMediaEmojiLocalMaxSize(v) } | ||||||
| 
 | 
 | ||||||
| // GetMediaEmojiRemoteMaxSize safely fetches the Configuration value for state's 'MediaEmojiRemoteMaxSize' field | // GetMediaEmojiRemoteMaxSize safely fetches the Configuration value for state's 'MediaEmojiRemoteMaxSize' field | ||||||
| func (st *ConfigState) GetMediaEmojiRemoteMaxSize() (v int) { | func (st *ConfigState) GetMediaEmojiRemoteMaxSize() (v bytesize.Size) { | ||||||
| 	st.mutex.Lock() | 	st.mutex.Lock() | ||||||
| 	v = st.config.MediaEmojiRemoteMaxSize | 	v = st.config.MediaEmojiRemoteMaxSize | ||||||
| 	st.mutex.Unlock() | 	st.mutex.Unlock() | ||||||
|  | @ -877,7 +879,7 @@ func (st *ConfigState) GetMediaEmojiRemoteMaxSize() (v int) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SetMediaEmojiRemoteMaxSize safely sets the Configuration value for state's 'MediaEmojiRemoteMaxSize' field | // SetMediaEmojiRemoteMaxSize safely sets the Configuration value for state's 'MediaEmojiRemoteMaxSize' field | ||||||
| func (st *ConfigState) SetMediaEmojiRemoteMaxSize(v int) { | func (st *ConfigState) SetMediaEmojiRemoteMaxSize(v bytesize.Size) { | ||||||
| 	st.mutex.Lock() | 	st.mutex.Lock() | ||||||
| 	defer st.mutex.Unlock() | 	defer st.mutex.Unlock() | ||||||
| 	st.config.MediaEmojiRemoteMaxSize = v | 	st.config.MediaEmojiRemoteMaxSize = v | ||||||
|  | @ -888,10 +890,10 @@ func (st *ConfigState) SetMediaEmojiRemoteMaxSize(v int) { | ||||||
| func MediaEmojiRemoteMaxSizeFlag() string { return "media-emoji-remote-max-size" } | func MediaEmojiRemoteMaxSizeFlag() string { return "media-emoji-remote-max-size" } | ||||||
| 
 | 
 | ||||||
| // GetMediaEmojiRemoteMaxSize safely fetches the value for global configuration 'MediaEmojiRemoteMaxSize' field | // GetMediaEmojiRemoteMaxSize safely fetches the value for global configuration 'MediaEmojiRemoteMaxSize' field | ||||||
| func GetMediaEmojiRemoteMaxSize() int { return global.GetMediaEmojiRemoteMaxSize() } | func GetMediaEmojiRemoteMaxSize() bytesize.Size { return global.GetMediaEmojiRemoteMaxSize() } | ||||||
| 
 | 
 | ||||||
| // SetMediaEmojiRemoteMaxSize safely sets the value for global configuration 'MediaEmojiRemoteMaxSize' field | // SetMediaEmojiRemoteMaxSize safely sets the value for global configuration 'MediaEmojiRemoteMaxSize' field | ||||||
| func SetMediaEmojiRemoteMaxSize(v int) { global.SetMediaEmojiRemoteMaxSize(v) } | func SetMediaEmojiRemoteMaxSize(v bytesize.Size) { global.SetMediaEmojiRemoteMaxSize(v) } | ||||||
| 
 | 
 | ||||||
| // GetStorageBackend safely fetches the Configuration value for state's 'StorageBackend' field | // GetStorageBackend safely fetches the Configuration value for state's 'StorageBackend' field | ||||||
| func (st *ConfigState) GetStorageBackend() (v string) { | func (st *ConfigState) GetStorageBackend() (v string) { | ||||||
|  |  | ||||||
|  | @ -133,6 +133,12 @@ func (st *ConfigState) reloadFromViper() { | ||||||
| 	if err := st.viper.Unmarshal(&st.config, func(c *mapstructure.DecoderConfig) { | 	if err := st.viper.Unmarshal(&st.config, func(c *mapstructure.DecoderConfig) { | ||||||
| 		c.TagName = "name" | 		c.TagName = "name" | ||||||
| 		c.ZeroFields = true // empty the config struct before we marshal values into it | 		c.ZeroFields = true // empty the config struct before we marshal values into it | ||||||
|  | 
 | ||||||
|  | 		oldhook := c.DecodeHook | ||||||
|  | 		c.DecodeHook = mapstructure.ComposeDecodeHookFunc( | ||||||
|  | 			mapstructure.TextUnmarshallerHookFunc(), | ||||||
|  | 			oldhook, | ||||||
|  | 		) | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -67,14 +67,6 @@ func Validate() error { | ||||||
| 		errs = append(errs, fmt.Errorf("%s must be set", WebAssetBaseDirFlag())) | 		errs = append(errs, fmt.Errorf("%s must be set", WebAssetBaseDirFlag())) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if m := GetMediaEmojiLocalMaxSize(); m < 0 { |  | ||||||
| 		errs = append(errs, fmt.Errorf("%s must not be less than 0", MediaEmojiLocalMaxSizeFlag())) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if m := GetMediaEmojiRemoteMaxSize(); m < 0 { |  | ||||||
| 		errs = append(errs, fmt.Errorf("%s must not be less than 0", MediaEmojiRemoteMaxSizeFlag())) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if len(errs) > 0 { | 	if len(errs) > 0 { | ||||||
| 		errStrings := []string{} | 		errStrings := []string{} | ||||||
| 		for _, err := range errs { | 		for _, err := range errs { | ||||||
|  |  | ||||||
|  | @ -141,16 +141,6 @@ func (suite *ConfigValidateTestSuite) TestValidateConfigBadProtocolNoHost() { | ||||||
| 	suite.EqualError(err, "host must be set; protocol must be set to either http or https, provided value was foo") | 	suite.EqualError(err, "host must be set; protocol must be set to either http or https, provided value was foo") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *ConfigValidateTestSuite) TestValidateConfigBadEmojiSizes() { |  | ||||||
| 	testrig.InitTestConfig() |  | ||||||
| 
 |  | ||||||
| 	config.SetMediaEmojiLocalMaxSize(-10) |  | ||||||
| 	config.SetMediaEmojiRemoteMaxSize(-50) |  | ||||||
| 
 |  | ||||||
| 	err := config.Validate() |  | ||||||
| 	suite.EqualError(err, "media-emoji-local-max-size must not be less than 0; media-emoji-remote-max-size must not be less than 0") |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestConfigValidateTestSuite(t *testing.T) { | func TestConfigValidateTestSuite(t *testing.T) { | ||||||
| 	suite.Run(t, &ConfigValidateTestSuite{}) | 	suite.Run(t, &ConfigValidateTestSuite{}) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -496,7 +496,7 @@ func (d *deref) fetchRemoteAccountMedia(ctx context.Context, targetAccount *gtsm | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			data := func(innerCtx context.Context) (io.Reader, int, error) { | 			data := func(innerCtx context.Context) (io.Reader, int64, error) { | ||||||
| 				return t.DereferenceMedia(innerCtx, avatarIRI) | 				return t.DereferenceMedia(innerCtx, avatarIRI) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -562,7 +562,7 @@ func (d *deref) fetchRemoteAccountMedia(ctx context.Context, targetAccount *gtsm | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			data := func(innerCtx context.Context) (io.Reader, int, error) { | 			data := func(innerCtx context.Context) (io.Reader, int64, error) { | ||||||
| 				return t.DereferenceMedia(innerCtx, headerIRI) | 				return t.DereferenceMedia(innerCtx, headerIRI) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ func (d *deref) GetRemoteEmoji(ctx context.Context, requestingUsername string, r | ||||||
| 		return nil, fmt.Errorf("GetRemoteEmoji: error parsing url: %s", err) | 		return nil, fmt.Errorf("GetRemoteEmoji: error parsing url: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	dataFunc := func(innerCtx context.Context) (io.Reader, int, error) { | 	dataFunc := func(innerCtx context.Context) (io.Reader, int64, error) { | ||||||
| 		return t.DereferenceMedia(innerCtx, derefURI) | 		return t.DereferenceMedia(innerCtx, derefURI) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ func (d *deref) GetRemoteMedia(ctx context.Context, requestingUsername string, a | ||||||
| 		return nil, fmt.Errorf("GetRemoteMedia: error parsing url: %s", err) | 		return nil, fmt.Errorf("GetRemoteMedia: error parsing url: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	dataFunc := func(innerCtx context.Context) (io.Reader, int, error) { | 	dataFunc := func(innerCtx context.Context) (io.Reader, int64, error) { | ||||||
| 		return t.DereferenceMedia(innerCtx, derefURI) | 		return t.DereferenceMedia(innerCtx, derefURI) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -43,13 +43,13 @@ type ManagerTestSuite struct { | ||||||
| func (suite *ManagerTestSuite) TestEmojiProcessBlocking() { | func (suite *ManagerTestSuite) TestEmojiProcessBlocking() { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		b, err := os.ReadFile("./test/rainbow-original.png") | 		b, err := os.ReadFile("./test/rainbow-original.png") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			panic(err) | 			panic(err) | ||||||
| 		} | 		} | ||||||
| 		return bytes.NewBuffer(b), len(b), nil | 		return bytes.NewBuffer(b), int64(len(b)), nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	emojiID := "01GDQ9G782X42BAMFASKP64343" | 	emojiID := "01GDQ9G782X42BAMFASKP64343" | ||||||
|  | @ -104,13 +104,13 @@ func (suite *ManagerTestSuite) TestEmojiProcessBlocking() { | ||||||
| func (suite *ManagerTestSuite) TestEmojiProcessBlockingTooLarge() { | func (suite *ManagerTestSuite) TestEmojiProcessBlockingTooLarge() { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		b, err := os.ReadFile("./test/big-panda.gif") | 		b, err := os.ReadFile("./test/big-panda.gif") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			panic(err) | 			panic(err) | ||||||
| 		} | 		} | ||||||
| 		return bytes.NewBuffer(b), len(b), nil | 		return bytes.NewBuffer(b), int64(len(b)), nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	emojiID := "01GDQ9G782X42BAMFASKP64343" | 	emojiID := "01GDQ9G782X42BAMFASKP64343" | ||||||
|  | @ -128,13 +128,13 @@ func (suite *ManagerTestSuite) TestEmojiProcessBlockingTooLarge() { | ||||||
| func (suite *ManagerTestSuite) TestEmojiProcessBlockingTooLargeNoSizeGiven() { | func (suite *ManagerTestSuite) TestEmojiProcessBlockingTooLargeNoSizeGiven() { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		b, err := os.ReadFile("./test/big-panda.gif") | 		b, err := os.ReadFile("./test/big-panda.gif") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			panic(err) | 			panic(err) | ||||||
| 		} | 		} | ||||||
| 		return bytes.NewBuffer(b), len(b), nil | 		return bytes.NewBuffer(b), int64(len(b)), nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	emojiID := "01GDQ9G782X42BAMFASKP64343" | 	emojiID := "01GDQ9G782X42BAMFASKP64343" | ||||||
|  | @ -152,7 +152,7 @@ func (suite *ManagerTestSuite) TestEmojiProcessBlockingTooLargeNoSizeGiven() { | ||||||
| func (suite *ManagerTestSuite) TestEmojiProcessBlockingNoFileSizeGiven() { | func (suite *ManagerTestSuite) TestEmojiProcessBlockingNoFileSizeGiven() { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		b, err := os.ReadFile("./test/rainbow-original.png") | 		b, err := os.ReadFile("./test/rainbow-original.png") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  | @ -214,13 +214,13 @@ func (suite *ManagerTestSuite) TestEmojiProcessBlockingNoFileSizeGiven() { | ||||||
| func (suite *ManagerTestSuite) TestSimpleJpegProcessBlocking() { | func (suite *ManagerTestSuite) TestSimpleJpegProcessBlocking() { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		b, err := os.ReadFile("./test/test-jpeg.jpg") | 		b, err := os.ReadFile("./test/test-jpeg.jpg") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			panic(err) | 			panic(err) | ||||||
| 		} | 		} | ||||||
| 		return bytes.NewBuffer(b), len(b), nil | 		return bytes.NewBuffer(b), int64(len(b)), nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	accountID := "01FS1X72SK9ZPW0J1QQ68BD264" | 	accountID := "01FS1X72SK9ZPW0J1QQ68BD264" | ||||||
|  | @ -286,7 +286,7 @@ func (suite *ManagerTestSuite) TestSimpleJpegProcessBlocking() { | ||||||
| func (suite *ManagerTestSuite) TestSimpleJpegProcessBlockingNoContentLengthGiven() { | func (suite *ManagerTestSuite) TestSimpleJpegProcessBlockingNoContentLengthGiven() { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		b, err := os.ReadFile("./test/test-jpeg.jpg") | 		b, err := os.ReadFile("./test/test-jpeg.jpg") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  | @ -359,7 +359,7 @@ func (suite *ManagerTestSuite) TestSimpleJpegProcessBlockingNoContentLengthGiven | ||||||
| func (suite *ManagerTestSuite) TestSimpleJpegProcessBlockingReadCloser() { | func (suite *ManagerTestSuite) TestSimpleJpegProcessBlockingReadCloser() { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// open test image as a file | 		// open test image as a file | ||||||
| 		f, err := os.Open("./test/test-jpeg.jpg") | 		f, err := os.Open("./test/test-jpeg.jpg") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  | @ -432,13 +432,13 @@ func (suite *ManagerTestSuite) TestSimpleJpegProcessBlockingReadCloser() { | ||||||
| func (suite *ManagerTestSuite) TestPngNoAlphaChannelProcessBlocking() { | func (suite *ManagerTestSuite) TestPngNoAlphaChannelProcessBlocking() { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		b, err := os.ReadFile("./test/test-png-noalphachannel.png") | 		b, err := os.ReadFile("./test/test-png-noalphachannel.png") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			panic(err) | 			panic(err) | ||||||
| 		} | 		} | ||||||
| 		return bytes.NewBuffer(b), len(b), nil | 		return bytes.NewBuffer(b), int64(len(b)), nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	accountID := "01FS1X72SK9ZPW0J1QQ68BD264" | 	accountID := "01FS1X72SK9ZPW0J1QQ68BD264" | ||||||
|  | @ -504,13 +504,13 @@ func (suite *ManagerTestSuite) TestPngNoAlphaChannelProcessBlocking() { | ||||||
| func (suite *ManagerTestSuite) TestPngAlphaChannelProcessBlocking() { | func (suite *ManagerTestSuite) TestPngAlphaChannelProcessBlocking() { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		b, err := os.ReadFile("./test/test-png-alphachannel.png") | 		b, err := os.ReadFile("./test/test-png-alphachannel.png") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			panic(err) | 			panic(err) | ||||||
| 		} | 		} | ||||||
| 		return bytes.NewBuffer(b), len(b), nil | 		return bytes.NewBuffer(b), int64(len(b)), nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	accountID := "01FS1X72SK9ZPW0J1QQ68BD264" | 	accountID := "01FS1X72SK9ZPW0J1QQ68BD264" | ||||||
|  | @ -576,13 +576,13 @@ func (suite *ManagerTestSuite) TestPngAlphaChannelProcessBlocking() { | ||||||
| func (suite *ManagerTestSuite) TestSimpleJpegProcessBlockingWithCallback() { | func (suite *ManagerTestSuite) TestSimpleJpegProcessBlockingWithCallback() { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		b, err := os.ReadFile("./test/test-jpeg.jpg") | 		b, err := os.ReadFile("./test/test-jpeg.jpg") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			panic(err) | 			panic(err) | ||||||
| 		} | 		} | ||||||
| 		return bytes.NewBuffer(b), len(b), nil | 		return bytes.NewBuffer(b), int64(len(b)), nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// test the callback function by setting a simple boolean | 	// test the callback function by setting a simple boolean | ||||||
|  | @ -659,13 +659,13 @@ func (suite *ManagerTestSuite) TestSimpleJpegProcessBlockingWithCallback() { | ||||||
| func (suite *ManagerTestSuite) TestSimpleJpegProcessAsync() { | func (suite *ManagerTestSuite) TestSimpleJpegProcessAsync() { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		b, err := os.ReadFile("./test/test-jpeg.jpg") | 		b, err := os.ReadFile("./test/test-jpeg.jpg") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			panic(err) | 			panic(err) | ||||||
| 		} | 		} | ||||||
| 		return bytes.NewBuffer(b), len(b), nil | 		return bytes.NewBuffer(b), int64(len(b)), nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	accountID := "01FS1X72SK9ZPW0J1QQ68BD264" | 	accountID := "01FS1X72SK9ZPW0J1QQ68BD264" | ||||||
|  | @ -744,9 +744,9 @@ func (suite *ManagerTestSuite) TestSimpleJpegQueueSpamming() { | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		return bytes.NewReader(b), len(b), nil | 		return bytes.NewReader(b), int64(len(b)), nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	accountID := "01FS1X72SK9ZPW0J1QQ68BD264" | 	accountID := "01FS1X72SK9ZPW0J1QQ68BD264" | ||||||
|  | @ -820,13 +820,13 @@ func (suite *ManagerTestSuite) TestSimpleJpegQueueSpamming() { | ||||||
| func (suite *ManagerTestSuite) TestSimpleJpegProcessBlockingWithDiskStorage() { | func (suite *ManagerTestSuite) TestSimpleJpegProcessBlockingWithDiskStorage() { | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 
 | 
 | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		b, err := os.ReadFile("./test/test-jpeg.jpg") | 		b, err := os.ReadFile("./test/test-jpeg.jpg") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			panic(err) | 			panic(err) | ||||||
| 		} | 		} | ||||||
| 		return bytes.NewBuffer(b), len(b), nil | 		return bytes.NewBuffer(b), int64(len(b)), nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	accountID := "01FS1X72SK9ZPW0J1QQ68BD264" | 	accountID := "01FS1X72SK9ZPW0J1QQ68BD264" | ||||||
|  |  | ||||||
|  | @ -210,11 +210,11 @@ func (p *ProcessingEmoji) store(ctx context.Context) error { | ||||||
| 	// concatenate the first bytes with the existing bytes still in the reader (thanks Mara) | 	// concatenate the first bytes with the existing bytes still in the reader (thanks Mara) | ||||||
| 	readerToStore := io.MultiReader(bytes.NewBuffer(firstBytes), reader) | 	readerToStore := io.MultiReader(bytes.NewBuffer(firstBytes), reader) | ||||||
| 
 | 
 | ||||||
| 	var maxEmojiSize int | 	var maxEmojiSize int64 | ||||||
| 	if p.emoji.Domain == "" { | 	if p.emoji.Domain == "" { | ||||||
| 		maxEmojiSize = config.GetMediaEmojiLocalMaxSize() | 		maxEmojiSize = int64(config.GetMediaEmojiLocalMaxSize()) | ||||||
| 	} else { | 	} else { | ||||||
| 		maxEmojiSize = config.GetMediaEmojiRemoteMaxSize() | 		maxEmojiSize = int64(config.GetMediaEmojiRemoteMaxSize()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// if we know the fileSize already, make sure it's not bigger than our limit | 	// if we know the fileSize already, make sure it's not bigger than our limit | ||||||
|  | @ -241,7 +241,7 @@ func (p *ProcessingEmoji) store(ctx context.Context) error { | ||||||
| 		return fmt.Errorf("store: discovered emoji fileSize (%db) is larger than allowed emojiRemoteMaxSize (%db)", fileSize, maxEmojiSize) | 		return fmt.Errorf("store: discovered emoji fileSize (%db) is larger than allowed emojiRemoteMaxSize (%db)", fileSize, maxEmojiSize) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	p.emoji.ImageFileSize = fileSize | 	p.emoji.ImageFileSize = int(fileSize) | ||||||
| 	p.read = true | 	p.read = true | ||||||
| 
 | 
 | ||||||
| 	if p.postData != nil { | 	if p.postData != nil { | ||||||
|  |  | ||||||
|  | @ -315,7 +315,7 @@ func (p *ProcessingMedia) store(ctx context.Context) error { | ||||||
| 		p.attachment.Type = gtsmodel.FileTypeImage | 		p.attachment.Type = gtsmodel.FileTypeImage | ||||||
| 		if fileSize > 0 { | 		if fileSize > 0 { | ||||||
| 			var err error | 			var err error | ||||||
| 			readerToStore, err = terminator.Terminate(readerToStore, fileSize, extension) | 			readerToStore, err = terminator.Terminate(readerToStore, int(fileSize), extension) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return fmt.Errorf("store: exif error: %s", err) | 				return fmt.Errorf("store: exif error: %s", err) | ||||||
| 			} | 			} | ||||||
|  | @ -344,7 +344,7 @@ func (p *ProcessingMedia) store(ctx context.Context) error { | ||||||
| 
 | 
 | ||||||
| 	cached := true | 	cached := true | ||||||
| 	p.attachment.Cached = &cached | 	p.attachment.Cached = &cached | ||||||
| 	p.attachment.File.FileSize = fileSize | 	p.attachment.File.FileSize = int(fileSize) | ||||||
| 	p.read = true | 	p.read = true | ||||||
| 
 | 
 | ||||||
| 	if p.postData != nil { | 	if p.postData != nil { | ||||||
|  |  | ||||||
|  | @ -74,13 +74,13 @@ func (suite *PruneRemoteTestSuite) TestPruneAndRecache() { | ||||||
| 	suite.ErrorIs(err, storage.ErrNotFound) | 	suite.ErrorIs(err, storage.ErrNotFound) | ||||||
| 
 | 
 | ||||||
| 	// now recache the image.... | 	// now recache the image.... | ||||||
| 	data := func(_ context.Context) (io.Reader, int, error) { | 	data := func(_ context.Context) (io.Reader, int64, error) { | ||||||
| 		// load bytes from a test image | 		// load bytes from a test image | ||||||
| 		b, err := os.ReadFile("../../testrig/media/thoughtsofdog-original.jpeg") | 		b, err := os.ReadFile("../../testrig/media/thoughtsofdog-original.jpeg") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			panic(err) | 			panic(err) | ||||||
| 		} | 		} | ||||||
| 		return bytes.NewBuffer(b), len(b), nil | 		return bytes.NewBuffer(b), int64(len(b)), nil | ||||||
| 	} | 	} | ||||||
| 	processingRecache, err := suite.manager.RecacheMedia(ctx, data, nil, testAttachment.ID) | 	processingRecache, err := suite.manager.RecacheMedia(ctx, data, nil, testAttachment.ID) | ||||||
| 	suite.NoError(err) | 	suite.NoError(err) | ||||||
|  |  | ||||||
|  | @ -118,7 +118,7 @@ type AdditionalEmojiInfo struct { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DataFunc represents a function used to retrieve the raw bytes of a piece of media. | // DataFunc represents a function used to retrieve the raw bytes of a piece of media. | ||||||
| type DataFunc func(ctx context.Context) (reader io.Reader, fileSize int, err error) | type DataFunc func(ctx context.Context) (reader io.Reader, fileSize int64, err error) | ||||||
| 
 | 
 | ||||||
| // PostDataCallbackFunc represents a function executed after the DataFunc has been executed, | // PostDataCallbackFunc represents a function executed after the DataFunc has been executed, | ||||||
| // and the returned reader has been read. It can be used to clean up any remaining resources. | // and the returned reader has been read. It can be used to clean up any remaining resources. | ||||||
|  |  | ||||||
|  | @ -151,19 +151,19 @@ func parseOlderThan(olderThanDays int) (time.Time, error) { | ||||||
| // lengthReader wraps a reader and reads the length of total bytes written as it goes. | // lengthReader wraps a reader and reads the length of total bytes written as it goes. | ||||||
| type lengthReader struct { | type lengthReader struct { | ||||||
| 	source io.Reader | 	source io.Reader | ||||||
| 	length int | 	length int64 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *lengthReader) Read(b []byte) (int, error) { | func (r *lengthReader) Read(b []byte) (int, error) { | ||||||
| 	n, err := r.source.Read(b) | 	n, err := r.source.Read(b) | ||||||
| 	r.length += n | 	r.length += int64(n) | ||||||
| 	return n, err | 	return n, err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // putStream either puts a file with a known fileSize into storage directly, and returns the | // putStream either puts a file with a known fileSize into storage directly, and returns the | ||||||
| // fileSize unchanged, or it wraps the reader with a lengthReader and returns the discovered | // fileSize unchanged, or it wraps the reader with a lengthReader and returns the discovered | ||||||
| // fileSize. | // fileSize. | ||||||
| func putStream(ctx context.Context, storage storage.Driver, key string, r io.Reader, fileSize int) (int, error) { | func putStream(ctx context.Context, storage storage.Driver, key string, r io.Reader, fileSize int64) (int64, error) { | ||||||
| 	if fileSize > 0 { | 	if fileSize > 0 { | ||||||
| 		return fileSize, storage.PutStream(ctx, key, r) | 		return fileSize, storage.PutStream(ctx, key, r) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -184,13 +184,13 @@ func (p *processor) Update(ctx context.Context, account *gtsmodel.Account, form | ||||||
| // the account's new avatar image. | // the account's new avatar image. | ||||||
| func (p *processor) UpdateAvatar(ctx context.Context, avatar *multipart.FileHeader, accountID string) (*gtsmodel.MediaAttachment, error) { | func (p *processor) UpdateAvatar(ctx context.Context, avatar *multipart.FileHeader, accountID string) (*gtsmodel.MediaAttachment, error) { | ||||||
| 	maxImageSize := config.GetMediaImageMaxSize() | 	maxImageSize := config.GetMediaImageMaxSize() | ||||||
| 	if int(avatar.Size) > maxImageSize { | 	if avatar.Size > int64(maxImageSize) { | ||||||
| 		return nil, fmt.Errorf("UpdateAvatar: avatar with size %d exceeded max image size of %d bytes", avatar.Size, maxImageSize) | 		return nil, fmt.Errorf("UpdateAvatar: avatar with size %d exceeded max image size of %d bytes", avatar.Size, maxImageSize) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	dataFunc := func(innerCtx context.Context) (io.Reader, int, error) { | 	dataFunc := func(innerCtx context.Context) (io.Reader, int64, error) { | ||||||
| 		f, err := avatar.Open() | 		f, err := avatar.Open() | ||||||
| 		return f, int(avatar.Size), err | 		return f, avatar.Size, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	isAvatar := true | 	isAvatar := true | ||||||
|  | @ -211,13 +211,13 @@ func (p *processor) UpdateAvatar(ctx context.Context, avatar *multipart.FileHead | ||||||
| // the account's new header image. | // the account's new header image. | ||||||
| func (p *processor) UpdateHeader(ctx context.Context, header *multipart.FileHeader, accountID string) (*gtsmodel.MediaAttachment, error) { | func (p *processor) UpdateHeader(ctx context.Context, header *multipart.FileHeader, accountID string) (*gtsmodel.MediaAttachment, error) { | ||||||
| 	maxImageSize := config.GetMediaImageMaxSize() | 	maxImageSize := config.GetMediaImageMaxSize() | ||||||
| 	if int(header.Size) > maxImageSize { | 	if header.Size > int64(maxImageSize) { | ||||||
| 		return nil, fmt.Errorf("UpdateHeader: header with size %d exceeded max image size of %d bytes", header.Size, maxImageSize) | 		return nil, fmt.Errorf("UpdateHeader: header with size %d exceeded max image size of %d bytes", header.Size, maxImageSize) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	dataFunc := func(innerCtx context.Context) (io.Reader, int, error) { | 	dataFunc := func(innerCtx context.Context) (io.Reader, int64, error) { | ||||||
| 		f, err := header.Open() | 		f, err := header.Open() | ||||||
| 		return f, int(header.Size), err | 		return f, header.Size, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	isHeader := true | 	isHeader := true | ||||||
|  |  | ||||||
|  | @ -52,9 +52,9 @@ func (p *processor) EmojiCreate(ctx context.Context, account *gtsmodel.Account, | ||||||
| 
 | 
 | ||||||
| 	emojiURI := uris.GenerateURIForEmoji(emojiID) | 	emojiURI := uris.GenerateURIForEmoji(emojiID) | ||||||
| 
 | 
 | ||||||
| 	data := func(innerCtx context.Context) (io.Reader, int, error) { | 	data := func(innerCtx context.Context) (io.Reader, int64, error) { | ||||||
| 		f, err := form.Image.Open() | 		f, err := form.Image.Open() | ||||||
| 		return f, int(form.Image.Size), err | 		return f, form.Image.Size, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	processingEmoji, err := p.mediaManager.ProcessEmoji(ctx, data, nil, form.Shortcode, emojiID, emojiURI, nil) | 	processingEmoji, err := p.mediaManager.ProcessEmoji(ctx, data, nil, form.Shortcode, emojiID, emojiURI, nil) | ||||||
|  |  | ||||||
|  | @ -30,9 +30,9 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func (p *processor) Create(ctx context.Context, account *gtsmodel.Account, form *apimodel.AttachmentRequest) (*apimodel.Attachment, gtserror.WithCode) { | func (p *processor) Create(ctx context.Context, account *gtsmodel.Account, form *apimodel.AttachmentRequest) (*apimodel.Attachment, gtserror.WithCode) { | ||||||
| 	data := func(innerCtx context.Context) (io.Reader, int, error) { | 	data := func(innerCtx context.Context) (io.Reader, int64, error) { | ||||||
| 		f, err := form.File.Open() | 		f, err := form.File.Open() | ||||||
| 		return f, int(form.File.Size), err | 		return f, form.File.Size, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	focusX, focusY, err := parseFocus(form.Focus) | 	focusX, focusY, err := parseFocus(form.Focus) | ||||||
|  |  | ||||||
|  | @ -138,7 +138,7 @@ func (p *processor) getAttachmentContent(ctx context.Context, requestingAccount | ||||||
| 		// if it's the thumbnail that's requested then the user will have to wait a bit while we process the | 		// if it's the thumbnail that's requested then the user will have to wait a bit while we process the | ||||||
| 		// large version and derive a thumbnail from it, so use the normal recaching procedure: fetch the media, | 		// large version and derive a thumbnail from it, so use the normal recaching procedure: fetch the media, | ||||||
| 		// process it, then return the thumbnail data | 		// process it, then return the thumbnail data | ||||||
| 		data = func(innerCtx context.Context) (io.Reader, int, error) { | 		data = func(innerCtx context.Context) (io.Reader, int64, error) { | ||||||
| 			transport, err := p.transportController.NewTransportForUsername(innerCtx, requestingUsername) | 			transport, err := p.transportController.NewTransportForUsername(innerCtx, requestingUsername) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, 0, err | 				return nil, 0, err | ||||||
|  | @ -169,7 +169,7 @@ func (p *processor) getAttachmentContent(ctx context.Context, requestingAccount | ||||||
| 		// the caller will read from the buffered reader, so it doesn't matter if they drop out without reading everything | 		// the caller will read from the buffered reader, so it doesn't matter if they drop out without reading everything | ||||||
| 		attachmentContent.Content = bufferedReader | 		attachmentContent.Content = bufferedReader | ||||||
| 
 | 
 | ||||||
| 		data = func(innerCtx context.Context) (io.Reader, int, error) { | 		data = func(innerCtx context.Context) (io.Reader, int64, error) { | ||||||
| 			transport, err := p.transportController.NewTransportForUsername(innerCtx, requestingUsername) | 			transport, err := p.transportController.NewTransportForUsername(innerCtx, requestingUsername) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, 0, err | 				return nil, 0, err | ||||||
|  |  | ||||||
|  | @ -26,7 +26,7 @@ import ( | ||||||
| 	"net/url" | 	"net/url" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func (t *transport) DereferenceMedia(ctx context.Context, iri *url.URL) (io.ReadCloser, int, error) { | func (t *transport) DereferenceMedia(ctx context.Context, iri *url.URL) (io.ReadCloser, int64, error) { | ||||||
| 	// Build IRI just once | 	// Build IRI just once | ||||||
| 	iriStr := iri.String() | 	iriStr := iri.String() | ||||||
| 
 | 
 | ||||||
|  | @ -50,5 +50,5 @@ func (t *transport) DereferenceMedia(ctx context.Context, iri *url.URL) (io.Read | ||||||
| 		return nil, 0, fmt.Errorf("GET request to %s failed (%d): %s", iriStr, rsp.StatusCode, rsp.Status) | 		return nil, 0, fmt.Errorf("GET request to %s failed (%d): %s", iriStr, rsp.StatusCode, rsp.Status) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return rsp.Body, int(rsp.ContentLength), nil | 	return rsp.Body, rsp.ContentLength, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -47,7 +47,7 @@ import ( | ||||||
| type Transport interface { | type Transport interface { | ||||||
| 	pub.Transport | 	pub.Transport | ||||||
| 	// DereferenceMedia fetches the given media attachment IRI, returning the reader and filesize. | 	// DereferenceMedia fetches the given media attachment IRI, returning the reader and filesize. | ||||||
| 	DereferenceMedia(ctx context.Context, iri *url.URL) (io.ReadCloser, int, error) | 	DereferenceMedia(ctx context.Context, iri *url.URL) (io.ReadCloser, int64, error) | ||||||
| 	// DereferenceInstance dereferences remote instance information, first by checking /api/v1/instance, and then by checking /.well-known/nodeinfo. | 	// DereferenceInstance dereferences remote instance information, first by checking /api/v1/instance, and then by checking /.well-known/nodeinfo. | ||||||
| 	DereferenceInstance(ctx context.Context, iri *url.URL) (*gtsmodel.Instance, error) | 	DereferenceInstance(ctx context.Context, iri *url.URL) (*gtsmodel.Instance, error) | ||||||
| 	// Finger performs a webfinger request with the given username and domain, and returns the bytes from the response body. | 	// Finger performs a webfinger request with the given username and domain, and returns the bytes from the response body. | ||||||
|  |  | ||||||
|  | @ -688,9 +688,9 @@ func (c *converter) InstanceToAPIInstance(ctx context.Context, i *gtsmodel.Insta | ||||||
| 			}, | 			}, | ||||||
| 			MediaAttachments: &model.InstanceConfigurationMediaAttachments{ | 			MediaAttachments: &model.InstanceConfigurationMediaAttachments{ | ||||||
| 				SupportedMimeTypes:  media.AllSupportedMIMETypes(), | 				SupportedMimeTypes:  media.AllSupportedMIMETypes(), | ||||||
| 				ImageSizeLimit:      config.GetMediaImageMaxSize(), | 				ImageSizeLimit:      int(config.GetMediaImageMaxSize()), | ||||||
| 				ImageMatrixLimit:    instanceMediaAttachmentsImageMatrixLimit, // height*width | 				ImageMatrixLimit:    instanceMediaAttachmentsImageMatrixLimit, // height*width | ||||||
| 				VideoSizeLimit:      config.GetMediaVideoMaxSize(), | 				VideoSizeLimit:      int(config.GetMediaVideoMaxSize()), | ||||||
| 				VideoFrameRateLimit: instanceMediaAttachmentsVideoFrameRateLimit, | 				VideoFrameRateLimit: instanceMediaAttachmentsVideoFrameRateLimit, | ||||||
| 				VideoMatrixLimit:    instanceMediaAttachmentsVideoMatrixLimit, // height*width | 				VideoMatrixLimit:    instanceMediaAttachmentsVideoMatrixLimit, // height*width | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| 
 | 
 | ||||||
| set -eu | set -eu | ||||||
| 
 | 
 | ||||||
| EXPECTED='{"account-domain":"peepee","accounts-allow-custom-css":true,"accounts-approval-required":false,"accounts-reason-required":false,"accounts-registration-open":true,"advanced-cookies-samesite":"strict","application-name":"gts","bind-address":"127.0.0.1","config-path":"./test/test.yaml","db-address":":memory:","db-database":"gotosocial_prod","db-password":"hunter2","db-port":6969,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"sqlite","db-user":"sex-haver","email":"","host":"example.com","instance-deliver-to-shared-inboxes":false,"instance-expose-peers":true,"instance-expose-suspended":true,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":true,"log-level":"info","media-description-max-chars":5000,"media-description-min-chars":69,"media-emoji-local-max-size":420,"media-emoji-remote-max-size":420,"media-image-max-size":420,"media-remote-cache-days":30,"media-video-max-size":420,"oidc-client-id":"1234","oidc-client-secret":"shhhh its a secret","oidc-enabled":true,"oidc-idp-name":"sex-haver","oidc-issuer":"whoknows","oidc-scopes":["read","write"],"oidc-skip-verification":true,"password":"","path":"","port":6969,"protocol":"http","smtp-from":"queen@terfisland.org","smtp-host":"example.com","smtp-password":"hunter2","smtp-port":4269,"smtp-username":"sex-haver","software-version":"","statuses-cw-max-chars":420,"statuses-max-chars":69,"statuses-media-max-files":1,"statuses-poll-max-options":1,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/root/store","storage-s3-access-key":"minio","storage-s3-bucket":"gts","storage-s3-endpoint":"localhost:9000","storage-s3-secret-key":"miniostorage","storage-s3-use-ssl":false,"syslog-address":"127.0.0.1:6969","syslog-enabled":true,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","docker.host.local"],"username":"","web-asset-base-dir":"/root","web-template-base-dir":"/root"}' | EXPECT='{"account-domain":"peepee","accounts-allow-custom-css":true,"accounts-approval-required":false,"accounts-reason-required":false,"accounts-registration-open":true,"advanced-cookies-samesite":"strict","application-name":"gts","bind-address":"127.0.0.1","config-path":"./test/test.yaml","db-address":":memory:","db-database":"gotosocial_prod","db-password":"hunter2","db-port":6969,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"sqlite","db-user":"sex-haver","email":"","host":"example.com","instance-deliver-to-shared-inboxes":false,"instance-expose-peers":true,"instance-expose-suspended":true,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":true,"log-level":"info","media-description-max-chars":5000,"media-description-min-chars":69,"media-emoji-local-max-size":420,"media-emoji-remote-max-size":420,"media-image-max-size":420,"media-remote-cache-days":30,"media-video-max-size":420,"oidc-client-id":"1234","oidc-client-secret":"shhhh its a secret","oidc-enabled":true,"oidc-idp-name":"sex-haver","oidc-issuer":"whoknows","oidc-scopes":["read","write"],"oidc-skip-verification":true,"password":"","path":"","port":6969,"protocol":"http","smtp-from":"queen.rip.in.piss@terfisland.org","smtp-host":"example.com","smtp-password":"hunter2","smtp-port":4269,"smtp-username":"sex-haver","software-version":"","statuses-cw-max-chars":420,"statuses-max-chars":69,"statuses-media-max-files":1,"statuses-poll-max-options":1,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/root/store","storage-s3-access-key":"minio","storage-s3-bucket":"gts","storage-s3-endpoint":"localhost:9000","storage-s3-secret-key":"miniostorage","storage-s3-use-ssl":false,"syslog-address":"127.0.0.1:6969","syslog-enabled":true,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","docker.host.local"],"username":"","web-asset-base-dir":"/root","web-template-base-dir":"/root"}' | ||||||
| 
 | 
 | ||||||
| # Set all the environment variables to  | # Set all the environment variables to  | ||||||
| # ensure that these are parsed without panic | # ensure that these are parsed without panic | ||||||
|  | @ -66,16 +66,24 @@ GTS_SMTP_HOST='example.com' \ | ||||||
| GTS_SMTP_PORT=4269 \ | GTS_SMTP_PORT=4269 \ | ||||||
| GTS_SMTP_USERNAME='sex-haver' \ | GTS_SMTP_USERNAME='sex-haver' \ | ||||||
| GTS_SMTP_PASSWORD='hunter2' \ | GTS_SMTP_PASSWORD='hunter2' \ | ||||||
| GTS_SMTP_FROM='queen@terfisland.org' \ | GTS_SMTP_FROM='queen.rip.in.piss@terfisland.org' \ | ||||||
| GTS_SYSLOG_ENABLED=true \ | GTS_SYSLOG_ENABLED=true \ | ||||||
| GTS_SYSLOG_PROTOCOL='udp' \ | GTS_SYSLOG_PROTOCOL='udp' \ | ||||||
| GTS_SYSLOG_ADDRESS='127.0.0.1:6969' \ | GTS_SYSLOG_ADDRESS='127.0.0.1:6969' \ | ||||||
| GTS_ADVANCED_COOKIES_SAMESITE='strict' \ | GTS_ADVANCED_COOKIES_SAMESITE='strict' \ | ||||||
| go run ./cmd/gotosocial/... --config-path $(dirname ${0})/test.yaml debug config) | go run ./cmd/gotosocial/... --config-path $(dirname ${0})/test.yaml debug config) | ||||||
| 
 | 
 | ||||||
| if [ "${OUTPUT}" != "${EXPECTED}" ]; then | OUTPUT_OUT=$(mktemp) | ||||||
|  | echo "$OUTPUT" > "$OUTPUT_OUT" | ||||||
|  | 
 | ||||||
|  | EXPECT_OUT=$(mktemp) | ||||||
|  | echo "$EXPECT" > "$EXPECT_OUT" | ||||||
|  | 
 | ||||||
|  | if ! DIFF=$(diff "$OUTPUT_OUT" "$EXPECT_OUT"); then | ||||||
|     echo "OUTPUT not equal EXPECTED" |     echo "OUTPUT not equal EXPECTED" | ||||||
|  |     echo "$DIFF" | ||||||
|     exit 1 |     exit 1 | ||||||
| else | else | ||||||
|     echo "OK" |     echo "OK" | ||||||
|  |     exit 0 | ||||||
| fi | fi | ||||||
|  |  | ||||||
							
								
								
									
										163
									
								
								vendor/codeberg.org/gruf/go-bytesize/bytesize.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										163
									
								
								vendor/codeberg.org/gruf/go-bytesize/bytesize.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -6,6 +6,24 @@ import ( | ||||||
| 	"unsafe" | 	"unsafe" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | const ( | ||||||
|  | 	// SI units | ||||||
|  | 	KB Size = 1e3 | ||||||
|  | 	MB Size = 1e6 | ||||||
|  | 	GB Size = 1e9 | ||||||
|  | 	TB Size = 1e12 | ||||||
|  | 	PB Size = 1e15 | ||||||
|  | 	EB Size = 1e18 | ||||||
|  | 
 | ||||||
|  | 	// IEC units | ||||||
|  | 	KiB Size = 1024 | ||||||
|  | 	MiB Size = KiB * 1024 | ||||||
|  | 	GiB Size = MiB * 1024 | ||||||
|  | 	TiB Size = GiB * 1024 | ||||||
|  | 	PiB Size = TiB * 1024 | ||||||
|  | 	EiB Size = PiB * 1024 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| var ( | var ( | ||||||
| 	// ErrInvalidUnit is returned when an invalid IEC/SI is provided. | 	// ErrInvalidUnit is returned when an invalid IEC/SI is provided. | ||||||
| 	ErrInvalidUnit = errors.New("bytesize: invalid unit") | 	ErrInvalidUnit = errors.New("bytesize: invalid unit") | ||||||
|  | @ -13,42 +31,39 @@ var ( | ||||||
| 	// ErrInvalidFormat is returned when an invalid size value is provided. | 	// ErrInvalidFormat is returned when an invalid size value is provided. | ||||||
| 	ErrInvalidFormat = errors.New("bytesize: invalid format") | 	ErrInvalidFormat = errors.New("bytesize: invalid format") | ||||||
| 
 | 
 | ||||||
| 	// bunits are the binary unit chars. |  | ||||||
| 	units = `kMGTPE` |  | ||||||
| 
 |  | ||||||
| 	// iecpows is a precomputed table of 1024^n. | 	// iecpows is a precomputed table of 1024^n. | ||||||
| 	iecpows = [...]float64{ | 	iecpows = [...]float64{ | ||||||
| 		float64(1024),                                    // KiB | 		float64(KiB), | ||||||
| 		float64(1024 * 1024),                             // MiB | 		float64(MiB), | ||||||
| 		float64(1024 * 1024 * 1024),                      // GiB | 		float64(GiB), | ||||||
| 		float64(1024 * 1024 * 1024 * 1024),               // TiB | 		float64(TiB), | ||||||
| 		float64(1024 * 1024 * 1024 * 1024 * 1024),        // PiB | 		float64(PiB), | ||||||
| 		float64(1024 * 1024 * 1024 * 1024 * 1024 * 1024), // EiB | 		float64(EiB), | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// sipows is a precomputed table of 1000^n. | 	// sipows is a precomputed table of 1000^n. | ||||||
| 	sipows = [...]float64{ | 	sipows = [...]float64{ | ||||||
| 		float64(1e3),  // KB | 		float64(KB), | ||||||
| 		float64(1e6),  // MB | 		float64(MB), | ||||||
| 		float64(1e9),  // GB | 		float64(GB), | ||||||
| 		float64(1e12), // TB | 		float64(TB), | ||||||
| 		float64(1e15), // PB | 		float64(PB), | ||||||
| 		float64(1e18), // EB | 		float64(EB), | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// bvals is a precomputed table of IEC unit values. | 	// bvals is a precomputed table of IEC unit values. | ||||||
| 	iecvals = [...]uint64{ | 	iecvals = [...]Size{ | ||||||
| 		'k': 1024, | 		'k': KiB, | ||||||
| 		'K': 1024, | 		'K': KiB, | ||||||
| 		'M': 1024 * 1024, | 		'M': MiB, | ||||||
| 		'G': 1024 * 1024 * 1024, | 		'G': GiB, | ||||||
| 		'T': 1024 * 1024 * 1024 * 1024, | 		'T': TiB, | ||||||
| 		'P': 1024 * 1024 * 1024 * 1024 * 1024, | 		'P': PiB, | ||||||
| 		'E': 1024 * 1024 * 1024 * 1024 * 1024 * 1024, | 		'E': EiB, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// sivals is a precomputed table of SI unit values. | 	// sivals is a precomputed table of SI unit values. | ||||||
| 	sivals = [...]uint64{ | 	sivals = [...]Size{ | ||||||
| 		// ASCII numbers _aren't_ valid SI unit values, | 		// ASCII numbers _aren't_ valid SI unit values, | ||||||
| 		// BUT if the space containing a possible unit | 		// BUT if the space containing a possible unit | ||||||
| 		// char is checked with this table -- it is valid | 		// char is checked with this table -- it is valid | ||||||
|  | @ -64,12 +79,13 @@ var ( | ||||||
| 		'8': 1, | 		'8': 1, | ||||||
| 		'9': 1, | 		'9': 1, | ||||||
| 
 | 
 | ||||||
| 		'k': 1e3, | 		'k': KB, | ||||||
| 		'M': 1e6, | 		'K': KB, | ||||||
| 		'G': 1e9, | 		'M': MB, | ||||||
| 		'T': 1e12, | 		'G': GB, | ||||||
| 		'P': 1e15, | 		'T': TB, | ||||||
| 		'E': 1e18, | 		'P': PB, | ||||||
|  | 		'E': EB, | ||||||
| 	} | 	} | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -91,7 +107,28 @@ func ParseSize(s string) (Size, error) { | ||||||
| 		return 0, ErrInvalidFormat | 		return 0, ErrInvalidFormat | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return Size(uint64(f) * unit), nil | 	return Size(f) * unit, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Set implements flag.Value{}. | ||||||
|  | func (sz *Size) Set(in string) error { | ||||||
|  | 	s, err := ParseSize(in) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*sz = s | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // MarshalText implements encoding.TextMarshaler{}. | ||||||
|  | func (sz *Size) MarshalText() ([]byte, error) { | ||||||
|  | 	const maxLen = 7 // max IEC string length | ||||||
|  | 	return sz.AppendFormatIEC(make([]byte, 0, maxLen)), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UnmarshalText implements encoding.TextUnmarshaler{}. | ||||||
|  | func (sz *Size) UnmarshalText(text []byte) error { | ||||||
|  | 	return sz.Set(*(*string)(unsafe.Pointer(&text))) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AppendFormat defaults to using Size.AppendFormatIEC(). | // AppendFormat defaults to using Size.AppendFormatIEC(). | ||||||
|  | @ -121,7 +158,13 @@ func (sz Size) AppendFormatIEC(dst []byte) []byte { | ||||||
| 
 | 
 | ||||||
| // appendFormat will append formatted Size to 'dst', depending on base, powers table and single unit suffix. | // appendFormat will append formatted Size to 'dst', depending on base, powers table and single unit suffix. | ||||||
| func (sz Size) appendFormat(dst []byte, base uint64, pows *[6]float64, sunit string) []byte { | func (sz Size) appendFormat(dst []byte, base uint64, pows *[6]float64, sunit string) []byte { | ||||||
| 	const min = 0.75 | 	const ( | ||||||
|  | 		// min "small" unit threshold | ||||||
|  | 		min = 0.75 | ||||||
|  | 
 | ||||||
|  | 		// binary unit chars. | ||||||
|  | 		units = `kMGTPE` | ||||||
|  | 	) | ||||||
| 
 | 
 | ||||||
| 	// Larger number: get value of | 	// Larger number: get value of | ||||||
| 	// i / unit size. We have a 'min' | 	// i / unit size. We have a 'min' | ||||||
|  | @ -143,13 +186,15 @@ func (sz Size) appendFormat(dst []byte, base uint64, pows *[6]float64, sunit str | ||||||
| 
 | 
 | ||||||
| // StringSI returns an SI unit string format of Size. | // StringSI returns an SI unit string format of Size. | ||||||
| func (sz Size) StringSI() string { | func (sz Size) StringSI() string { | ||||||
| 	b := sz.AppendFormatSI(make([]byte, 0, 6)) | 	const maxLen = 6 // max SI string length | ||||||
|  | 	b := sz.AppendFormatSI(make([]byte, 0, maxLen)) | ||||||
| 	return *(*string)(unsafe.Pointer(&b)) | 	return *(*string)(unsafe.Pointer(&b)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // StringIEC returns an IEC unit string format of Size. | // StringIEC returns an IEC unit string format of Size. | ||||||
| func (sz Size) StringIEC() string { | func (sz Size) StringIEC() string { | ||||||
| 	b := sz.AppendFormatIEC(make([]byte, 0, 7)) | 	const maxLen = 7 // max IEC string length | ||||||
|  | 	b := sz.AppendFormatIEC(make([]byte, 0, maxLen)) | ||||||
| 	return *(*string)(unsafe.Pointer(&b)) | 	return *(*string)(unsafe.Pointer(&b)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -159,9 +204,7 @@ func (sz Size) String() string { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // parseUnit will parse the byte size unit from string 's'. | // parseUnit will parse the byte size unit from string 's'. | ||||||
| func parseUnit(s string) (uint64, int, error) { | func parseUnit(s string) (Size, int, error) { | ||||||
| 	var isIEC bool |  | ||||||
| 
 |  | ||||||
| 	// Check for string | 	// Check for string | ||||||
| 	if len(s) < 1 { | 	if len(s) < 1 { | ||||||
| 		return 0, 0, ErrInvalidFormat | 		return 0, 0, ErrInvalidFormat | ||||||
|  | @ -171,8 +214,8 @@ func parseUnit(s string) (uint64, int, error) { | ||||||
| 	if l := len(s) - 1; s[l] == 'B' { | 	if l := len(s) - 1; s[l] == 'B' { | ||||||
| 		s = s[:l] | 		s = s[:l] | ||||||
| 
 | 
 | ||||||
| 		// Check str remains |  | ||||||
| 		if len(s) < 1 { | 		if len(s) < 1 { | ||||||
|  | 			// No remaining str before unit suffix | ||||||
| 			return 0, 0, ErrInvalidFormat | 			return 0, 0, ErrInvalidFormat | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -180,38 +223,41 @@ func parseUnit(s string) (uint64, int, error) { | ||||||
| 	// Strip IEC binary unit suffix | 	// Strip IEC binary unit suffix | ||||||
| 	if l := len(s) - 1; s[l] == 'i' { | 	if l := len(s) - 1; s[l] == 'i' { | ||||||
| 		s = s[:l] | 		s = s[:l] | ||||||
| 		isIEC = true |  | ||||||
| 
 | 
 | ||||||
| 		// Check str remains |  | ||||||
| 		if len(s) < 1 { | 		if len(s) < 1 { | ||||||
|  | 			// No remaining str before unit suffix | ||||||
| 			return 0, 0, ErrInvalidFormat | 			return 0, 0, ErrInvalidFormat | ||||||
| 		} | 		} | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 		// Location of unit char. | 		// Location of unit char. | ||||||
| 		l := len(s) - 1 | 		l := len(s) - 1 | ||||||
|  | 		c := int(s[l]) | ||||||
| 
 | 
 | ||||||
| 	var unit uint64 | 		// Check valid unit char was provided | ||||||
| 	switch c := int(s[l]); { | 		if len(iecvals) < c || iecvals[c] == 0 { | ||||||
| 	// Determine IEC unit in use |  | ||||||
| 	case isIEC && c < len(iecvals): |  | ||||||
| 		unit = iecvals[c] |  | ||||||
| 		if unit == 0 { |  | ||||||
| 			return 0, 0, ErrInvalidUnit | 			return 0, 0, ErrInvalidUnit | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	// Determine SI unit in use | 		// Return parsed IEC unit size | ||||||
| 	case c < len(sivals): | 		return iecvals[c], l, nil | ||||||
| 		unit = sivals[c] | 	} | ||||||
| 		switch unit { | 
 | ||||||
| 		case 0: | 	// Location of unit char. | ||||||
|  | 	l := len(s) - 1 | ||||||
|  | 	c := int(s[l]) | ||||||
|  | 
 | ||||||
|  | 	switch { | ||||||
|  | 	// Check valid unit char provided | ||||||
|  | 	case len(sivals) < c || sivals[c] == 0: | ||||||
| 		return 0, 0, ErrInvalidUnit | 		return 0, 0, ErrInvalidUnit | ||||||
| 		case 1: | 
 | ||||||
|  | 	// No unit char (only ascii number) | ||||||
|  | 	case sivals[c] == 1: | ||||||
| 		l++ | 		l++ | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	return unit, l, nil | 	// Return parsed SI unit size | ||||||
|  | 	return sivals[c], l, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ftoa appends string formatted 'f' to 'dst', assumed < ~800. | // ftoa appends string formatted 'f' to 'dst', assumed < ~800. | ||||||
|  | @ -286,7 +332,7 @@ func ftoa(dst []byte, f float64) []byte { | ||||||
| 
 | 
 | ||||||
| // itoa appends string formatted 'i' to 'dst'. | // itoa appends string formatted 'i' to 'dst'. | ||||||
| func itoa(dst []byte, i uint64) []byte { | func itoa(dst []byte, i uint64) []byte { | ||||||
| 	// Assemble int in reverse order. | 	// Assemble uint in reverse order. | ||||||
| 	var b [4]byte | 	var b [4]byte | ||||||
| 	bp := len(b) - 1 | 	bp := len(b) - 1 | ||||||
| 
 | 
 | ||||||
|  | @ -302,5 +348,10 @@ func itoa(dst []byte, i uint64) []byte { | ||||||
| 	return append(dst, b[bp:]...) | 	return append(dst, b[bp:]...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // We use the following internal strconv function usually | ||||||
|  | // used internally to parse float values, as we know that | ||||||
|  | // are value passed will always be of 64bit type, and knowing | ||||||
|  | // the returned float string length is very helpful! | ||||||
|  | // | ||||||
| //go:linkname atof64 strconv.atof64 | //go:linkname atof64 strconv.atof64 | ||||||
| func atof64(string) (float64, int, error) | func atof64(string) (float64, int, error) | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								vendor/modules.txt
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/modules.txt
									
										
									
									
										vendored
									
									
								
							|  | @ -7,7 +7,7 @@ codeberg.org/gruf/go-bitutil | ||||||
| # codeberg.org/gruf/go-bytes v1.0.2 | # codeberg.org/gruf/go-bytes v1.0.2 | ||||||
| ## explicit; go 1.14 | ## explicit; go 1.14 | ||||||
| codeberg.org/gruf/go-bytes | codeberg.org/gruf/go-bytes | ||||||
| # codeberg.org/gruf/go-bytesize v0.2.1 | # codeberg.org/gruf/go-bytesize v1.0.0 | ||||||
| ## explicit; go 1.17 | ## explicit; go 1.17 | ||||||
| codeberg.org/gruf/go-bytesize | codeberg.org/gruf/go-bytesize | ||||||
| # codeberg.org/gruf/go-byteutil v1.0.2 | # codeberg.org/gruf/go-byteutil v1.0.2 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue