<commit_before>package server

import (
	"crypto/rsa"
	"crypto/x509"
	"database/sql"
	"encoding/pem"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"

	"pixur.org/pixur/handlers"

	_ "github.com/go-sql-driver/mysql"
)

type Config struct {
	MysqlConfig           string `json:"mysql_config"`
	HttpSpec              string `json:"spec"`
	PixPath               string `json:"pix_path"`
	SessionPrivateKeyPath string `json:"priv_key"`
	SessionPublicKeyPath  string `json:"pub_key"`
}

type Server struct {
	db         *sql.DB
	s          *http.Server
	pixPath    string
	publicKey  *rsa.PublicKey
	privateKey *rsa.PrivateKey
}

func (s *Server) setup(c *Config) error {
	// setup the database
	db, err := sql.Open("mysql", c.MysqlConfig)
	if err != nil {
		return err
	}
	if err := db.Ping(); err != nil {
		return err
	}
	s.db = db
	// TODO: make this configurable
	db.SetMaxOpenConns(20)

	// setup storage
	fi, err := os.Stat(c.PixPath)
	if os.IsNotExist(err) {
		if err := os.MkdirAll(c.PixPath, os.ModeDir|0775); err != nil {
			return err
		}
		//make it
	} else if err != nil {
		return err
	} else if !fi.IsDir() {
		return fmt.Errorf("%s is not a directory", c.PixPath)
	}
	s.pixPath = c.PixPath

	if c.SessionPrivateKeyPath != "" {
		f, err := os.Open(c.SessionPrivateKeyPath)
		if err != nil {
			return err
		}
		defer f.Close()
		data, err := ioutil.ReadAll(f)
		if err != nil {
			return err
		}
		block, _ := pem.Decode(data)
		if block == nil {
			return fmt.Errorf("No key in %s", c.SessionPrivateKeyPath)
		}
		if block.Type != "RSA PRIVATE KEY" {
			return fmt.Errorf("Wrong private key type")
		}
		key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
		if err != nil {
			return err
		}
		s.privateKey = key
	}

	if c.SessionPublicKeyPath != "" {
		f, err := os.Open(c.SessionPublicKeyPath)
		if err != nil {
			return err
		}
		defer f.Close()
		data, err := ioutil.ReadAll(f)
		if err != nil {
			return err
		}
		block, _ := pem.Decode(data)
		if block == nil {
			return fmt.Errorf("No key in %s", c.SessionPublicKeyPath)
		}
		if block.Type != "PUBLIC KEY" {
			return fmt.Errorf("Wrong public key type")
		}
		key, err := x509.ParsePKIXPublicKey(block.Bytes)
		if err != nil {
			return err
		}
		if rsaKey, ok := key.(*rsa.PublicKey); ok {
			s.publicKey = rsaKey
		} else {
			return fmt.Errorf("Wrong public key type %T", key)
		}
	}

	s.s = new(http.Server)
	s.s.Addr = c.HttpSpec
	mux := http.NewServeMux()
	s.s.Handler = mux

	handlers.AddAllHandlers(mux, &handlers.ServerConfig{
		DB:      db,
		PixPath: s.pixPath,
	})
	return nil
}

func (s *Server) StartAndWait(c *Config) error {
	if err := s.setup(c); err != nil {
		return err
	}
	return s.s.ListenAndServe()<commit_msg>Precompute rsa keys on start up<commit_after>package server

import (
	"crypto/rsa"
	"crypto/x509"
	"database/sql"
	"encoding/pem"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"

	"pixur.org/pixur/handlers"

	_ "github.com/go-sql-driver/mysql"
)

type Config struct {
	MysqlConfig           string `json:"mysql_config"`
	HttpSpec              string `json:"spec"`
	PixPath               string `json:"pix_path"`
	SessionPrivateKeyPath string `json:"priv_key"`
	SessionPublicKeyPath  string `json:"pub_key"`
}

type Server struct {
	db         *sql.DB
	s          *http.Server
	pixPath    string
	publicKey  *rsa.PublicKey
	privateKey *rsa.PrivateKey
}

func (s *Server) setup(c *Config) error {
	// setup the database
	db, err := sql.Open("mysql", c.MysqlConfig)
	if err != nil {
		return err
	}
	if err := db.Ping(); err != nil {
		return err
	}
	s.db = db
	// TODO: make this configurable
	db.SetMaxOpenConns(20)

	// setup storage
	fi, err := os.Stat(c.PixPath)
	if os.IsNotExist(err) {
		if err := os.MkdirAll(c.PixPath, os.ModeDir|0775); err != nil {
			return err
		}
		//make it
	} else if err != nil {
		return err
	} else if !fi.IsDir() {
		return fmt.Errorf("%s is not a directory", c.PixPath)
	}
	s.pixPath = c.PixPath

	if c.SessionPrivateKeyPath != "" {
		f, err := os.Open(c.SessionPrivateKeyPath)
		if err != nil {
			return err
		}
		defer f.Close()
		data, err := ioutil.ReadAll(f)
		if err != nil {
			return err
		}
		block, _ := pem.Decode(data)
		if block == nil {
			return fmt.Errorf("No key in %s", c.SessionPrivateKeyPath)
		}
		if block.Type != "RSA PRIVATE KEY" {
			return fmt.Errorf("Wrong private key type")
		}
		key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
		if err != nil {
			return err
		}
		key.Precompute()
		s.privateKey = key
	}

	if c.SessionPublicKeyPath != "" {
		f, err := os.Open(c.SessionPublicKeyPath)
		if err != nil {
			return err
		}
		defer f.Close()
		data, err := ioutil.ReadAll(f)
		if err != nil {
			return err
		}
		block, _ := pem.Decode(data)
		if block == nil {
			return fmt.Errorf("No key in %s", c.SessionPublicKeyPath)
		}
		if block.Type != "PUBLIC KEY" {
			return fmt.Errorf("Wrong public key type")
		}
		key, err := x509.ParsePKIXPublicKey(block.Bytes)
		if err != nil {
			return err
		}
		if rsaKey, ok := key.(*rsa.PublicKey); ok {
			s.publicKey = rsaKey
		} else {
			return fmt.Errorf("Wrong public key type %T", key)
		}
	}

	s.s = new(http.Server)
	s.s.Addr = c.HttpSpec
	mux := http.NewServeMux()
	s.s.Handler = mux

	handlers.AddAllHandlers(mux, &handlers.ServerConfig{
		DB:         db,
		PixPath:    s.pixPath,
		PrivateKey: s.privateKey,
		PublicKey:  s.publicKey,
	})
	return nil
}

func (s *Server) StartAndWait(c *Config) error {
	if err := s.setup(c); err != nil {
		return err
	}
	return s.s.ListenAndServe()
{'fraction_non_alphanumeric': 0.14309150565074735, 'fraction_numerical': 0.005833029529711994, 'mean_word_length': 2.888731396172927, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2173190', 'n_tokens_mistral': 2324, 'n_tokens_neox': 2130, 'n_words': 521}