選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

cmd.go 11 KiB

4年前
4年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
5年前
3年前
5年前
3年前
5年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
5年前
3年前
5年前
3年前
5年前
3年前
5年前
5年前
3年前
5年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. package cmd
  2. import (
  3. "fmt"
  4. "log"
  5. "os"
  6. "strings"
  7. "github.com/dutchcoders/transfer.sh/server"
  8. "github.com/fatih/color"
  9. "github.com/urfave/cli"
  10. "google.golang.org/api/googleapi"
  11. )
  12. var Version = "1.1.7"
  13. var helpTemplate = `NAME:
  14. {{.Name}} - {{.Usage}}
  15. DESCRIPTION:
  16. {{.Description}}
  17. USAGE:
  18. {{.Name}} {{if .Flags}}[flags] {{end}}command{{if .Flags}}{{end}} [arguments...]
  19. COMMANDS:
  20. {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
  21. {{end}}{{if .Flags}}
  22. FLAGS:
  23. {{range .Flags}}{{.}}
  24. {{end}}{{end}}
  25. VERSION:
  26. ` + Version +
  27. `{{ "\n"}}`
  28. var globalFlags = []cli.Flag{
  29. cli.StringFlag{
  30. Name: "listener",
  31. Usage: "127.0.0.1:8080",
  32. Value: "127.0.0.1:8080",
  33. EnvVar: "LISTENER",
  34. },
  35. // redirect to https?
  36. // hostnames
  37. cli.StringFlag{
  38. Name: "profile-listener",
  39. Usage: "127.0.0.1:6060",
  40. Value: "",
  41. EnvVar: "PROFILE_LISTENER",
  42. },
  43. cli.BoolFlag{
  44. Name: "force-https",
  45. Usage: "",
  46. EnvVar: "FORCE_HTTPS",
  47. },
  48. cli.StringFlag{
  49. Name: "tls-listener",
  50. Usage: "127.0.0.1:8443",
  51. Value: "",
  52. EnvVar: "TLS_LISTENER",
  53. },
  54. cli.BoolFlag{
  55. Name: "tls-listener-only",
  56. Usage: "",
  57. EnvVar: "TLS_LISTENER_ONLY",
  58. },
  59. cli.StringFlag{
  60. Name: "tls-cert-file",
  61. Value: "",
  62. EnvVar: "TLS_CERT_FILE",
  63. },
  64. cli.StringFlag{
  65. Name: "tls-private-key",
  66. Value: "",
  67. EnvVar: "TLS_PRIVATE_KEY",
  68. },
  69. cli.StringFlag{
  70. Name: "temp-path",
  71. Usage: "path to temp files",
  72. Value: os.TempDir(),
  73. EnvVar: "TEMP_PATH",
  74. },
  75. cli.StringFlag{
  76. Name: "web-path",
  77. Usage: "path to static web files",
  78. Value: "",
  79. EnvVar: "WEB_PATH",
  80. },
  81. cli.StringFlag{
  82. Name: "proxy-path",
  83. Usage: "path prefix when service is run behind a proxy",
  84. Value: "",
  85. EnvVar: "PROXY_PATH",
  86. },
  87. cli.StringFlag{
  88. Name: "proxy-port",
  89. Usage: "port of the proxy when the service is run behind a proxy",
  90. Value: "",
  91. EnvVar: "PROXY_PORT",
  92. },
  93. cli.StringFlag{
  94. Name: "ga-key",
  95. Usage: "key for google analytics (front end)",
  96. Value: "",
  97. EnvVar: "GA_KEY",
  98. },
  99. cli.StringFlag{
  100. Name: "uservoice-key",
  101. Usage: "key for user voice (front end)",
  102. Value: "",
  103. EnvVar: "USERVOICE_KEY",
  104. },
  105. cli.StringFlag{
  106. Name: "provider",
  107. Usage: "s3|gdrive|local",
  108. Value: "",
  109. EnvVar: "PROVIDER",
  110. },
  111. cli.StringFlag{
  112. Name: "s3-endpoint",
  113. Usage: "",
  114. Value: "",
  115. EnvVar: "S3_ENDPOINT",
  116. },
  117. cli.StringFlag{
  118. Name: "s3-region",
  119. Usage: "",
  120. Value: "eu-west-1",
  121. EnvVar: "S3_REGION",
  122. },
  123. cli.StringFlag{
  124. Name: "aws-access-key",
  125. Usage: "",
  126. Value: "",
  127. EnvVar: "AWS_ACCESS_KEY",
  128. },
  129. cli.StringFlag{
  130. Name: "aws-secret-key",
  131. Usage: "",
  132. Value: "",
  133. EnvVar: "AWS_SECRET_KEY",
  134. },
  135. cli.StringFlag{
  136. Name: "bucket",
  137. Usage: "",
  138. Value: "",
  139. EnvVar: "BUCKET",
  140. },
  141. cli.BoolFlag{
  142. Name: "s3-no-multipart",
  143. Usage: "Disables S3 Multipart Puts",
  144. EnvVar: "S3_NO_MULTIPART",
  145. },
  146. cli.BoolFlag{
  147. Name: "s3-path-style",
  148. Usage: "Forces path style URLs, required for Minio.",
  149. EnvVar: "S3_PATH_STYLE",
  150. },
  151. cli.StringFlag{
  152. Name: "gdrive-client-json-filepath",
  153. Usage: "",
  154. Value: "",
  155. EnvVar: "GDRIVE_CLIENT_JSON_FILEPATH",
  156. },
  157. cli.StringFlag{
  158. Name: "gdrive-local-config-path",
  159. Usage: "",
  160. Value: "",
  161. EnvVar: "GDRIVE_LOCAL_CONFIG_PATH",
  162. },
  163. cli.IntFlag{
  164. Name: "gdrive-chunk-size",
  165. Usage: "",
  166. Value: googleapi.DefaultUploadChunkSize / 1024 / 1024,
  167. EnvVar: "GDRIVE_CHUNK_SIZE",
  168. },
  169. cli.StringFlag{
  170. Name: "storj-access",
  171. Usage: "Access for the project",
  172. Value: "",
  173. EnvVar: "STORJ_ACCESS",
  174. },
  175. cli.StringFlag{
  176. Name: "storj-bucket",
  177. Usage: "Bucket to use within the project",
  178. Value: "",
  179. EnvVar: "STORJ_BUCKET",
  180. },
  181. cli.IntFlag{
  182. Name: "rate-limit",
  183. Usage: "requests per minute",
  184. Value: 0,
  185. EnvVar: "RATE_LIMIT",
  186. },
  187. cli.Int64Flag{
  188. Name: "max-upload-size",
  189. Usage: "max limit for upload, in kilobytes",
  190. Value: 0,
  191. EnvVar: "MAX_UPLOAD_SIZE",
  192. },
  193. cli.StringFlag{
  194. Name: "lets-encrypt-hosts",
  195. Usage: "host1, host2",
  196. Value: "",
  197. EnvVar: "HOSTS",
  198. },
  199. cli.StringFlag{
  200. Name: "log",
  201. Usage: "/var/log/transfersh.log",
  202. Value: "",
  203. EnvVar: "LOG",
  204. },
  205. cli.StringFlag{
  206. Name: "basedir",
  207. Usage: "path to storage",
  208. Value: "",
  209. EnvVar: "BASEDIR",
  210. },
  211. cli.StringFlag{
  212. Name: "clamav-host",
  213. Usage: "clamav-host",
  214. Value: "",
  215. EnvVar: "CLAMAV_HOST",
  216. },
  217. cli.StringFlag{
  218. Name: "virustotal-key",
  219. Usage: "virustotal-key",
  220. Value: "",
  221. EnvVar: "VIRUSTOTAL_KEY",
  222. },
  223. cli.BoolFlag{
  224. Name: "profiler",
  225. Usage: "enable profiling",
  226. EnvVar: "PROFILER",
  227. },
  228. cli.StringFlag{
  229. Name: "http-auth-user",
  230. Usage: "user for http basic auth",
  231. Value: "",
  232. EnvVar: "HTTP_AUTH_USER",
  233. },
  234. cli.StringFlag{
  235. Name: "http-auth-pass",
  236. Usage: "pass for http basic auth",
  237. Value: "",
  238. EnvVar: "HTTP_AUTH_PASS",
  239. },
  240. cli.StringFlag{
  241. Name: "ip-whitelist",
  242. Usage: "comma separated list of ips allowed to connect to the service",
  243. Value: "",
  244. EnvVar: "IP_WHITELIST",
  245. },
  246. cli.StringFlag{
  247. Name: "ip-blacklist",
  248. Usage: "comma separated list of ips not allowed to connect to the service",
  249. Value: "",
  250. EnvVar: "IP_BLACKLIST",
  251. },
  252. cli.StringFlag{
  253. Name: "cors-domains",
  254. Usage: "comma separated list of domains allowed for CORS requests",
  255. Value: "",
  256. EnvVar: "CORS_DOMAINS",
  257. },
  258. }
  259. type Cmd struct {
  260. *cli.App
  261. }
  262. func VersionAction(c *cli.Context) {
  263. fmt.Println(color.YellowString(fmt.Sprintf("transfer.sh %s: Easy file sharing from the command line", Version)))
  264. }
  265. func New() *Cmd {
  266. logger := log.New(os.Stdout, "[transfer.sh]", log.LstdFlags)
  267. app := cli.NewApp()
  268. app.Name = "transfer.sh"
  269. app.Author = ""
  270. app.Usage = "transfer.sh"
  271. app.Description = `Easy file sharing from the command line`
  272. app.Version = Version
  273. app.Flags = globalFlags
  274. app.CustomAppHelpTemplate = helpTemplate
  275. app.Commands = []cli.Command{
  276. {
  277. Name: "version",
  278. Action: VersionAction,
  279. },
  280. }
  281. app.Before = func(c *cli.Context) error {
  282. return nil
  283. }
  284. app.Action = func(c *cli.Context) {
  285. options := []server.OptionFn{}
  286. if v := c.String("listener"); v != "" {
  287. options = append(options, server.Listener(v))
  288. }
  289. if v := c.String("cors-domains"); v != "" {
  290. options = append(options, server.CorsDomains(v))
  291. }
  292. if v := c.String("tls-listener"); v == "" {
  293. } else if c.Bool("tls-listener-only") {
  294. options = append(options, server.TLSListener(v, true))
  295. } else {
  296. options = append(options, server.TLSListener(v, false))
  297. }
  298. if v := c.String("profile-listener"); v != "" {
  299. options = append(options, server.ProfileListener(v))
  300. }
  301. if v := c.String("web-path"); v != "" {
  302. options = append(options, server.WebPath(v))
  303. }
  304. if v := c.String("proxy-path"); v != "" {
  305. options = append(options, server.ProxyPath(v))
  306. }
  307. if v := c.String("proxy-port"); v != "" {
  308. options = append(options, server.ProxyPort(v))
  309. }
  310. if v := c.String("ga-key"); v != "" {
  311. options = append(options, server.GoogleAnalytics(v))
  312. }
  313. if v := c.String("uservoice-key"); v != "" {
  314. options = append(options, server.UserVoice(v))
  315. }
  316. if v := c.String("temp-path"); v != "" {
  317. options = append(options, server.TempPath(v))
  318. }
  319. if v := c.String("log"); v != "" {
  320. options = append(options, server.LogFile(logger, v))
  321. } else {
  322. options = append(options, server.Logger(logger))
  323. }
  324. if v := c.String("lets-encrypt-hosts"); v != "" {
  325. options = append(options, server.UseLetsEncrypt(strings.Split(v, ",")))
  326. }
  327. if v := c.String("virustotal-key"); v != "" {
  328. options = append(options, server.VirustotalKey(v))
  329. }
  330. if v := c.String("clamav-host"); v != "" {
  331. options = append(options, server.ClamavHost(v))
  332. }
  333. if v := c.Int64("max-upload-size"); v > 0 {
  334. options = append(options, server.MaxUploadSize(v))
  335. }
  336. if v := c.Int("rate-limit"); v > 0 {
  337. options = append(options, server.RateLimit(v))
  338. }
  339. if cert := c.String("tls-cert-file"); cert == "" {
  340. } else if pk := c.String("tls-private-key"); pk == "" {
  341. } else {
  342. options = append(options, server.TLSConfig(cert, pk))
  343. }
  344. if c.Bool("profiler") {
  345. options = append(options, server.EnableProfiler())
  346. }
  347. if c.Bool("force-https") {
  348. options = append(options, server.ForceHTTPs())
  349. }
  350. if httpAuthUser := c.String("http-auth-user"); httpAuthUser == "" {
  351. } else if httpAuthPass := c.String("http-auth-pass"); httpAuthPass == "" {
  352. } else {
  353. options = append(options, server.HttpAuthCredentials(httpAuthUser, httpAuthPass))
  354. }
  355. applyIPFilter := false
  356. ipFilterOptions := server.IPFilterOptions{}
  357. if ipWhitelist := c.String("ip-whitelist"); ipWhitelist != "" {
  358. applyIPFilter = true
  359. ipFilterOptions.AllowedIPs = strings.Split(ipWhitelist, ",")
  360. ipFilterOptions.BlockByDefault = true
  361. }
  362. if ipBlacklist := c.String("ip-blacklist"); ipBlacklist != "" {
  363. applyIPFilter = true
  364. ipFilterOptions.BlockedIPs = strings.Split(ipBlacklist, ",")
  365. }
  366. if applyIPFilter {
  367. options = append(options, server.FilterOptions(ipFilterOptions))
  368. }
  369. switch provider := c.String("provider"); provider {
  370. case "s3":
  371. if accessKey := c.String("aws-access-key"); accessKey == "" {
  372. panic("access-key not set.")
  373. } else if secretKey := c.String("aws-secret-key"); secretKey == "" {
  374. panic("secret-key not set.")
  375. } else if bucket := c.String("bucket"); bucket == "" {
  376. panic("bucket not set.")
  377. } else if storage, err := server.NewS3Storage(accessKey, secretKey, bucket, c.String("s3-region"), c.String("s3-endpoint"), logger, c.Bool("s3-no-multipart"), c.Bool("s3-path-style")); err != nil {
  378. panic(err)
  379. } else {
  380. options = append(options, server.UseStorage(storage))
  381. }
  382. case "gdrive":
  383. chunkSize := c.Int("gdrive-chunk-size")
  384. if clientJsonFilepath := c.String("gdrive-client-json-filepath"); clientJsonFilepath == "" {
  385. panic("client-json-filepath not set.")
  386. } else if localConfigPath := c.String("gdrive-local-config-path"); localConfigPath == "" {
  387. panic("local-config-path not set.")
  388. } else if basedir := c.String("basedir"); basedir == "" {
  389. panic("basedir not set.")
  390. } else if storage, err := server.NewGDriveStorage(clientJsonFilepath, localConfigPath, basedir, chunkSize, logger); err != nil {
  391. panic(err)
  392. } else {
  393. options = append(options, server.UseStorage(storage))
  394. }
  395. case "storj":
  396. if access := c.String("storj-access"); access == "" {
  397. panic("storj-access not set.")
  398. } else if bucket := c.String("storj-bucket"); bucket == "" {
  399. panic("storj-bucket not set.")
  400. } else if storage, err := server.NewStorjStorage(access, bucket, logger); err != nil {
  401. panic(err)
  402. } else {
  403. options = append(options, server.UseStorage(storage))
  404. }
  405. case "local":
  406. if v := c.String("basedir"); v == "" {
  407. panic("basedir not set.")
  408. } else if storage, err := server.NewLocalStorage(v, logger); err != nil {
  409. panic(err)
  410. } else {
  411. options = append(options, server.UseStorage(storage))
  412. }
  413. default:
  414. panic("Provider not set or invalid.")
  415. }
  416. srvr, err := server.New(
  417. options...,
  418. )
  419. if err != nil {
  420. logger.Println(color.RedString("Error starting server: %s", err.Error()))
  421. return
  422. }
  423. srvr.Run()
  424. }
  425. return &Cmd{
  426. App: app,
  427. }
  428. }