<commit_before>package local

import (
    "bytes"
    "errors"
    "io"
    "io/ioutil"
    "github.com/squioc/notebook"
)

var ErrorInvalidLocalNoteFormat = errors.New("The format of the local note is invalid. Missing the NUL separator between the type of the note and its content")

// LoadNote reads a note from a io.Reader
func LoadNote(reader io.Reader) (*notebook.Note, error) {
    content, err := ioutil.ReadAll(reader)
    if err != nil {
        return nil, err
    }

    separatorPosition := bytes.IndexByte(content, 0x00)
    if separatorPosition == -1 {
        return nil, ErrorInvalidLocalNoteFormat
    }

    return notebook.NewNote(
        string(content[:separatorPosition]),
        content[separatorPosition+1:],
    ), nil
}

// SaveNote writes a note in a io.Writer
func SaveNote(note *notebook.Note, writer io.Writer) (int64, error) {
    var buffer bytes.Buffer
    buffer.WriteString(note.Category)
    buffer.WriteByte(0x0)
    buffer.Write(note.Content)
    return buffer.WriteTo(writer)
}

<commit_msg>refactor(local): refactores the local note<commit_after>package local

import (
    "bytes"
    "errors"
    "io"
    "io/ioutil"
    "github.com/squioc/notebook"
)

var ErrorInvalidLocalNoteFormat = errors.New("The format of the local note is invalid. Missing the NUL separator between the type of the note and its content")

// LoadNote reads a note from a io.Reader
func LoadNote(reader io.Reader) (*notebook.Note, error) {
    data, err := ioutil.ReadAll(reader)
    if err != nil {
        return nil, err
    }

    separatorPosition := bytes.IndexByte(data, 0x00)
    if separatorPosition == -1 {
        return nil, ErrorInvalidLocalNoteFormat
    }

    category := string(data[:separatorPosition])
    content := data[separatorPosition+1:]
    return notebook.NewNote(category, content), nil
}

// SaveNote writes a note in a io.Writer
func SaveNote(note *notebook.Note, writer io.Writer) (int64, error) {
    var buffer bytes.Buffer
    buffer.WriteString(note.Category)
    buffer.WriteByte(0x0)
    buffer.Write(note.Content)
    return buffer.WriteTo(writer)
}

<|endoftext|>


<commit_before>package main

import (
	"errors"
	"io"
	"testing"

	"github.com/flynn/lorne/types"
	"github.com/flynn/sampi/types"
	"github.com/technoweenie/grohl"
	"github.com/titanous/go-dockerclient"
)

type nullLogger struct{}

func (nullLogger) Log(grohl.Data) error { return nil }

func init() { grohl.SetLogger(nullLogger{}) }

type dockerClient struct {
	createErr error
	startErr  error
	pullErr   error
	created   *docker.Config
	pulled    string
	started   bool
	hostConf  *docker.HostConfig
}

func (c *dockerClient) CreateContainer(config *docker.Config) (*docker.Container, error) {
	if c.createErr != nil {
		err := c.createErr
		c.createErr = nil
		return nil, err
	}
	c.created = config
	return &docker.Container{ID: "asdf"}, nil
}

func (c *dockerClient) StartContainer(id string, config *docker.HostConfig) error {
	if id != "asdf" {
		return errors.New("Invalid ID")
	}
	if c.startErr != nil {
		return c.startErr
	}
	c.started = true
	c.hostConf = config
	return nil
}

func (c *dockerClient) PullImage(opts docker.PullImageOptions, w io.Writer) error {
	if c.pullErr != nil {
		return c.pullErr
	}
	c.pulled = opts.Repository
	return nil
}

func testProcess(job *sampi.Job, t *testing.T) (*State, *dockerClient) {
	client := &dockerClient{}
	return testProcessWithOpts(job, "", client, t), client
}

func testProcessWithOpts(job *sampi.Job, extAddr string, client *dockerClient, t *testing.T) *State {
	if client == nil {
		client = &dockerClient{}
	}
	state := processWithOpts(job, extAddr, client)

	if client.created != job.Config {
		t.Error("job not created")
	}
	if job.Config.Name != "flynn-a" {
		t.Error("job name not set")
	}
	if !client.started {
		t.Error("job not started")
	}
	sjob := state.GetJob("a")
	if sjob == nil || sjob.StartedAt.IsZero() || sjob.Status != lorne.StatusRunning || sjob.ContainerID != "asdf" {
		t.Error("incorrect state")
	}

	return state
}

func testProcessWithError(job *sampi.Job, client *dockerClient, err error, t *testing.T) *State {
	state := processWithOpts(job, "", client)

	sjob := state.GetJob(job.ID)
	if sjob.Status != lorne.StatusFailed {
		t.Errorf("expected status failed, got %s", sjob.Status)
	}
	if sjob.Error != err {
		t.Error("error not saved")
	}
	return state
}

func processWithOpts(job *sampi.Job, extAddr string, client *dockerClient) *State {
	jobs := make(chan *sampi.Job)
	done := make(chan struct{})
	ports := make(chan int)
	state := NewState()
	go allocatePorts(ports, 500, 501)
	go func() {
		processJobs(jobs, extAddr, client, state, ports)
		close(done)
	}()
	jobs <- job
	close(jobs)
	<-done
	return state
}

func TestProcessJob(t *testing.T) {
	testProcess(&sampi.Job{ID: "a", Config: &docker.Config{}}, t)
}

func TestProcessJobWithPort(t *testing.T) {
	job := &sampi.Job{TCPPorts: 1, ID: "a", Config: &docker.Config{}}
	_, client := testProcess(job, t)

	if len(job.Config.Env) == 0 || job.Config.Env[len(job.Config.Env)-1] != "PORT=500" {
		t.Error("port env not set")
	}
	if _, ok := job.Config.ExposedPorts["500/tcp"]; !ok {
		t.Error("exposed port not set")
	}
	if b := client.hostConf.PortBindings["500/tcp"]; len(b) == 0 || b[0].HostPort != "500" {
		t.Error("port binding not set")
	}
}

func TestProcessWithExtAddr(t *testing.T) {
	job := &sampi.Job{ID: "a", Config: &docker.Config{}}
	testProcessWithOpts(job, "10.10.10.1", nil, t)

	if !sliceHasString(job.Config.Env, "EXTERNAL_IP=10.10.10.1") {
		t.Error("EXTERNAL_IP not set")
	}
	if !sliceHasString(job.Config.Env, "DISCOVERD=10.10.10.1:1111") {
		t.Error("DISCOVERD not set")
	}
}

func sliceHasString(slice []string, str string) bool {
	for _, s := range slice {
		if s == str {
			return true
		}
	}
	return false
}

func TestProcessWithPull(t *testing.T) {
	job := &sampi.Job{ID: "a", Config: &docker.Config{Image: "test/foo"}}
	client := &dockerClient{createErr: docker.ErrNoSuchImage}
	testProcessWithOpts(job, "", client, t)

	if client.pulled != "test/foo" {
		t.Error("image not pulled")
	}
}

func TestProcessWithCreateFailure(t *testing.T) {
	job := &sampi.Job{ID: "a", Config: &docker.Config{}}
	err := errors.New("undefined failure")
	client := &dockerClient{createErr: err}
	testProcessWithError(job, client, err, t)
}

func TestProcessWithPullFailure(t *testing.T) {
	job := &sampi.Job{ID: "a", Config: &docker.Config{}}
	err := errors.New("undefined failure")
	client := &dockerClient{createErr: docker.ErrNoSuchImage, pullErr: err}
	testProcessWithError(job, client, err, t)
}

func TestProcessWithStartFailure(t *testing.T) {
	job := &sampi.Job{ID: "a", Config: &docker.Config{}}
	err := errors.New("undefined failure")
	client := &dockerClient{startErr: err}
	testProcessWithError(job, client, err, t)
}

type schedulerSyncClient struct {
	removeErr error
	removed   []string
}

func (s *schedulerSyncClient) RemoveJobs(jobs []string) error {
	if s.removeErr != nil {
		return s.removeErr
	}
	s.removed = append(s.removed, jobs...)
	return nil
}

func TestSyncScheduler(t *testing.T) {
	events := make(chan lorne.Event)
	client := &schedulerSyncClient{}
	done := make(chan struct{})
	go func() {
		syncScheduler(client, events)
		close(done)
	}()

	events <- lorne.Event{Event: "stop", JobID: "a"}
	close(events)
	<-done

	if len(client.removed) != 1 && client.removed[0] != "a" {
		t.Error("job not removed")
	}
}
<commit_msg>host: Add docker event stream test<commit_after>package main

import (
	"errors"
	"io"
	"testing"

	"github.com/flynn/lorne/types"
	"github.com/flynn/sampi/types"
	"github.com/technoweenie/grohl"
	"github.com/titanous/go-dockerclient"
)

type nullLogger struct{}

func (nullLogger) Log(grohl.Data) error { return nil }

func init() { grohl.SetLogger(nullLogger{}) }

type dockerClient struct {
	createErr error
	startErr  error
	pullErr   error
	created   *docker.Config
	pulled    string
	started   bool
	hostConf  *docker.HostConfig
}

func (c *dockerClient) CreateContainer(config *docker.Config) (*docker.Container, error) {
	if c.createErr != nil {
		err := c.createErr
		c.createErr = nil
		return nil, err
	}
	c.created = config
	return &docker.Container{ID: "asdf"}, nil
}

func (c *dockerClient) StartContainer(id string, config *docker.HostConfig) error {
	if id != "asdf" {
		return errors.New("Invalid ID")
	}
	if c.startErr != nil {
		return c.startErr
	}
	c.started = true
	c.hostConf = config
	return nil
}

func (c *dockerClient) PullImage(opts docker.PullImageOptions, w io.Writer) error {
	if c.pullErr != nil {
		return c.pullErr
	}
	c.pulled = opts.Repository
	return nil
}

func testProcess(job *sampi.Job, t *testing.T) (*State, *dockerClient) {
	client := &dockerClient{}
	return testProcessWithOpts(job, "", client, t), client
}

func testProcessWithOpts(job *sampi.Job, extAddr string, client *dockerClient, t *testing.T) *State {
	if client == nil {
		client = &dockerClient{}
	}
	state := processWithOpts(job, extAddr, client)

	if client.created != job.Config {
		t.Error("job not created")
	}
	if job.Config.Name != "flynn-a" {
		t.Error("job name not set")
	}
	if !client.started {
		t.Error("job not started")
	}
	sjob := state.GetJob("a")
	if sjob == nil || sjob.StartedAt.IsZero() || sjob.Status != lorne.StatusRunning || sjob.ContainerID != "asdf" {
		t.Error("incorrect state")
	}

	return state
}

func testProcessWithError(job *sampi.Job, client *dockerClient, err error, t *testing.T) *State {
	state := processWithOpts(job, "", client)

	sjob := state.GetJob(job.ID)
	if sjob.Status != lorne.StatusFailed {
		t.Errorf("expected status failed, got %s", sjob.Status)
	}
	if sjob.Error != err {
		t.Error("error not saved")
	}
	return state
}

func processWithOpts(job *sampi.Job, extAddr string, client *dockerClient) *State {
	jobs := make(chan *sampi.Job)
	done := make(chan struct{})
	ports := make(chan int)
	state := NewState()
	go allocatePorts(ports, 500, 501)
	go func() {
		processJobs(jobs, extAddr, client, state, ports)
		close(done)
	}()
	jobs <- job
	close(jobs)
	<-done
	return state
}

func TestProcessJob(t *testing.T) {
	testProcess(&sampi.Job{ID: "a", Config: &docker.Config{}}, t)
}

func TestProcessJobWithPort(t *testing.T) {
	job := &sampi.Job{TCPPorts: 1, ID: "a", Config: &docker.Config{}}
	_, client := testProcess(job, t)

	if len(job.Config.Env) == 0 || job.Config.Env[len(job.Config.Env)-1] != "PORT=500" {
		t.Error("port env not set")
	}
	if _, ok := job.Config.ExposedPorts["500/tcp"]; !ok {
		t.Error("exposed port not set")
	}
	if b := client.hostConf.PortBindings["500/tcp"]; len(b) == 0 || b[0].HostPort != "500" {
		t.Error("port binding not set")
	}
}

func TestProcessWithExtAddr(t *testing.T) {
	job := &sampi.Job{ID: "a", Config: &docker.Config{}}
	testProcessWithOpts(job, "10.10.10.1", nil, t)

	if !sliceHasString(job.Config.Env, "EXTERNAL_IP=10.10.10.1") {
		t.Error("EXTERNAL_IP not set")
	}
	if !sliceHasString(job.Config.Env, "DISCOVERD=10.10.10.1:1111") {
		t.Error("DISCOVERD not set")
	}
}

func sliceHasString(slice []string, str string) bool {
	for _, s := range slice {
		if s == str {
			return true
		}
	}
	return false
}

func TestProcessWithPull(t *testing.T) {
	job := &sampi.Job{ID: "a", Config: &docker.Config{Image: "test/foo"}}
	client := &dockerClient{createErr: docker.ErrNoSuchImage}
	testProcessWithOpts(job, "", client, t)

	if client.pulled != "test/foo" {
		t.Error("image not pulled")
	}
}

func TestProcessWithCreateFailure(t *testing.T) {
	job := &sampi.Job{ID: "a", Config: &docker.Config{}}
	err := errors.New("undefined failure")
	client := &dockerClient{createErr: err}
	testProcessWithError(job, client, err, t)
}

func TestProcessWithPullFailure(t *testing.T) {
	job := &sampi.Job{ID: "a", Config: &docker.Config{}}
	err := errors.New("undefined failure")
	client := &dockerClient{createErr: docker.ErrNoSuchImage, pullErr: err}
	testProcessWithError(job, client, err, t)
}

func TestProcessWithStartFailure(t *testing.T) {
	job := &sampi.Job{ID: "a", Config: &docker.Config{}}
	err := errors.New("undefined failure")
	client := &dockerClient{startErr: err}
	testProcessWithError(job, client, err, t)
}

type schedulerSyncClient struct {
	removeErr error
	removed   []string
}

func (s *schedulerSyncClient) RemoveJobs(jobs []string) error {
	if s.removeErr != nil {
		return s.removeErr
	}
	s.removed = append(s.removed, jobs...)
	return nil
}

func TestSyncScheduler(t *testing.T) {
	events := make(chan lorne.Event)
	client := &schedulerSyncClient{}
	done := make(chan struct{})
	go func() {
		syncScheduler(client, events)
		close(done)
	}()

	events <- lorne.Event{Event: "stop", JobID: "a"}
	close(events)
	<-done

	if len(client.removed) != 1 && client.removed[0] != "a" {
		t.Error("job not removed")
	}
}

type streamClient struct {
	events chan *docker.Event
}

func (s *streamClient) Events() (*docker.EventStream, error) {
	return &docker.EventStream{Events: s.events}, nil
}

func (s *streamClient) InspectContainer(id string) (*docker.Container, error) {
	if id != "1" {
		return nil, errors.New("incorrect id")
	}
	return &docker.Container{State: docker.State{ExitCode: 1}}, nil
}

func TestStreamEvents(t *testing.T) {
	events := make(chan *docker.Event)
	state := NewState()
	state.AddJob(&sampi.Job{ID: "a"})
	state.SetContainerID("a", "1")
	state.SetStatusRunning("a")

	done := make(chan struct{})
	go func() {
		streamEvents(&streamClient{events}, state)
		close(done)
	}()

	events <- &docker.Event{Status: "die", ID: "1"}
	close(events)
	<-done

	job := state.GetJob("a")
	if job.Status != lorne.StatusCrashed {
		t.Error("incorrect status")
	}
	if job.ExitCode != 1 {
		t.Error("incorrect exit code")
	}
}
<|endoftext|>


<commit_before>package google

import (
	"errors"
	"fmt"
	"log"
	"time"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"

	"google.golang.org/api/googleapi"
	"google.golang.org/api/storage/v1"
)

func resourceStorageBucket() *schema.Resource {
	return &schema.Resource{
		Create: resourceStorageBucketCreate,
		Read:   resourceStorageBucketRead,
		Update: resourceStorageBucketUpdate,
		Delete: resourceStorageBucketDelete,

		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"force_destroy": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},

			"location": &schema.Schema{
				Type:     schema.TypeString,
				Default:  "US",
				Optional: true,
				ForceNew: true,
			},

			"predefined_acl": &schema.Schema{
				Type:       schema.TypeString,
				Deprecated: "Please use resource \"storage_bucket_acl.predefined_acl\" instead.",
				Optional:   true,
				ForceNew:   true,
			},

			"project": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},

			"self_link": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},

			"storage_class": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Default:  "STANDARD",
				ForceNew: true,
			},

			"website": &schema.Schema{
				Type:     schema.TypeList,
				Optional: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"main_page_suffix": &schema.Schema{
							Type:     schema.TypeString,
							Optional: true,
						},
						"not_found_page": &schema.Schema{
							Type:     schema.TypeString,
							Optional: true,
						},
					},
				},
			},
		},
	}
}

func resourceStorageBucketCreate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	project, err := getProject(d, config)
	if err != nil {
		return err
	}

	// Get the bucket and acl
	bucket := d.Get("name").(string)
	location := d.Get("location").(string)

	// Create a bucket, setting the acl, location and name.
	sb := &storage.Bucket{Name: bucket, Location: location}

	if v, ok := d.GetOk("storage_class"); ok {
		sb.StorageClass = v.(string)
	}

	if v, ok := d.GetOk("website"); ok {
		websites := v.([]interface{})

		if len(websites) > 1 {
			return fmt.Errorf("At most one website block is allowed")
		}

		sb.Website = &storage.BucketWebsite{}

		website := websites[0].(map[string]interface{})

		if v, ok := website["not_found_page"]; ok {
			sb.Website.NotFoundPage = v.(string)
		}

		if v, ok := website["main_page_suffix"]; ok {
			sb.Website.MainPageSuffix = v.(string)
		}
	}

	var res *storage.Bucket

	err = resource.Retry(1*time.Minute, func() *resource.RetryError {
		call := config.clientStorage.Buckets.Insert(project, sb)
		if v, ok := d.GetOk("predefined_acl"); ok {
			call = call.PredefinedAcl(v.(string))
		}

		res, err = call.Do()
		if err == nil {
			return nil
		}
		if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 429 {
			return resource.RetryableError(gerr)
		}
		return resource.NonRetryableError(err)
	})

	if err != nil {
		fmt.Printf("Error creating bucket %s: %v", bucket, err)
		return err
	}

	log.Printf("[DEBUG] Created bucket %v at location %v\n\n", res.Name, res.SelfLink)

	// Assign the bucket ID as the resource ID
	d.Set("self_link", res.SelfLink)
	d.SetId(res.Id)

	return nil
}

func resourceStorageBucketUpdate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	sb := &storage.Bucket{}

	if d.HasChange("website") {
		if v, ok := d.GetOk("website"); ok {
			websites := v.([]interface{})

			if len(websites) > 1 {
				return fmt.Errorf("At most one website block is allowed")
			}

			// Setting fields to "" to be explicit that the PATCH call will
			// delete this field.
			if len(websites) == 0 {
				sb.Website.NotFoundPage = ""
				sb.Website.MainPageSuffix = ""
			} else {
				website := websites[0].(map[string]interface{})
				sb.Website = &storage.BucketWebsite{}
				if v, ok := website["not_found_page"]; ok {
					sb.Website.NotFoundPage = v.(string)
				} else {
					sb.Website.NotFoundPage = ""
				}

				if v, ok := website["main_page_suffix"]; ok {
					sb.Website.MainPageSuffix = v.(string)
				} else {
					sb.Website.MainPageSuffix = ""
				}
			}
		}
	}

	res, err := config.clientStorage.Buckets.Patch(d.Get("name").(string), sb).Do()

	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Patched bucket %v at location %v\n\n", res.Name, res.SelfLink)

	// Assign the bucket ID as the resource ID
	d.Set("self_link", res.SelfLink)
	d.SetId(res.Id)

	return nil
}

func resourceStorageBucketRead(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	// Get the bucket and acl
	bucket := d.Get("name").(string)
	res, err := config.clientStorage.Buckets.Get(bucket).Do()

	if err != nil {
		return handleNotFoundError(err, d, fmt.Sprintf("Storage Bucket %q", d.Get("name").(string)))
	}

	log.Printf("[DEBUG] Read bucket %v at location %v\n\n", res.Name, res.SelfLink)

	// Update the bucket ID according to the resource ID
	d.Set("self_link", res.SelfLink)
	d.SetId(res.Id)

	return nil
}

func resourceStorageBucketDelete(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	// Get the bucket
	bucket := d.Get("name").(string)

	for {
		res, err := config.clientStorage.Objects.List(bucket).Do()
		if err != nil {
			fmt.Printf("Error Objects.List failed: %v", err)
			return err
		}

		if len(res.Items) != 0 {
			if d.Get("force_destroy").(bool) {
				// purge the bucket...
				log.Printf("[DEBUG] GCS Bucket attempting to forceDestroy\n\n")

				for _, object := range res.Items {
					log.Printf("[DEBUG] Found %s", object.Name)
					if err := config.clientStorage.Objects.Delete(bucket, object.Name).Do(); err != nil {
						log.Fatalf("Error trying to delete object: %s %s\n\n", object.Name, err)
					} else {
						log.Printf("Object deleted: %s \n\n", object.Name)
					}
				}

			} else {
				delete_err := errors.New("Error trying to delete a bucket containing objects without `force_destroy` set to true")
				log.Printf("Error! %s : %s\n\n", bucket, delete_err)
				return delete_err
			}
		} else {
			break // 0 items, bucket empty
		}
	}

	// remove empty bucket
	err := resource.Retry(1*time.Minute, func() *resource.RetryError {
		err := config.clientStorage.Buckets.Delete(bucket).Do()
		if err == nil {
			return nil
		}
		if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 429 {
			return resource.RetryableError(gerr)
		}
		return resource.NonRetryableError(err)
	})
	if err != nil {
		fmt.Printf("Error deleting bucket %s: %v\n\n", bucket, err)
		return err
	}
	log.Printf("[DEBUG] Deleted bucket %v\n\n", bucket)

	return nil
}
<commit_msg>Add a `url` attribute to `google_storage_bucket` (#14393)<commit_after>package google

import (
	"errors"
	"fmt"
	"log"
	"time"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"

	"google.golang.org/api/googleapi"
	"google.golang.org/api/storage/v1"
)

func resourceStorageBucket() *schema.Resource {
	return &schema.Resource{
		Create: resourceStorageBucketCreate,
		Read:   resourceStorageBucketRead,
		Update: resourceStorageBucketUpdate,
		Delete: resourceStorageBucketDelete,

		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"force_destroy": &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				Default:  false,
			},

			"location": &schema.Schema{
				Type:     schema.TypeString,
				Default:  "US",
				Optional: true,
				ForceNew: true,
			},

			"predefined_acl": &schema.Schema{
				Type:       schema.TypeString,
				Deprecated: "Please use resource \"storage_bucket_acl.predefined_acl\" instead.",
				Optional:   true,
				ForceNew:   true,
			},

			"project": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},

			"self_link": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},

			"url": &schema.Schema{
				Type:     schema.TypeString,
				Computed: true,
			},

			"storage_class": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Default:  "STANDARD",
				ForceNew: true,
			},

			"website": &schema.Schema{
				Type:     schema.TypeList,
				Optional: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"main_page_suffix": &schema.Schema{
							Type:     schema.TypeString,
							Optional: true,
						},
						"not_found_page": &schema.Schema{
							Type:     schema.TypeString,
							Optional: true,
						},
					},
				},
			},
		},
	}
}

func resourceStorageBucketCreate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	project, err := getProject(d, config)
	if err != nil {
		return err
	}

	// Get the bucket and acl
	bucket := d.Get("name").(string)
	location := d.Get("location").(string)

	// Create a bucket, setting the acl, location and name.
	sb := &storage.Bucket{Name: bucket, Location: location}

	if v, ok := d.GetOk("storage_class"); ok {
		sb.StorageClass = v.(string)
	}

	if v, ok := d.GetOk("website"); ok {
		websites := v.([]interface{})

		if len(websites) > 1 {
			return fmt.Errorf("At most one website block is allowed")
		}

		sb.Website = &storage.BucketWebsite{}

		website := websites[0].(map[string]interface{})

		if v, ok := website["not_found_page"]; ok {
			sb.Website.NotFoundPage = v.(string)
		}

		if v, ok := website["main_page_suffix"]; ok {
			sb.Website.MainPageSuffix = v.(string)
		}
	}

	var res *storage.Bucket

	err = resource.Retry(1*time.Minute, func() *resource.RetryError {
		call := config.clientStorage.Buckets.Insert(project, sb)
		if v, ok := d.GetOk("predefined_acl"); ok {
			call = call.PredefinedAcl(v.(string))
		}

		res, err = call.Do()
		if err == nil {
			return nil
		}
		if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 429 {
			return resource.RetryableError(gerr)
		}
		return resource.NonRetryableError(err)
	})

	if err != nil {
		fmt.Printf("Error creating bucket %s: %v", bucket, err)
		return err
	}

	log.Printf("[DEBUG] Created bucket %v at location %v\n\n", res.Name, res.SelfLink)

	// Assign the bucket ID as the resource ID
	d.Set("self_link", res.SelfLink)
	d.Set("url", fmt.Sprintf("gs://%s", bucket))
	d.SetId(res.Id)

	return nil
}

func resourceStorageBucketUpdate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	sb := &storage.Bucket{}

	if d.HasChange("website") {
		if v, ok := d.GetOk("website"); ok {
			websites := v.([]interface{})

			if len(websites) > 1 {
				return fmt.Errorf("At most one website block is allowed")
			}

			// Setting fields to "" to be explicit that the PATCH call will
			// delete this field.
			if len(websites) == 0 {
				sb.Website.NotFoundPage = ""
				sb.Website.MainPageSuffix = ""
			} else {
				website := websites[0].(map[string]interface{})
				sb.Website = &storage.BucketWebsite{}
				if v, ok := website["not_found_page"]; ok {
					sb.Website.NotFoundPage = v.(string)
				} else {
					sb.Website.NotFoundPage = ""
				}

				if v, ok := website["main_page_suffix"]; ok {
					sb.Website.MainPageSuffix = v.(string)
				} else {
					sb.Website.MainPageSuffix = ""
				}
			}
		}
	}

	res, err := config.clientStorage.Buckets.Patch(d.Get("name").(string), sb).Do()

	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Patched bucket %v at location %v\n\n", res.Name, res.SelfLink)

	// Assign the bucket ID as the resource ID
	d.Set("self_link", res.SelfLink)
	d.SetId(res.Id)

	return nil
}

func resourceStorageBucketRead(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	// Get the bucket and acl
	bucket := d.Get("name").(string)
	res, err := config.clientStorage.Buckets.Get(bucket).Do()

	if err != nil {
		return handleNotFoundError(err, d, fmt.Sprintf("Storage Bucket %q", d.Get("name").(string)))
	}

	log.Printf("[DEBUG] Read bucket %v at location %v\n\n", res.Name, res.SelfLink)

	// Update the bucket ID according to the resource ID
	d.Set("self_link", res.SelfLink)
	d.SetId(res.Id)

	return nil
}

func resourceStorageBucketDelete(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	// Get the bucket
	bucket := d.Get("name").(string)

	for {
		res, err := config.clientStorage.Objects.List(bucket).Do()
		if err != nil {
			fmt.Printf("Error Objects.List failed: %v", err)
			return err
		}

		if len(res.Items) != 0 {
			if d.Get("force_destroy").(bool) {
				// purge the bucket...
				log.Printf("[DEBUG] GCS Bucket attempting to forceDestroy\n\n")

				for _, object := range res.Items {
					log.Printf("[DEBUG] Found %s", object.Name)
					if err := config.clientStorage.Objects.Delete(bucket, object.Name).Do(); err != nil {
						log.Fatalf("Error trying to delete object: %s %s\n\n", object.Name, err)
					} else {
						log.Printf("Object deleted: %s \n\n", object.Name)
					}
				}

			} else {
				delete_err := errors.New("Error trying to delete a bucket containing objects without `force_destroy` set to true")
				log.Printf("Error! %s : %s\n\n", bucket, delete_err)
				return delete_err
			}
		} else {
			break // 0 items, bucket empty
		}
	}

	// remove empty bucket
	err := resource.Retry(1*time.Minute, func() *resource.RetryError {
		err := config.clientStorage.Buckets.Delete(bucket).Do()
		if err == nil {
			return nil
		}
		if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 429 {
			return resource.RetryableError(gerr)
		}
		return resource.NonRetryableError(err)
	})
	if err != nil {
		fmt.Printf("Error deleting bucket %s: %v\n\n", bucket, err)
		return err
	}
	log.Printf("[DEBUG] Deleted bucket %v\n\n", bucket)

	return nil
}
<|endoftext|>


<commit_before><commit_msg>can now download a random file<commit_after><|endoftext|>


<commit_before>package command

import (
	"encoding/json"
	"testing"

	"gotest.tools/v3/assert"
)

func TestDockerContextMetadataKeepAdditionalFields(t *testing.T) {
	c := DockerContext{
		Description: "test",
		AdditionalFields: map[string]interface{}{
			"foo": "bar",
		},
	}
	jsonBytes, err := json.Marshal(c)
	assert.NilError(t, err)
	assert.Equal(t, `{"Description":"test","foo":"bar"}`, string(jsonBytes))

	var c2 DockerContext
	assert.NilError(t, json.Unmarshal(jsonBytes, &c2))
	assert.Equal(t, c2.AdditionalFields["foo"], "bar")
	assert.Equal(t, c2.Description, "test")
}
<commit_msg>cli/command: use more descriptive const in test<commit_after>package command

import (
	"encoding/json"
	"testing"

	"gotest.tools/v3/assert"
)

func TestDockerContextMetadataKeepAdditionalFields(t *testing.T) {
	c := DockerContext{
		Description: "test",
		AdditionalFields: map[string]interface{}{
			"foo": "bar",
		},
	}
	jsonBytes, err := json.Marshal(c)
	assert.NilError(t, err)
	const expected = `{"Description":"test","foo":"bar"}`
	assert.Equal(t, string(jsonBytes), expected)

	var c2 DockerContext
	assert.NilError(t, json.Unmarshal(jsonBytes, &c2))
	assert.Equal(t, c2.AdditionalFields["foo"], "bar")
	assert.Equal(t, c2.Description, "test")
}
<|endoftext|>


<commit_before>package flags_test

import (
	"bytes"
	"strings"
	"testing"

	tmflags "github.com/tendermint/tmlibs/cli/flags"
	"github.com/tendermint/tmlibs/log"
)

const (
	defaultLogLevelValue = "info"
)

func TestParseLogLevel(t *testing.T) {
	var buf bytes.Buffer
	jsonLogger := log.NewTMJSONLogger(&buf)

	correctLogLevels := []struct {
		lvl              string
		expectedLogLines []string
	}{
		{"mempool:error", []string{
			``, // if no default is given, assume info
			``,
			`{"_msg":"Mesmero","level":"error","module":"mempool"}`,
			`{"_msg":"Mind","level":"info","module":"state"}`}}, // if no default is given, assume info
		{"mempool:error,*:debug", []string{
			`{"_msg":"Kingpin","level":"debug","module":"wire"}`,
			``,
			`{"_msg":"Mesmero","level":"error","module":"mempool"}`,
			`{"_msg":"Mind","level":"info","module":"state"}`}},

		{"*:debug,wire:none", []string{
			``,
			`{"_msg":"Kitty Pryde","level":"info","module":"mempool"}`,
			`{"_msg":"Mesmero","level":"error","module":"mempool"}`,
			`{"_msg":"Mind","level":"info","module":"state"}`}},
	}

	for _, c := range correctLogLevels {
		logger, err := tmflags.ParseLogLevel(c.lvl, jsonLogger, defaultLogLevelValue)
		if err != nil {
			t.Fatal(err)
		}

		logger = logger

		buf.Reset()

		logger.With("module", "wire").Debug("Kingpin")
		if have := strings.TrimSpace(buf.String()); c.expectedLogLines[0] != have {
			t.Errorf("\nwant '%s'\nhave '%s'\nlevel '%s'", c.expectedLogLines[0], have, c.lvl)
		}

		buf.Reset()

		logger.With("module", "mempool").Info("Kitty Pryde")
		if have := strings.TrimSpace(buf.String()); c.expectedLogLines[1] != have {
			t.Errorf("\nwant '%s'\nhave '%s'\nlevel '%s'", c.expectedLogLines[1], have, c.lvl)
		}

		buf.Reset()

		logger.With("module", "mempool").Error("Mesmero")
		if have := strings.TrimSpace(buf.String()); c.expectedLogLines[2] != have {
			t.Errorf("\nwant '%s'\nhave '%s'\nlevel '%s'", c.expectedLogLines[2], have, c.lvl)
		}

		buf.Reset()

		logger.With("module", "state").Info("Mind")
		if have := strings.TrimSpace(buf.String()); c.expectedLogLines[3] != have {
			t.Errorf("\nwant '%s'\nhave '%s'\nlevel '%s'", c.expectedLogLines[3], have, c.lvl)
		}

	}

	incorrectLogLevel := []string{"some", "mempool:some", "*:some,mempool:error"}
	for _, lvl := range incorrectLogLevel {
		if _, err := tmflags.ParseLogLevel(lvl, jsonLogger, defaultLogLevelValue); err == nil {
			t.Fatalf("Expected %s to produce error", lvl)
		}
	}
}
<commit_msg>[cli] add a test case to TestParseLogLevel where there is no module key<commit_after>package flags_test

import (
	"bytes"
	"strings"
	"testing"

	tmflags "github.com/tendermint/tmlibs/cli/flags"
	"github.com/tendermint/tmlibs/log"
)

const (
	defaultLogLevelValue = "info"
)

func TestParseLogLevel(t *testing.T) {
	var buf bytes.Buffer
	jsonLogger := log.NewTMJSONLogger(&buf)

	correctLogLevels := []struct {
		lvl              string
		expectedLogLines []string
	}{
		{"mempool:error", []string{
			``, // if no default is given, assume info
			``,
			`{"_msg":"Mesmero","level":"error","module":"mempool"}`,
			`{"_msg":"Mind","level":"info","module":"state"}`, // if no default is given, assume info
			``}},

		{"mempool:error,*:debug", []string{
			`{"_msg":"Kingpin","level":"debug","module":"wire"}`,
			``,
			`{"_msg":"Mesmero","level":"error","module":"mempool"}`,
			`{"_msg":"Mind","level":"info","module":"state"}`,
			`{"_msg":"Gideon","level":"debug"}`}},

		{"*:debug,wire:none", []string{
			``,
			`{"_msg":"Kitty Pryde","level":"info","module":"mempool"}`,
			`{"_msg":"Mesmero","level":"error","module":"mempool"}`,
			`{"_msg":"Mind","level":"info","module":"state"}`,
			`{"_msg":"Gideon","level":"debug"}`}},
	}

	for _, c := range correctLogLevels {
		logger, err := tmflags.ParseLogLevel(c.lvl, jsonLogger, defaultLogLevelValue)
		if err != nil {
			t.Fatal(err)
		}

		logger = logger

		buf.Reset()

		logger.With("module", "wire").Debug("Kingpin")
		if have := strings.TrimSpace(buf.String()); c.expectedLogLines[0] != have {
			t.Errorf("\nwant '%s'\nhave '%s'\nlevel '%s'", c.expectedLogLines[0], have, c.lvl)
		}

		buf.Reset()

		logger.With("module", "mempool").Info("Kitty Pryde")
		if have := strings.TrimSpace(buf.String()); c.expectedLogLines[1] != have {
			t.Errorf("\nwant '%s'\nhave '%s'\nlevel '%s'", c.expectedLogLines[1], have, c.lvl)
		}

		buf.Reset()

		logger.With("module", "mempool").Error("Mesmero")
		if have := strings.TrimSpace(buf.String()); c.expectedLogLines[2] != have {
			t.Errorf("\nwant '%s'\nhave '%s'\nlevel '%s'", c.expectedLogLines[2], have, c.lvl)
		}

		buf.Reset()

		logger.With("module", "state").Info("Mind")
		if have := strings.TrimSpace(buf.String()); c.expectedLogLines[3] != have {
			t.Errorf("\nwant '%s'\nhave '%s'\nlevel '%s'", c.expectedLogLines[3], have, c.lvl)
		}

		buf.Reset()

		logger.Debug("Gideon")
		if have := strings.TrimSpace(buf.String()); c.expectedLogLines[4] != have {
			t.Errorf("\nwant '%s'\nhave '%s'\nlevel '%s'", c.expectedLogLines[4], have, c.lvl)
		}
	}

	incorrectLogLevel := []string{"some", "mempool:some", "*:some,mempool:error"}
	for _, lvl := range incorrectLogLevel {
		if _, err := tmflags.ParseLogLevel(lvl, jsonLogger, defaultLogLevelValue); err == nil {
			t.Fatalf("Expected %s to produce error", lvl)
		}
	}
}
<|endoftext|>


<commit_before>package config

const (
	Production          = true
	InstaJoinProduction = "#chaos-hd #i3 #noname-ev"
	InstaJoinDebug      = "#test"
	NickServPass        = ""
	IrcServer           = "irc.twice-irc.de"
	BotNick             = "frank"
	Master              = "xeen"
)
<commit_msg>set production to false<commit_after>package config

const (
	Production          = false
	InstaJoinProduction = "#chaos-hd #i3 #noname-ev"
	InstaJoinDebug      = "#test"
	NickServPass        = ""
	IrcServer           = "irc.twice-irc.de"
	BotNick             = "frank"
	Master              = "xeen"
)
<|endoftext|>


<commit_before><commit_msg>fix uncompleted value in ui (#238)<commit_after><|endoftext|>


<commit_before>// +build linux

package fs

import (
	"os"
	"time"

	"github.com/hanwen/go-fuse/fuse"
	"github.com/hanwen/go-fuse/fuse/nodefs"
)

type Node interface {
	nodefs.Node
}

func NewNode() Node {
	return nodefs.NewDefaultNode()
}

func (f *FileInfo) FillAttr(out *fuse.Attr) {
	perm := uint32(f.Mode & os.ModePerm)
	if f.IsDir() {
		out.Mode = fuse.S_IFDIR | perm
	} else {
		out.Mode = fuse.S_IFREG | perm
	}
	out.Size = uint64(f.Size)
	out.Atime = uint64(f.LastMod.Unix())
	out.Mtime = uint64(f.LastMod.Unix())
}

func (f *FileInfo) FillDirEntry(out *fuse.DirEntry) {
	out.Name = f.Name
	out.Mode = uint32(f.Mode & os.ModePerm)
	if f.IsDir() {
		out.Mode |= fuse.S_IFDIR
	}
}

func (root *Root) MountAndServe(mtpt string, debug bool) error {
	opts := nodefs.Options{
		AttrTimeout:  time.Second,
		EntryTimeout: time.Second,
		Debug:        debug,
	}
	s, _, err := nodefs.MountRoot(mtpt, root, &opts)
	if err != nil {
		return err
	}
	s.Serve()
	return nil
}

func (root *Root) Lookup(out *fuse.Attr, name string, ctx *fuse.Context) (*nodefs.Inode, fuse.Status) {
	return lookupName(root, name, out, ctx)
}

func (root *Root) GetAttr(out *fuse.Attr, file nodefs.File, ctx *fuse.Context) fuse.Status {
	root.FileInfo.FillAttr(out)
	return fuse.OK
}

func (root *Root) OpenDir(ctx *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
	return readDir(root)
}

func (dir *ServiceDir) Lookup(out *fuse.Attr, name string, ctx *fuse.Context) (*nodefs.Inode, fuse.Status) {
	return lookupName(dir, name, out, ctx)
}

func (dir *ServiceDir) GetAttr(out *fuse.Attr, file nodefs.File, ctx *fuse.Context) fuse.Status {
	dir.FileInfo.FillAttr(out)
	return fuse.OK
}

func (dir *ServiceDir) OpenDir(ctx *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
	return readDir(dir)
}

func (dir *TaskDir) Lookup(out *fuse.Attr, name string, ctx *fuse.Context) (*nodefs.Inode, fuse.Status) {
	return lookupName(dir, name, out, ctx)
}

func (dir *TaskDir) GetAttr(out *fuse.Attr, file nodefs.File, ctx *fuse.Context) fuse.Status {
	dir.FileInfo.FillAttr(out)
	return fuse.OK
}

func (dir *TaskDir) OpenDir(ctx *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
	return readDir(dir)
}

func (t *Text) GetAttr(out *fuse.Attr, file nodefs.File, ctx *fuse.Context) fuse.Status {
	t.FileInfo.FillAttr(out)
	return fuse.OK
}

func (t *Text) OpenDir(ctx *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
	return nil, fuse.EINVAL
}

func (t *Text) Open(flags uint32, ctx *fuse.Context) (nodefs.File, fuse.Status) {
	if flags&fuse.O_ANYWRITE != 0 {
		return nil, fuse.EPERM
	}
	p, err := t.ReadFile()
	if err != nil {
		return nil, fuse.EIO
	}
	return nodefs.NewDataFile(p), fuse.OK
}

func (t *CommentText) GetAttr(out *fuse.Attr, file nodefs.File, ctx *fuse.Context) fuse.Status {
	t.FileInfo.FillAttr(out)
	return fuse.OK
}

func (t *CommentText) OpenDir(ctx *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
	return nil, fuse.EINVAL
}

func (t *CommentText) Open(flags uint32, ctx *fuse.Context) (nodefs.File, fuse.Status) {
	if flags&fuse.O_ANYWRITE != 0 {
		return nil, fuse.EPERM
	}
	p, err := t.ReadFile()
	if err != nil {
		return nil, fuse.EIO
	}
	return nodefs.NewDataFile(p), fuse.OK
}

func (ctl *Ctl) GetAttr(out *fuse.Attr, file nodefs.File, ctx *fuse.Context) fuse.Status {
	ctl.FileInfo.FillAttr(out)
	return fuse.OK
}

func (ctl *Ctl) OpenDir(ctx *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
	return nil, fuse.EINVAL
}

func (ctl *Ctl) Open(flags uint32, ctx *fuse.Context) (nodefs.File, fuse.Status) {
	p, err := ctl.ReadFile()
	if err != nil {
		return nil, fuse.EIO
	}
	return nodefs.NewDataFile(p), fuse.OK
}

func (ctl *Ctl) Truncate(file nodefs.File, size uint64, ctx *fuse.Context) fuse.Status {
	return fuse.OK
}

func (ctl *Ctl) Write(file nodefs.File, data []byte, off int64, ctx *fuse.Context) (uint32, fuse.Status) {
	err := ctl.WriteFile(data)
	if err != nil {
		return 0, fuse.EINVAL
	}
	return uint32(len(data)), fuse.OK
}

func lookupName(dir Dir, name string, out *fuse.Attr, ctx *fuse.Context) (*nodefs.Inode, fuse.Status) {
	_, status := readDir(dir)
	if status != fuse.OK {
		return nil, status
	}
	c := dir.Inode().GetChild(name)
	if c == nil {
		return nil, fuse.ENOENT
	}
	status = c.Node().GetAttr(out, nil, ctx)
	if status != fuse.OK {
		return nil, status
	}
	return c, fuse.OK
}

func readDir(dir Dir) ([]fuse.DirEntry, fuse.Status) {
	p := dir.Inode()
	kids, err := dir.ReadDir()
	if err != nil {
		return nil, fuse.EIO
	}
	a := make([]fuse.DirEntry, len(kids))
	for i, kid := range kids {
		info := kid.Stat()
		if p.GetChild(info.Name) == nil {
			p.NewChild(info.Name, info.IsDir(), kid)
		}
		info.FillDirEntry(&a[i])
	}
	return a, fuse.OK
}
<commit_msg>add FUSE for macOS support<commit_after>// +build linux darwin

package fs

import (
	"os"
	"time"

	"github.com/hanwen/go-fuse/fuse"
	"github.com/hanwen/go-fuse/fuse/nodefs"
)

type Node interface {
	nodefs.Node
}

func NewNode() Node {
	return nodefs.NewDefaultNode()
}

func (f *FileInfo) FillAttr(out *fuse.Attr) {
	perm := uint32(f.Mode & os.ModePerm)
	if f.IsDir() {
		out.Mode = fuse.S_IFDIR | perm
	} else {
		out.Mode = fuse.S_IFREG | perm
	}
	out.Size = uint64(f.Size)
	out.Atime = uint64(f.LastMod.Unix())
	out.Mtime = uint64(f.LastMod.Unix())
}

func (f *FileInfo) FillDirEntry(out *fuse.DirEntry) {
	out.Name = f.Name
	out.Mode = uint32(f.Mode & os.ModePerm)
	if f.IsDir() {
		out.Mode |= fuse.S_IFDIR
	}
}

func (root *Root) MountAndServe(mtpt string, debug bool) error {
	opts := nodefs.Options{
		AttrTimeout:  time.Second,
		EntryTimeout: time.Second,
		Debug:        debug,
	}
	s, _, err := nodefs.MountRoot(mtpt, root, &opts)
	if err != nil {
		return err
	}
	s.Serve()
	return nil
}

func (root *Root) Lookup(out *fuse.Attr, name string, ctx *fuse.Context) (*nodefs.Inode, fuse.Status) {
	return lookupName(root, name, out, ctx)
}

func (root *Root) GetAttr(out *fuse.Attr, file nodefs.File, ctx *fuse.Context) fuse.Status {
	root.FileInfo.FillAttr(out)
	return fuse.OK
}

func (root *Root) OpenDir(ctx *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
	return readDir(root)
}

func (dir *ServiceDir) Lookup(out *fuse.Attr, name string, ctx *fuse.Context) (*nodefs.Inode, fuse.Status) {
	return lookupName(dir, name, out, ctx)
}

func (dir *ServiceDir) GetAttr(out *fuse.Attr, file nodefs.File, ctx *fuse.Context) fuse.Status {
	dir.FileInfo.FillAttr(out)
	return fuse.OK
}

func (dir *ServiceDir) OpenDir(ctx *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
	return readDir(dir)
}

func (dir *TaskDir) Lookup(out *fuse.Attr, name string, ctx *fuse.Context) (*nodefs.Inode, fuse.Status) {
	return lookupName(dir, name, out, ctx)
}

func (dir *TaskDir) GetAttr(out *fuse.Attr, file nodefs.File, ctx *fuse.Context) fuse.Status {
	dir.FileInfo.FillAttr(out)
	return fuse.OK
}

func (dir *TaskDir) OpenDir(ctx *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
	return readDir(dir)
}

func (t *Text) GetAttr(out *fuse.Attr, file nodefs.File, ctx *fuse.Context) fuse.Status {
	t.FileInfo.FillAttr(out)
	return fuse.OK
}

func (t *Text) OpenDir(ctx *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
	return nil, fuse.EINVAL
}

func (t *Text) Open(flags uint32, ctx *fuse.Context) (nodefs.File, fuse.Status) {
	if flags&fuse.O_ANYWRITE != 0 {
		return nil, fuse.EPERM
	}
	p, err := t.ReadFile()
	if err != nil {
		return nil, fuse.EIO
	}
	return nodefs.NewDataFile(p), fuse.OK
}

func (t *CommentText) GetAttr(out *fuse.Attr, file nodefs.File, ctx *fuse.Context) fuse.Status {
	t.FileInfo.FillAttr(out)
	return fuse.OK
}

func (t *CommentText) OpenDir(ctx *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
	return nil, fuse.EINVAL
}

func (t *CommentText) Open(flags uint32, ctx *fuse.Context) (nodefs.File, fuse.Status) {
	if flags&fuse.O_ANYWRITE != 0 {
		return nil, fuse.EPERM
	}
	p, err := t.ReadFile()
	if err != nil {
		return nil, fuse.EIO
	}
	return nodefs.NewDataFile(p), fuse.OK
}

func (ctl *Ctl) GetAttr(out *fuse.Attr, file nodefs.File, ctx *fuse.Context) fuse.Status {
	ctl.FileInfo.FillAttr(out)
	return fuse.OK
}

func (ctl *Ctl) OpenDir(ctx *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
	return nil, fuse.EINVAL
}

func (ctl *Ctl) Open(flags uint32, ctx *fuse.Context) (nodefs.File, fuse.Status) {
	p, err := ctl.ReadFile()
	if err != nil {
		return nil, fuse.EIO
	}
	return nodefs.NewDataFile(p), fuse.OK
}

func (ctl *Ctl) Truncate(file nodefs.File, size uint64, ctx *fuse.Context) fuse.Status {
	return fuse.OK
}

func (ctl *Ctl) Write(file nodefs.File, data []byte, off int64, ctx *fuse.Context) (uint32, fuse.Status) {
	err := ctl.WriteFile(data)
	if err != nil {
		return 0, fuse.EINVAL
	}
	return uint32(len(data)), fuse.OK
}

func lookupName(dir Dir, name string, out *fuse.Attr, ctx *fuse.Context) (*nodefs.Inode, fuse.Status) {
	_, status := readDir(dir)
	if status != fuse.OK {
		return nil, status
	}
	c := dir.Inode().GetChild(name)
	if c == nil {
		return nil, fuse.ENOENT
	}
	status = c.Node().GetAttr(out, nil, ctx)
	if status != fuse.OK {
		return nil, status
	}
	return c, fuse.OK
}

func readDir(dir Dir) ([]fuse.DirEntry, fuse.Status) {
	p := dir.Inode()
	kids, err := dir.ReadDir()
	if err != nil {
		return nil, fuse.EIO
	}
	a := make([]fuse.DirEntry, len(kids))
	for i, kid := range kids {
		info := kid.Stat()
		if p.GetChild(info.Name) == nil {
			p.NewChild(info.Name, info.IsDir(), kid)
		}
		info.FillDirEntry(&a[i])
	}
	return a, fuse.OK
}
<|endoftext|>


<commit_before>package client

import (
	"context"
	"github.com/imdario/mergo"
	"github.com/ory/fosite"
	"github.com/pkg/errors"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

// MongoManager cares for the managing of the Mongo Session instance of a Client
type MongoManager struct {
	DB     *mgo.Database
	Hasher fosite.Hasher
}

// GetClient returns a Client if found by an ID lookup.
func (m *MongoManager) GetClient(ctx context.Context, id string) (fosite.Client, error) {
	return m.GetConcreteClient(id)
}

// UpdateClient updates an OAuth 2.0 Client record. This is done using the equivalent of an object replace.
func (m *MongoManager) UpdateClient(c *Client) error {
	o, err := m.GetConcreteClient(c.ID)
	if err != nil {
		return errors.WithStack(err)
	}

	// If the password isn't updated, grab it from the stored object
	if c.Secret == "" {
		c.Secret = string(c.GetHashedSecret())
	} else {
		h, err := m.Hasher.Hash([]byte(c.Secret))
		if err != nil {
			return errors.WithStack(err)
		}
		c.Secret = string(h)
	}

	// Otherwise, update the object with the new updates
	if err := mergo.Merge(c, o); err != nil {
		return errors.WithStack(err)
	}

	// Update Mongo reference with the updated object
	collection := m.DB.C("clients").With(m.DB.Session.Copy())
	defer collection.Database.Session.Close()
	selector := bson.M{"_id": c.ID}
	if err := collection.Update(selector, c); err != nil {
		return errors.WithStack(err)
	}
	return nil
}

// GetConcreteClient finds a Client based on ID and returns it, if found in Mongo.
func (m *MongoManager) GetConcreteClient(id string) (*Client, error) {
	collection := m.DB.C("clients").With(m.DB.Session.Copy())
	defer collection.Database.Session.Close()

	client := &Client{}
	err := collection.Find(bson.M{"_id": id}).One(client)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return client, nil
}

// Authenticate compares a client secret with the client's stored hashed secret
func (m *MongoManager) Authenticate(id string, secret []byte) (*Client, error) {
	c, err := m.GetConcreteClient(id)
	if err != nil {
		return nil, errors.WithStack(err)
	}

	if err := m.Hasher.Compare(c.GetHashedSecret(), secret); err != nil {
		return nil, errors.WithStack(err)
	}
	return c, nil
}
<commit_msg>:arrow_up: Client: Add CreateClient method<commit_after>package client

import (
	"context"
	"github.com/imdario/mergo"
	"github.com/ory/fosite"
	"github.com/pborman/uuid"
	"github.com/pkg/errors"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

// MongoManager cares for the managing of the Mongo Session instance of a Client
type MongoManager struct {
	DB     *mgo.Database
	Hasher fosite.Hasher
}

// GetClient returns a Client if found by an ID lookup.
func (m *MongoManager) GetClient(ctx context.Context, id string) (fosite.Client, error) {
	return m.GetConcreteClient(id)
}

// UpdateClient updates an OAuth 2.0 Client record. This is done using the equivalent of an object replace.
func (m *MongoManager) UpdateClient(c *Client) error {
	o, err := m.GetConcreteClient(c.ID)
	if err != nil {
		return errors.WithStack(err)
	}

	// If the password isn't updated, grab it from the stored object
	if c.Secret == "" {
		c.Secret = string(c.GetHashedSecret())
	} else {
		h, err := m.Hasher.Hash([]byte(c.Secret))
		if err != nil {
			return errors.WithStack(err)
		}
		c.Secret = string(h)
	}

	// Otherwise, update the object with the new updates
	if err := mergo.Merge(c, o); err != nil {
		return errors.WithStack(err)
	}

	// Update Mongo reference with the updated object
	collection := m.DB.C("clients").With(m.DB.Session.Copy())
	defer collection.Database.Session.Close()
	selector := bson.M{"_id": c.ID}
	if err := collection.Update(selector, c); err != nil {
		return errors.WithStack(err)
	}
	return nil
}

// GetConcreteClient finds a Client based on ID and returns it, if found in Mongo.
func (m *MongoManager) GetConcreteClient(id string) (*Client, error) {
	collection := m.DB.C("clients").With(m.DB.Session.Copy())
	defer collection.Database.Session.Close()

	client := &Client{}
	err := collection.Find(bson.M{"_id": id}).One(client)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return client, nil
}

// Authenticate compares a client secret with the client's stored hashed secret
func (m *MongoManager) Authenticate(id string, secret []byte) (*Client, error) {
	c, err := m.GetConcreteClient(id)
	if err != nil {
		return nil, errors.WithStack(err)
	}

	if err := m.Hasher.Compare(c.GetHashedSecret(), secret); err != nil {
		return nil, errors.WithStack(err)
	}
	return c, nil
}

// CreateClient adds a new OAuth2.0 Client to the client store.
func (m *MongoManager) CreateClient(c *Client) error {
	if c.ID == "" {
		c.ID = uuid.New()
	}

	// Hash incoming secret
	h, err := m.Hasher.Hash([]byte(c.Secret))
	if err != nil {
		return errors.WithStack(err)
	}
	c.Secret = string(h)

	// Insert to Mongo
	collection := m.DB.C("clients").With(m.DB.Session.Copy())
	defer collection.Database.Session.Close()
	if err := collection.Insert(c); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
<|endoftext|>


<commit_before>package tsc

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"text/template"
	"time"
	"unicode"
	"unicode/utf8"
)

func nonil(err ...error) error {
	for _, err := range err {
		if err != nil {
			return err
		}
	}
	return nil
}

type Event struct {
	Name    string      // https://developer.github.com/webhooks/#events
	Payload interface{} // https://developer.github.com/v3/activity/events/types/
	Args    map[string]string
}

type Script struct {
	// ErrorLog specifies an optional logger for errors serving requests.
	// If nil, logging goes to os.Stderr via the log package's standard logger.
	ErrorLog *log.Logger

	OutputFunc func() io.Writer

	bash bool
	tmpl *template.Template
	args map[string]string
}

func New(file string, args []string) (*Script, error) {
	if len(args)&1 == 1 {
		return nil, errors.New("number of arguments for template script must be even")
	}
	s := &Script{}
	if len(args) != 0 {
		s.args = make(map[string]string, len(args)/2)
		for i := 0; i < len(args); i += 2 {
			if len(args[i]) < 2 || args[i][0] != '-' {
				return nil, errors.New("invalid flag name: " + args[i])
			}
			r, n := utf8.DecodeRuneInString(args[i][1:])
			if r == utf8.RuneError {
				return nil, errors.New("invalid flag name: " + args[i])
			}
			s.args[string(unicode.ToUpper(r))+args[i][1+n:]] = args[i+1]
		}
	}
	s.bash = strings.HasSuffix(file, ".sh") || strings.HasSuffix(file, ".bash")
	var err error
	s.tmpl, err = template.New(filepath.Base(file)).Funcs(s.funcs()).ParseFiles(file)
	if err != nil {
		return nil, err
	}
	return s, nil
}

func (s *Script) Webhook(event string, payload interface{}) {
	e := &Event{
		Name:    event,
		Payload: payload,
		Args:    s.args,
	}
	var err error
	if s.bash {
		err = s.runBash(e)
	} else {
		err = s.execute(s.output(), e)
	}
	if err != nil {
		s.logf("ERROR template script error: %v", err)
	}
}

func (s *Script) runBash(e *Event) (err error) {
	var buf bytes.Buffer
	if err = s.execute(&buf, e); err != nil {
		return err
	}

	cmd := exec.Command("bash")
	cmd.Stdin = bytes.NewReader(buf.Bytes())
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stderr
	cmd.Env = append(os.Environ(), "WEBHOOK=1") // cache?

	if err = cmd.Run(); err != nil {
		// dump script for later troubleshooting
		f, e := ioutil.TempFile("webhook", "debug")
		if e == nil {
			_, e = io.Copy(f, bytes.NewReader(buf.Bytes()))
			e = nonil(e, f.Close())
		}
		if e != nil {
			return fmt.Errorf("%s (failed to dump script file: %s)", err, e)
		}
		return fmt.Errorf("%s: failed with: %s", f.Name(), err)
	}

	return nil
}

func (s *Script) execute(w io.Writer, e *Event) error {
	err := s.tmpl.Execute(w, e)
	if c, ok := w.(io.Closer); ok {
		err = nonil(err, c.Close())
	}
	return err
}

func (s *Script) funcs() template.FuncMap {
	return template.FuncMap{
		"env": func(s string) string {
			return os.Getenv(s)
		},
		"exec": func(cmd string, args ...string) (string, error) {
			out, err := exec.Command(cmd, args...).Output()
			return string(bytes.TrimSpace(out)), err
		},
		"sleep": func(s string) (string, error) {
			d, err := time.ParseDuration(s)
			if err != nil {
				return "", err
			}
			time.Sleep(d)
			return "", nil
		},
		"log": func(v ...interface{}) string {
			if len(v) != 0 {
				s.log(v...)
			}
			return ""
		},
		"logf": func(format string, v ...interface{}) string {
			if format == "" {
				return ""
			}
			if len(v) == 0 {
				s.logf("%s", format)
			} else {
				s.logf(format, v...)
			}
			return ""
		},
	}
}

func (s *Script) output() io.Writer {
	if s.OutputFunc != nil {
		return s.OutputFunc()
	} else {
		return ioutil.Discard
	}
}

func (s *Script) logf(format string, v ...interface{}) {
	if s.ErrorLog != nil {
		s.ErrorLog.Printf(format, v...)
	} else {
		log.Printf(format, v...)
	}
}

func (s *Script) log(v ...interface{}) {
	if s.ErrorLog != nil {
		s.ErrorLog.Println(v...)
	} else {
		log.Println(v...)
	}
}
<commit_msg>cmd/webhook: add json func for tsc files<commit_after>package tsc

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"text/template"
	"time"
	"unicode"
	"unicode/utf8"
)

func nonil(err ...error) error {
	for _, err := range err {
		if err != nil {
			return err
		}
	}
	return nil
}

type Event struct {
	Name    string      // https://developer.github.com/webhooks/#events
	Payload interface{} // https://developer.github.com/v3/activity/events/types/
	Args    map[string]string
}

type Script struct {
	// ErrorLog specifies an optional logger for errors serving requests.
	// If nil, logging goes to os.Stderr via the log package's standard logger.
	ErrorLog *log.Logger

	OutputFunc func() io.Writer

	bash bool
	tmpl *template.Template
	args map[string]string
}

func New(file string, args []string) (*Script, error) {
	if len(args)&1 == 1 {
		return nil, errors.New("number of arguments for template script must be even")
	}
	s := &Script{}
	if len(args) != 0 {
		s.args = make(map[string]string, len(args)/2)
		for i := 0; i < len(args); i += 2 {
			if len(args[i]) < 2 || args[i][0] != '-' {
				return nil, errors.New("invalid flag name: " + args[i])
			}
			r, n := utf8.DecodeRuneInString(args[i][1:])
			if r == utf8.RuneError {
				return nil, errors.New("invalid flag name: " + args[i])
			}
			s.args[string(unicode.ToUpper(r))+args[i][1+n:]] = args[i+1]
		}
	}
	s.bash = strings.HasSuffix(file, ".sh") || strings.HasSuffix(file, ".bash")
	var err error
	s.tmpl, err = template.New(filepath.Base(file)).Funcs(s.funcs()).ParseFiles(file)
	if err != nil {
		return nil, err
	}
	return s, nil
}

func (s *Script) Webhook(event string, payload interface{}) {
	e := &Event{
		Name:    event,
		Payload: payload,
		Args:    s.args,
	}
	var err error
	if s.bash {
		err = s.runBash(e)
	} else {
		err = s.execute(s.output(), e)
	}
	if err != nil {
		s.logf("ERROR template script error: %v", err)
	}
}

func (s *Script) runBash(e *Event) (err error) {
	var buf bytes.Buffer
	if err = s.execute(&buf, e); err != nil {
		return err
	}

	cmd := exec.Command("bash")
	cmd.Stdin = bytes.NewReader(buf.Bytes())
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stderr
	cmd.Env = append(os.Environ(), "WEBHOOK=1") // cache?

	if err = cmd.Run(); err != nil {
		// dump script for later troubleshooting
		f, e := ioutil.TempFile("webhook", "debug")
		if e == nil {
			_, e = io.Copy(f, bytes.NewReader(buf.Bytes()))
			e = nonil(e, f.Close())
		}
		if e != nil {
			return fmt.Errorf("%s (failed to dump script file: %s)", err, e)
		}
		return fmt.Errorf("%s: failed with: %s", f.Name(), err)
	}

	return nil
}

func (s *Script) execute(w io.Writer, e *Event) error {
	err := s.tmpl.Execute(w, e)
	if c, ok := w.(io.Closer); ok {
		err = nonil(err, c.Close())
	}
	return err
}

func (s *Script) funcs() template.FuncMap {
	return template.FuncMap{
		"env": func(s string) string {
			return os.Getenv(s)
		},
		"exec": func(cmd string, args ...string) (string, error) {
			out, err := exec.Command(cmd, args...).Output()
			return string(bytes.TrimSpace(out)), err
		},
		"sleep": func(s string) (string, error) {
			d, err := time.ParseDuration(s)
			if err != nil {
				return "", err
			}
			time.Sleep(d)
			return "", nil
		},
		"log": func(v ...interface{}) string {
			if len(v) != 0 {
				s.log(v...)
			}
			return ""
		},
		"json": func(v interface{}) (string, error) {
			var buf bytes.Buffer
			enc := json.NewEncoder(&buf)
			enc.SetIndent("", "\t")
			enc.SetEscapeHTML(false)
			if err := enc.Encode(v); err != nil {
				return "", err
			}
			return buf.String(), nil
		},
		"logf": func(format string, v ...interface{}) string {
			if format == "" {
				return ""
			}
			if len(v) == 0 {
				s.logf("%s", format)
			} else {
				s.logf(format, v...)
			}
			return ""
		},
	}
}

func (s *Script) output() io.Writer {
	if s.OutputFunc != nil {
		return s.OutputFunc()
	} else {
		return ioutil.Discard
	}
}

func (s *Script) logf(format string, v ...interface{}) {
	if s.ErrorLog != nil {
		s.ErrorLog.Printf(format, v...)
	} else {
		log.Printf(format, v...)
	}
}

func (s *Script) log(v ...interface{}) {
	if s.ErrorLog != nil {
		s.ErrorLog.Println(v...)
	} else {
		log.Println(v...)
	}
}
<|endoftext|>


<commit_before>// Copyright 2010 Alexander Neumann. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package pgsql

import (
	"encoding/binary"
	"fmt"
	"math"
	"strconv"
	"time"
)

func (conn *Conn) flush() {
	err := conn.writer.Flush()
	if err != nil {
		panic(fmt.Sprintf("flush failed: %s", err))
	}
}

func (conn *Conn) write(b []byte) {
	_, err := conn.writer.Write(b)
	if err != nil {
		panic(fmt.Sprintf("write failed: %s", err))
	}
}

func (conn *Conn) writeByte(b byte) {
	err := conn.writer.WriteByte(b)
	if err != nil {
		panic(fmt.Sprintf("writeByte failed: %s", err))
	}
}

func (conn *Conn) writeFloat32(f float32) {
	var buf [4]byte
	b := buf[0:]

	binary.BigEndian.PutUint32(b, math.Float32bits(f))
	conn.write(b)
}

func (conn *Conn) writeFloat64(f float64) {
	var buf [8]byte
	b := buf[0:]

	binary.BigEndian.PutUint64(b, math.Float64bits(f))
	conn.write(b)
}

func (conn *Conn) writeFrontendMessageCode(code frontendMessageCode) {
	err := conn.writer.WriteByte(byte(code))
	if err != nil {
		panic(fmt.Sprintf("writeFrontendMessageCode failed: %s", err))
	}
}

func (conn *Conn) writeInt16(i int16) {
	var buf [2]byte
	b := buf[0:]

	binary.BigEndian.PutUint16(b, uint16(i))
	conn.write(b)
}

func (conn *Conn) writeInt32(i int32) {
	var buf [4]byte
	b := buf[0:]

	binary.BigEndian.PutUint32(b, uint32(i))
	conn.write(b)
}

func (conn *Conn) writeInt64(i int64) {
	var buf [8]byte
	b := buf[0:]

	binary.BigEndian.PutUint64(b, uint64(i))
	conn.write(b)
}

func (conn *Conn) writeString(s string) {
	_, err := conn.writer.WriteString(s)
	if err != nil {
		panic(fmt.Sprintf("writeString failed: %s", err))
	}
}

func (conn *Conn) writeString0(s string) {
	conn.writeString(s)
	conn.writeByte(0)
}

func (conn *Conn) writeFlush() {
	conn.writeFrontendMessageCode(_Flush)
	conn.writeInt32(4)

	conn.flush()
}

func (conn *Conn) writeBind(stmt *Statement) {
	values := make([]string, len(stmt.params))

	var paramValuesLen int
	for i, param := range stmt.params {
		value := param.value
		if val, ok := value.(uint64); ok {
			value = int64(val)
		}

		switch val := value.(type) {
		case bool:
			if val {
				values[i] = "t"
			} else {
				values[i] = "f"
			}

		case byte:
			values[i] = string([]byte{val})

		case float:
			values[i] = strconv.Ftoa(val, 'f', -1)

		case float32:
			values[i] = strconv.Ftoa32(val, 'f', -1)

		case float64:
			values[i] = strconv.Ftoa64(val, 'f', -1)

		case int:
			values[i] = strconv.Itoa(val)

		case int16:
			values[i] = strconv.Itoa(int(val))

		case int32:
			values[i] = strconv.Itoa(int(val))

		case int64:
			switch param.typ {
			case Date:
				values[i] = time.SecondsToUTC(val).Format("2006-01-02")

			case Time, TimeTZ:
				values[i] = time.SecondsToUTC(val).Format("15:04:05")

			case Timestamp, TimestampTZ:
				values[i] = time.SecondsToUTC(val).Format("2006-01-02 15:04:05")

			default:
				values[i] = strconv.Itoa64(val)
			}

		case nil:

		case string:
			values[i] = val

		case *time.Time:
			switch param.typ {
			case Date:
				values[i] = val.Format("2006-01-02")

			case Time, TimeTZ:
				values[i] = val.Format("15:04:05")

			case Timestamp, TimestampTZ:
				values[i] = val.Format("2006-01-02 15:04:05")

			default:
				panic("invalid use of *time.Time")
			}

		default:
			panic("unsupported parameter type")
		}

		paramValuesLen += len(values[i])
	}

	msgLen := int32(4 +
		len(stmt.portalName) + 1 +
		len(stmt.name) + 1 +
		2 + 2 +
		2 + len(stmt.params)*4 + paramValuesLen +
		2 + 2)

	conn.writeFrontendMessageCode(_Bind)
	conn.writeInt32(msgLen)
	conn.writeString0(stmt.portalName)
	conn.writeString0(stmt.name)
	conn.writeInt16(1)
	conn.writeInt16(int16(textFormat))
	conn.writeInt16(int16(len(stmt.params)))

	for i, param := range stmt.params {
		if param.value == nil {
			conn.writeInt32(-1)
		} else {
			conn.writeInt32(int32(len(values[i])))
			conn.writeString(values[i])
		}
	}

	conn.writeInt16(1)
	conn.writeInt16(binaryFormat)

	conn.writeFlush()
}

func (conn *Conn) writeClose(itemType byte, itemName string) {
	msgLen := int32(4 + 1 + len(itemName) + 1)

	conn.writeFrontendMessageCode(_Close)
	conn.writeInt32(msgLen)
	conn.writeByte(itemType)
	conn.writeString0(itemName)

	conn.flush()
}

func (conn *Conn) writeDescribe(stmt *Statement) {
	msgLen := int32(4 + 1 + len(stmt.portalName) + 1)

	conn.writeFrontendMessageCode(_Describe)
	conn.writeInt32(msgLen)
	conn.writeByte('P')
	conn.writeString0(stmt.portalName)

	conn.writeFlush()
}

func (conn *Conn) writeExecute(stmt *Statement) {
	msgLen := int32(4 + len(stmt.portalName) + 1 + 4)

	conn.writeFrontendMessageCode(_Execute)
	conn.writeInt32(msgLen)
	conn.writeString0(stmt.portalName)
	conn.writeInt32(0)

	conn.writeFlush()
}

func (conn *Conn) writeParse(stmt *Statement) {
	if conn.LogLevel >= LogDebug {
		defer conn.logExit(conn.logEnter("*Conn.writeParse"))
	}

	if conn.LogLevel >= LogCommand {
		conn.log(LogCommand, fmt.Sprintf("stmt.ActualCommand: '%s'", stmt.ActualCommand()))
	}

	msgLen := int32(4 +
		len(stmt.name) + 1 +
		len(stmt.actualCommand) + 1 +
		2 + len(stmt.params)*4)

	conn.writeFrontendMessageCode(_Parse)
	conn.writeInt32(msgLen)
	conn.writeString0(stmt.name)
	conn.writeString0(stmt.actualCommand)

	conn.writeInt16(int16(len(stmt.params)))
	for _, param := range stmt.params {
		conn.writeInt32(int32(param.typ))
	}

	conn.writeFlush()
}

func (conn *Conn) writePasswordMessage(password string) {
	if conn.LogLevel >= LogDebug {
		defer conn.logExit(conn.logEnter("*Conn.writePasswordMessage"))
	}

	msgLen := int32(4 + len(password) + 1)

	conn.writeFrontendMessageCode(_PasswordMessage)
	conn.writeInt32(msgLen)
	conn.writeString0(password)

	conn.flush()
}

func (conn *Conn) writeQuery(command string) {
	if conn.LogLevel >= LogDebug {
		defer conn.logExit(conn.logEnter("*Conn.writeQuery"))
	}

	if conn.LogLevel >= LogCommand {
		conn.log(LogCommand, fmt.Sprintf("command: '%s'", command))
	}

	conn.writeFrontendMessageCode(_Query)
	conn.writeInt32(int32(4 + len(command) + 1))
	conn.writeString0(command)

	conn.flush()
}

func (conn *Conn) writeStartup() {
	if conn.LogLevel >= LogDebug {
		defer conn.logExit(conn.logEnter("*Conn.writeStartup"))
	}

	msglen := int32(4 + 4 +
		len("user") + 1 + len(conn.params.User) + 1 +
		len("database") + 1 + len(conn.params.Database) + 1 + 1)

	conn.writeInt32(msglen)

	// For now we only support protocol version 3.0.
	conn.writeInt32(3 << 16)

	conn.writeString0("user")
	conn.writeString0(conn.params.User)

	conn.writeString0("database")
	conn.writeString0(conn.params.Database)

	conn.writeByte(0)

	conn.flush()
}

func (conn *Conn) writeSync() {
	conn.writeFrontendMessageCode(_Sync)
	conn.writeInt32(4)

	conn.writeFlush()
}

func (conn *Conn) writeTerminate() {
	conn.writeFrontendMessageCode(_Terminate)
	conn.writeInt32(4)

	conn.flush()
}
<commit_msg>Use always text format for now<commit_after>// Copyright 2010 Alexander Neumann. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package pgsql

import (
	"encoding/binary"
	"fmt"
	"math"
	"strconv"
	"time"
)

func (conn *Conn) flush() {
	err := conn.writer.Flush()
	if err != nil {
		panic(fmt.Sprintf("flush failed: %s", err))
	}
}

func (conn *Conn) write(b []byte) {
	_, err := conn.writer.Write(b)
	if err != nil {
		panic(fmt.Sprintf("write failed: %s", err))
	}
}

func (conn *Conn) writeByte(b byte) {
	err := conn.writer.WriteByte(b)
	if err != nil {
		panic(fmt.Sprintf("writeByte failed: %s", err))
	}
}

func (conn *Conn) writeFloat32(f float32) {
	var buf [4]byte
	b := buf[0:]

	binary.BigEndian.PutUint32(b, math.Float32bits(f))
	conn.write(b)
}

func (conn *Conn) writeFloat64(f float64) {
	var buf [8]byte
	b := buf[0:]

	binary.BigEndian.PutUint64(b, math.Float64bits(f))
	conn.write(b)
}

func (conn *Conn) writeFrontendMessageCode(code frontendMessageCode) {
	err := conn.writer.WriteByte(byte(code))
	if err != nil {
		panic(fmt.Sprintf("writeFrontendMessageCode failed: %s", err))
	}
}

func (conn *Conn) writeInt16(i int16) {
	var buf [2]byte
	b := buf[0:]

	binary.BigEndian.PutUint16(b, uint16(i))
	conn.write(b)
}

func (conn *Conn) writeInt32(i int32) {
	var buf [4]byte
	b := buf[0:]

	binary.BigEndian.PutUint32(b, uint32(i))
	conn.write(b)
}

func (conn *Conn) writeInt64(i int64) {
	var buf [8]byte
	b := buf[0:]

	binary.BigEndian.PutUint64(b, uint64(i))
	conn.write(b)
}

func (conn *Conn) writeString(s string) {
	_, err := conn.writer.WriteString(s)
	if err != nil {
		panic(fmt.Sprintf("writeString failed: %s", err))
	}
}

func (conn *Conn) writeString0(s string) {
	conn.writeString(s)
	conn.writeByte(0)
}

func (conn *Conn) writeFlush() {
	conn.writeFrontendMessageCode(_Flush)
	conn.writeInt32(4)

	conn.flush()
}

func (conn *Conn) writeBind(stmt *Statement) {
	values := make([]string, len(stmt.params))

	var paramValuesLen int
	for i, param := range stmt.params {
		value := param.value
		if val, ok := value.(uint64); ok {
			value = int64(val)
		}

		switch val := value.(type) {
		case bool:
			if val {
				values[i] = "t"
			} else {
				values[i] = "f"
			}

		case byte:
			values[i] = string([]byte{val})

		case float:
			values[i] = strconv.Ftoa(val, 'f', -1)

		case float32:
			values[i] = strconv.Ftoa32(val, 'f', -1)

		case float64:
			values[i] = strconv.Ftoa64(val, 'f', -1)

		case int:
			values[i] = strconv.Itoa(val)

		case int16:
			values[i] = strconv.Itoa(int(val))

		case int32:
			values[i] = strconv.Itoa(int(val))

		case int64:
			switch param.typ {
			case Date:
				values[i] = time.SecondsToUTC(val).Format("2006-01-02")

			case Time, TimeTZ:
				values[i] = time.SecondsToUTC(val).Format("15:04:05")

			case Timestamp, TimestampTZ:
				values[i] = time.SecondsToUTC(val).Format("2006-01-02 15:04:05")

			default:
				values[i] = strconv.Itoa64(val)
			}

		case nil:

		case string:
			values[i] = val

		case *time.Time:
			switch param.typ {
			case Date:
				values[i] = val.Format("2006-01-02")

			case Time, TimeTZ:
				values[i] = val.Format("15:04:05")

			case Timestamp, TimestampTZ:
				values[i] = val.Format("2006-01-02 15:04:05")

			default:
				panic("invalid use of *time.Time")
			}

		default:
			panic("unsupported parameter type")
		}

		paramValuesLen += len(values[i])
	}

	msgLen := int32(4 +
		len(stmt.portalName) + 1 +
		len(stmt.name) + 1 +
		2 + 2 +
		2 + len(stmt.params)*4 + paramValuesLen +
		2 + 2)

	conn.writeFrontendMessageCode(_Bind)
	conn.writeInt32(msgLen)
	conn.writeString0(stmt.portalName)
	conn.writeString0(stmt.name)
	conn.writeInt16(1)
	conn.writeInt16(int16(textFormat))
	conn.writeInt16(int16(len(stmt.params)))

	for i, param := range stmt.params {
		if param.value == nil {
			conn.writeInt32(-1)
		} else {
			conn.writeInt32(int32(len(values[i])))
			conn.writeString(values[i])
		}
	}

	conn.writeInt16(1)
	conn.writeInt16(int16(textFormat))

	conn.writeFlush()
}

func (conn *Conn) writeClose(itemType byte, itemName string) {
	msgLen := int32(4 + 1 + len(itemName) + 1)

	conn.writeFrontendMessageCode(_Close)
	conn.writeInt32(msgLen)
	conn.writeByte(itemType)
	conn.writeString0(itemName)

	conn.flush()
}

func (conn *Conn) writeDescribe(stmt *Statement) {
	msgLen := int32(4 + 1 + len(stmt.portalName) + 1)

	conn.writeFrontendMessageCode(_Describe)
	conn.writeInt32(msgLen)
	conn.writeByte('P')
	conn.writeString0(stmt.portalName)

	conn.writeFlush()
}

func (conn *Conn) writeExecute(stmt *Statement) {
	msgLen := int32(4 + len(stmt.portalName) + 1 + 4)

	conn.writeFrontendMessageCode(_Execute)
	conn.writeInt32(msgLen)
	conn.writeString0(stmt.portalName)
	conn.writeInt32(0)

	conn.writeFlush()
}

func (conn *Conn) writeParse(stmt *Statement) {
	if conn.LogLevel >= LogDebug {
		defer conn.logExit(conn.logEnter("*Conn.writeParse"))
	}

	if conn.LogLevel >= LogCommand {
		conn.log(LogCommand, fmt.Sprintf("stmt.ActualCommand: '%s'", stmt.ActualCommand()))
	}

	msgLen := int32(4 +
		len(stmt.name) + 1 +
		len(stmt.actualCommand) + 1 +
		2 + len(stmt.params)*4)

	conn.writeFrontendMessageCode(_Parse)
	conn.writeInt32(msgLen)
	conn.writeString0(stmt.name)
	conn.writeString0(stmt.actualCommand)

	conn.writeInt16(int16(len(stmt.params)))
	for _, param := range stmt.params {
		conn.writeInt32(int32(param.typ))
	}

	conn.writeFlush()
}

func (conn *Conn) writePasswordMessage(password string) {
	if conn.LogLevel >= LogDebug {
		defer conn.logExit(conn.logEnter("*Conn.writePasswordMessage"))
	}

	msgLen := int32(4 + len(password) + 1)

	conn.writeFrontendMessageCode(_PasswordMessage)
	conn.writeInt32(msgLen)
	conn.writeString0(password)

	conn.flush()
}

func (conn *Conn) writeQuery(command string) {
	if conn.LogLevel >= LogDebug {
		defer conn.logExit(conn.logEnter("*Conn.writeQuery"))
	}

	if conn.LogLevel >= LogCommand {
		conn.log(LogCommand, fmt.Sprintf("command: '%s'", command))
	}

	conn.writeFrontendMessageCode(_Query)
	conn.writeInt32(int32(4 + len(command) + 1))
	conn.writeString0(command)

	conn.flush()
}

func (conn *Conn) writeStartup() {
	if conn.LogLevel >= LogDebug {
		defer conn.logExit(conn.logEnter("*Conn.writeStartup"))
	}

	msglen := int32(4 + 4 +
		len("user") + 1 + len(conn.params.User) + 1 +
		len("database") + 1 + len(conn.params.Database) + 1 + 1)

	conn.writeInt32(msglen)

	// For now we only support protocol version 3.0.
	conn.writeInt32(3 << 16)

	conn.writeString0("user")
	conn.writeString0(conn.params.User)

	conn.writeString0("database")
	conn.writeString0(conn.params.Database)

	conn.writeByte(0)

	conn.flush()
}

func (conn *Conn) writeSync() {
	conn.writeFrontendMessageCode(_Sync)
	conn.writeInt32(4)

	conn.writeFlush()
}

func (conn *Conn) writeTerminate() {
	conn.writeFrontendMessageCode(_Terminate)
	conn.writeInt32(4)

	conn.flush()
}
<|endoftext|>


<commit_before>package main

import (
	"net"

	"golang.org/x/crypto/ssh"
)

type connMetadata struct {
	ssh.ConnMetadata
	cfg *config
}

type channelMetadata struct {
	connMetadata
	channelID int
}

var channelHandlers = map[string]func(newChannel ssh.NewChannel, metadata channelMetadata) error{
	"session":      handleSessionChannel,
	"direct-tcpip": handleDirectTCPIPChannel,
}

func handleConnection(conn net.Conn, cfg *config) {
	defer conn.Close()
	serverConn, newChannels, requests, err := ssh.NewServerConn(conn, cfg.sshConfig)
	if err != nil {
		warningLogger.Printf("Failed to establish SSH connection: %v", err)
		return
	}
	defer serverConn.Close()

	metadata := connMetadata{serverConn, cfg}

	metadata.logEvent(connectionLog{
		ClientVersion: string(serverConn.ClientVersion()),
	})
	defer metadata.logEvent(connectionCloseLog{})

	if _, _, err := serverConn.SendRequest("hostkeys-00@openssh.com", false, createHostkeysRequestPayload(cfg.parsedHostKeys)); err != nil {
		warningLogger.Printf("Failed to send hostkeys-00@openssh.com request: %v", err)
		return
	}

	go func() {
		for request := range requests {
			if err := handleGlobalRequest(request, metadata); err != nil {
				warningLogger.Printf("Failed to handle global request: %v", err)
				serverConn.Close()
			}
		}
	}()

	channelID := 0
	for newChannel := range newChannels {
		channelType := newChannel.ChannelType()
		handler := channelHandlers[channelType]
		if handler == nil {
			warningLogger.Printf("Unsupported channel type %v", channelType)
			if err := newChannel.Reject(ssh.ConnectionFailed, "open failed"); err != nil {
				warningLogger.Printf("Failed to reject channel: %v", err)
				break
			}
			continue
		}
		go func() {
			if err := handler(newChannel, channelMetadata{metadata, channelID}); err != nil {
				warningLogger.Printf("Failed to handle new channel: %v", err)
				serverConn.Close()
			}
		}()
		channelID++
	}
}
<commit_msg>Wait for channels to close after closing a connection before returning<commit_after>package main

import (
	"net"

	"golang.org/x/crypto/ssh"
)

type connMetadata struct {
	ssh.ConnMetadata
	cfg *config
}

type channelMetadata struct {
	connMetadata
	channelID int
}

var channelHandlers = map[string]func(newChannel ssh.NewChannel, metadata channelMetadata) error{
	"session":      handleSessionChannel,
	"direct-tcpip": handleDirectTCPIPChannel,
}

func handleConnection(conn net.Conn, cfg *config) {
	defer conn.Close()
	serverConn, newChannels, requests, err := ssh.NewServerConn(conn, cfg.sshConfig)
	if err != nil {
		warningLogger.Printf("Failed to establish SSH connection: %v", err)
		return
	}
	channels := []chan interface{}{}
	metadata := connMetadata{serverConn, cfg}
	defer func() {
		serverConn.Close()
		for _, channel := range channels {
			<-channel
		}
		metadata.logEvent(connectionCloseLog{})
	}()

	metadata.logEvent(connectionLog{
		ClientVersion: string(serverConn.ClientVersion()),
	})

	if _, _, err := serverConn.SendRequest("hostkeys-00@openssh.com", false, createHostkeysRequestPayload(cfg.parsedHostKeys)); err != nil {
		warningLogger.Printf("Failed to send hostkeys-00@openssh.com request: %v", err)
		return
	}

	go func() {
		for request := range requests {
			if err := handleGlobalRequest(request, metadata); err != nil {
				warningLogger.Printf("Failed to handle global request: %v", err)
				serverConn.Close()
			}
		}
	}()

	channelID := 0
	for newChannel := range newChannels {
		channelType := newChannel.ChannelType()
		handler := channelHandlers[channelType]
		if handler == nil {
			warningLogger.Printf("Unsupported channel type %v", channelType)
			if err := newChannel.Reject(ssh.ConnectionFailed, "open failed"); err != nil {
				warningLogger.Printf("Failed to reject channel: %v", err)
				break
			}
			continue
		}
		go func() {
			channelChan := make(chan interface{})
			channels = append(channels, channelChan)
			defer func() { channelChan <- nil }()
			if err := handler(newChannel, channelMetadata{metadata, channelID}); err != nil {
				warningLogger.Printf("Failed to handle new channel: %v", err)
				serverConn.Close()
			}
		}()
		channelID++
	}
}
<|endoftext|>


<commit_before>package sdbot

import (
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"os/signal"
	"strings"
	"sync"
	"time"

	"github.com/gorilla/websocket"
	"github.com/mikopits/sdbot/utilities"
)

// LoginTime contains the unix login times as values to each particular room
// the bot has joined. This allows us to ignore messages that occurred before
// the bot has logged in.
var LoginTime map[string]int = make(map[string]int)

var interrupt chan os.Signal

// Connection represents the connection to the websocket.
type Connection struct {
	Bot       *Bot
	Connected bool
	LoginTime map[string]int
	conn      *websocket.Conn
	queue     chan string
}

// NewConnection creates a new connection for a bot.
func NewConnection(b *Bot) *Connection {
	return &Connection{
		Bot:       b,
		LoginTime: make(map[string]int),
		queue:     make(chan string, 64),
	}
}

// TODO Automatic reconnection to the socket.
// Connects to the server websocket and initialize reading and writing threads.
func (c *Connection) connect() {
	host := c.Bot.Config.Server + ":" + c.Bot.Config.Port
	u := url.URL{Scheme: "ws", Host: host, Path: "/showdown/websocket"}
	Info(fmt.Sprintf("Connecting to %s...", u.String()))

	var res *http.Response
	var err error
	dialer := websocket.DefaultDialer
	c.conn, res, err = dialer.Dial(u.String(), http.Header{
		"Origin": []string{"https://play.pokemonshowdown.com"},
	})
	CheckErr(err)

	c.Connected = true

	defer res.Body.Close()
	defer c.conn.Close()

	var wg sync.WaitGroup
	wg.Add(1)
	c.startReading()
	c.startSending()
	defer wg.Done()
	wg.Wait()
}

// ErrUnexpectedMessageType is returned when we receive a message from the
// websocket that isn't a websocket.TextMessage or a normal closure.
var ErrUnexpectedMessageType = errors.New("sdbot: unexpected message type from the websocket")

// Listens for messages from the websocket.
// TODO gracefully break out of this loop on interrupt.
func (c *Connection) startReading() {
	go func() {
		for {
			msgType, msg, err := c.conn.ReadMessage()
			CheckErr(err)

			var room string
			messages := strings.Split(string(msg), "\n")

			if string(messages[0][0]) == ">" {
				room, messages = messages[0], messages[1:]
			}

			for _, rawmessage := range messages {
				s, err := utilities.Encode(rawmessage, utilities.UTF8)
				CheckErr(err)
				c.parse(fmt.Sprintf("%s\n%s", room, s))
			}
		}
	}()
}

// Initiates the message sending goroutine.
func (c *Connection) startSending() {
	go func() {
		interrupt = make(chan os.Signal, 1)
		signal.Notify(interrupt, os.Interrupt)
		done := make(chan struct{})

		for {
			select {
			case msg := <-c.queue:
				send(c, msg)
				ms := 1000.0 / c.Bot.Config.MessagesPerSecond
				time.Sleep(time.Duration(ms) * time.Millisecond)
			case <-interrupt:
				Warn("Process was interrupted. Closing connection...")

				// Send a close frame and wait for the server to close the connection.
				err := c.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
				if err != nil {
					Error(err)
					return
				}

				// FIXME None of this seems to work as intended.
				// Close all plugin goroutines gracefully.
				var wg sync.WaitGroup
				wg.Add(1)
				c.Bot.StopTimedPlugins()
				c.Bot.UnregisterPlugins()
				defer wg.Done()
				wg.Wait()

				select {
				case <-done:
				case <-time.After(time.Second):
					os.Exit(0)
				}
				c.conn.Close()
				c.Connected = false
				return
			}
		}
	}()
}

// QueueMessage adds a message to the outgoing queue.
func (c *Connection) QueueMessage(msg string) {
	c.queue <- msg
}

// Sends a message upstream to the websocket ignoring the message queue.
func send(c *Connection, s string) {
	out, err := utilities.Encode(s, utilities.UTF8)
	CheckErr(err)
	logOutgoingAll(loggers, s)

	err := c.conn.WriteMessage(websocket.TextMessage, []byte(out))
	CheckErr(err)
}

// Parses the message and difers it to a relevant handler.
func (c *Connection) parse(s string) {
	m := NewMessage(s, c.Bot)

	// Log the incoming messages to every logger.
	logIncomingAll(loggers, s)

	cmd := strings.ToLower(m.Command)

	if cmd == ":" {
		c.LoginTime[m.Room.Name] = m.Timestamp
	}

	callHandler(handlers, cmd, m)
}
<commit_msg>connection: fix typo and oversight in startReading, send<commit_after>package sdbot

import (
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"os/signal"
	"strings"
	"sync"
	"time"

	"github.com/gorilla/websocket"
	"github.com/mikopits/sdbot/utilities"
)

// LoginTime contains the unix login times as values to each particular room
// the bot has joined. This allows us to ignore messages that occurred before
// the bot has logged in.
var LoginTime map[string]int = make(map[string]int)

var interrupt chan os.Signal

// Connection represents the connection to the websocket.
type Connection struct {
	Bot       *Bot
	Connected bool
	LoginTime map[string]int
	conn      *websocket.Conn
	queue     chan string
}

// NewConnection creates a new connection for a bot.
func NewConnection(b *Bot) *Connection {
	return &Connection{
		Bot:       b,
		LoginTime: make(map[string]int),
		queue:     make(chan string, 64),
	}
}

// TODO Automatic reconnection to the socket.
// Connects to the server websocket and initialize reading and writing threads.
func (c *Connection) connect() {
	host := c.Bot.Config.Server + ":" + c.Bot.Config.Port
	u := url.URL{Scheme: "ws", Host: host, Path: "/showdown/websocket"}
	Info(fmt.Sprintf("Connecting to %s...", u.String()))

	var res *http.Response
	var err error
	dialer := websocket.DefaultDialer
	c.conn, res, err = dialer.Dial(u.String(), http.Header{
		"Origin": []string{"https://play.pokemonshowdown.com"},
	})
	CheckErr(err)

	c.Connected = true

	defer res.Body.Close()
	defer c.conn.Close()

	var wg sync.WaitGroup
	wg.Add(1)
	c.startReading()
	c.startSending()
	defer wg.Done()
	wg.Wait()
}

// ErrUnexpectedMessageType is returned when we receive a message from the
// websocket that isn't a websocket.TextMessage or a normal closure.
var ErrUnexpectedMessageType = errors.New("sdbot: unexpected message type from the websocket")

// Listens for messages from the websocket.
// TODO gracefully break out of this loop on interrupt.
func (c *Connection) startReading() {
	go func() {
		for {
			msgType, msg, err := c.conn.ReadMessage()
			CheckErr(err)

			if msgType != websocket.TextMessage || msgType == -1 {
				Fatalf("sdbot: got message type %d from server", msgType)
			}

			var room string
			messages := strings.Split(string(msg), "\n")

			if string(messages[0][0]) == ">" {
				room, messages = messages[0], messages[1:]
			}

			for _, rawmessage := range messages {
				s, err := utilities.Encode(rawmessage, utilities.UTF8)
				CheckErr(err)
				c.parse(fmt.Sprintf("%s\n%s", room, s))
			}
		}
	}()
}

// Initiates the message sending goroutine.
func (c *Connection) startSending() {
	go func() {
		interrupt = make(chan os.Signal, 1)
		signal.Notify(interrupt, os.Interrupt)
		done := make(chan struct{})

		for {
			select {
			case msg := <-c.queue:
				send(c, msg)
				ms := 1000.0 / c.Bot.Config.MessagesPerSecond
				time.Sleep(time.Duration(ms) * time.Millisecond)
			case <-interrupt:
				Warn("Process was interrupted. Closing connection...")

				// Send a close frame and wait for the server to close the connection.
				err := c.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
				if err != nil {
					Error(err)
					return
				}

				// FIXME None of this seems to work as intended.
				// Close all plugin goroutines gracefully.
				var wg sync.WaitGroup
				wg.Add(1)
				c.Bot.StopTimedPlugins()
				c.Bot.UnregisterPlugins()
				defer wg.Done()
				wg.Wait()

				select {
				case <-done:
				case <-time.After(time.Second):
					os.Exit(0)
				}
				c.conn.Close()
				c.Connected = false
				return
			}
		}
	}()
}

// QueueMessage adds a message to the outgoing queue.
func (c *Connection) QueueMessage(msg string) {
	c.queue <- msg
}

// Sends a message upstream to the websocket ignoring the message queue.
func send(c *Connection, s string) {
	enc, err := utilities.Encode(s, utilities.UTF8)
	CheckErr(err)
	logOutgoingAll(loggers, s)

	err = c.conn.WriteMessage(websocket.TextMessage, []byte(enc))
	CheckErr(err)
}

// Parses the message and difers it to a relevant handler.
func (c *Connection) parse(s string) {
	m := NewMessage(s, c.Bot)

	// Log the incoming messages to every logger.
	logIncomingAll(loggers, s)

	cmd := strings.ToLower(m.Command)

	if cmd == ":" {
		c.LoginTime[m.Room.Name] = m.Timestamp
	}

	callHandler(handlers, cmd, m)
}
<|endoftext|>


<commit_before>package http2

import (
	"fmt"
	hpack "github.com/ami-GS/GoHPACK"
	"net"
	"reflect"
)

type Connection struct {
	Conn                 net.Conn
	Streams              map[uint32]*Stream
	lastStreamID         uint32
	Table                *hpack.Table
	HeaderTableSize      uint32
	EnablePush           byte
	MaxConcurrentStreams uint32
	InitialWindowSize    uint32
	MaxFrameSize         uint32
	MaxHeaderListSize    uint32
}

func (self *Connection) Parse(buf []byte) {
	info := Http2Header{}
	info.Parse(buf[:9])

	ID := info.GetStreamID()
	_, ok := self.Streams[ID]
	if !ok {
		// not cool
		self.AddStream(ID)
	}

	var frame Frame
	switch info.Type {
	case DATA_FRAME:
		frame = &Data{Header: &info}
	case HEADERS_FRAME:
		frame = &Headers{Header: &info, Table: self.Table} // not cool using table here
	case PRIORITY_FRAME:
		frame = &Priority{Header: &info}
	case RST_STREAM_FRAME:
		frame = &Rst_stream{Header: &info}
	case SETTINGS_FRAME:
		frame = &Settings{Header: &info}
	case PING_FRAME:
		frame = &Ping{Header: &info}
	case GOAWAY_FRAME:
		frame = &GoAway{Header: &info}
	case WINDOW_UPDATE_FRAME:
		frame = &WindowUpdate{Header: &info}
	case CONTINUATION_FRAME:
		frame = &Continuation{Header: &info}
	default:
		panic("undefined frame type")
	}
	frame.Parse(buf[9:])

	fmt.Printf("Receive: %s\n%s\n", self.Streams[ID].String(), frame.String())
	self.Streams[ID].EvaluateFrame(frame)
}

func (self *Connection) Send(frame Frame) {
	self.Streams[frame.GetStreamID()].Send(frame)
}

func (self *Connection) RunReceiver() {
	var buf []byte
	for {
		buf = make([]byte, 1024)
		_, err := self.Conn.Read(buf)
		if err != nil {
			return //EOF?
		} else {
			if reflect.DeepEqual(buf[:24], CONNECTION_PREFACE) {
				fmt.Printf("New connection from %v\n", self.Conn.RemoteAddr())
				continue
			}
			self.Parse(buf)
		}
	}
}

func (self *Connection) AddStream(streamID uint32) {
	self.Streams[streamID] = NewStream(self, streamID)
}

func (self *Connection) SetHeaderTableSize(value uint32) {
	self.HeaderTableSize = value
	self.Table.SetDynamicTableSize(value)
}

func NewConnection(conn net.Conn, streamID uint32) *Connection {
	table := hpack.NewTable()
	connection := Connection{conn, nil, 0, &table, 4096, 1, INFINITE, 65535, MAX_FRAME_SIZE_MIN, INFINITE}
	connection.Streams = map[uint32]*Stream{0: NewStream(&connection, 0)}
	connection.AddStream(streamID)
	return &connection
}
<commit_msg>receive each size of packet<commit_after>package http2

import (
	"fmt"
	hpack "github.com/ami-GS/GoHPACK"
	"net"
	"reflect"
)

type Connection struct {
	Conn                 net.Conn
	Streams              map[uint32]*Stream
	lastStreamID         uint32
	Table                *hpack.Table
	HeaderTableSize      uint32
	EnablePush           byte
	MaxConcurrentStreams uint32
	InitialWindowSize    uint32
	MaxFrameSize         uint32
	MaxHeaderListSize    uint32
	Preface              bool
	buf                  []byte
}

func (self *Connection) Parse(info *Http2Header) (frame Frame) {

	switch info.Type {
	case DATA_FRAME:
		frame = &Data{Header: info}
	case HEADERS_FRAME:
		frame = &Headers{Header: info, Table: self.Table} // not cool using table here
	case PRIORITY_FRAME:
		frame = &Priority{Header: info}
	case RST_STREAM_FRAME:
		frame = &Rst_stream{Header: info}
	case SETTINGS_FRAME:
		frame = &Settings{Header: info}
	case PING_FRAME:
		frame = &Ping{Header: info}
	case GOAWAY_FRAME:
		frame = &GoAway{Header: info}
	case WINDOW_UPDATE_FRAME:
		frame = &WindowUpdate{Header: info}
	case CONTINUATION_FRAME:
		frame = &Continuation{Header: info}
	default:
		panic("undefined frame type")
	}
	self.buf = make([]byte, info.Length)
	self.Conn.Read(self.buf)
	frame.Parse(self.buf)

	return frame
}

func (self *Connection) Send(frame Frame) {
	self.Streams[frame.GetStreamID()].Send(frame)
}

func (self *Connection) RunReceiver() {
	for {
		if self.Preface {
			self.buf = make([]byte, 9)
			self.Conn.Read(self.buf)
			if reflect.DeepEqual(self.buf, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0}) {
				self.Preface = false
				return // connection closed from client
			}
			info := Http2Header{}
			info.Parse(self.buf)
			ID := info.GetStreamID()
			_, ok := self.Streams[ID]
			if !ok {
				// not cool
				self.AddStream(ID)
			}
			frame := self.Parse(&info)
			fmt.Printf("Receive: %s\n%s\n", self.Streams[ID].String(), frame.String())
			self.Streams[ID].EvaluateFrame(frame)
		} else {
			self.buf = make([]byte, 24)
			_, err := self.Conn.Read(self.buf)
			if err != nil {
				return
			} else {
				if reflect.DeepEqual(self.buf, CONNECTION_PREFACE) {
					self.Preface = true
					fmt.Printf("New connection from %v\n", self.Conn.RemoteAddr())
				}
			}
		}
	}
}

func (self *Connection) AddStream(streamID uint32) {
	self.Streams[streamID] = NewStream(self, streamID)
}

func (self *Connection) SetHeaderTableSize(value uint32) {
	self.HeaderTableSize = value
	self.Table.SetDynamicTableSize(value)
}

func NewConnection(conn net.Conn, streamID uint32) *Connection {
	table := hpack.NewTable()
	connection := Connection{conn, nil, 0, &table, 4096, 1, INFINITE, 65535, MAX_FRAME_SIZE_MIN, INFINITE, false, []byte{}}
	connection.Streams = map[uint32]*Stream{0: NewStream(&connection, 0)}
	connection.AddStream(streamID)
	return &connection
}
<|endoftext|>


<commit_before>package xmpp;

import (
  "crypto/tls"
  "fmt"
  "os"
  "regexp"
  "net"
)

type Client struct {
  hostname string
  conn net.Conn
}

func (client *Client) startTls() {
  var plain_conn net.Conn
  var err os.Error

  if plain_conn, err = net.Dial("tcp", "", client.hostname + ":5222"); err != nil {
    die("Failed to establish plain connection: %s", err)
  }

  write(plain_conn, "<?xml version='1.0'?>")
  write(plain_conn, "<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")

  log("Read: %s", read(plain_conn))

  // assuming need to start tls
  write(plain_conn, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls' />")
  log("Read: %s", read(plain_conn))

  // assuming the server asked to proceed
  if client.conn, err = tls.Dial("tcp", "", client.hostname + ":https", nil); err != nil {
    die("Failed to establish tls connection (%s)", err)
  }
}

func NewClient(hostname, user, password string) (client *Client, failure os.Error) {
  failure = nil
  defer func() {
    if err := recover(); err != nil {
      client = nil

      var ok bool
      if failure, ok = err.(os.Error); !ok {
        failure = os.NewError(fmt.Sprintf("Weird error happened: %s\n", failure))
      }
    }
  }()

  client = &Client{hostname: hostname}

  client.startTls()

  client.write("<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")

  client.read()
  client.read()

  auth := NewAuth(user, password)

  client.write("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN' xmlns:ga='http://www.google.com/talk/protocol/auth' ga:client-uses-full-bind-result='true'>%s</auth>", auth.Base64())

  client.read()

  client.write("<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")

  client.read()

  client.write("<iq type='set' id='xmpp-bot1029'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>Home</resource></bind></iq>")

  client.read()
  client.read()
  client.read()

  client.Message("ratnikov@gmail.com", "Write me something and I will write back! (Please send 2 messages at first....)")

  client.read()

  for {
    raw := client.read()

    var recipient, received string

    if match := regexp.MustCompile("to=\"([^/\"]*)/").FindStringSubmatch(raw); len(match) > 1 {
      recipient = match[1]
    }

    if match := regexp.MustCompile("(.*)").FindStringSubmatch(raw); len(match) > 1 {
      received = match[1]
    }

    message := "You wrote: " + received

    fmt.Printf("Sending message %s to %s", message, recipient)

    client.Message(recipient, message)
  }

  return client, nil
}

func (client *Client) read() string {
  return read(client.conn)
}

func (client *Client) write(format string, args ...interface{}) int {
  return write(client.conn, format, args...)
}

func (client *Client) Message(recipient, msg string) {
  client.write("<message type='chat' id='xmpp-bot1029' to='%s'>%s</message>", recipient, msg)
}
<commit_msg>Extracted out authentication step.<commit_after>package xmpp;

import (
  "crypto/tls"
  "fmt"
  "os"
  "regexp"
  "net"
)

type Client struct {
  hostname string
  conn net.Conn
}

func NewClient(hostname, user, password string) (client *Client, failure os.Error) {
  failure = nil
  defer func() {
    if err := recover(); err != nil {
      client = nil

      var ok bool
      if failure, ok = err.(os.Error); !ok {
        failure = os.NewError(fmt.Sprintf("Weird error happened: %s\n", failure))
      }
    }
  }()

  client = &Client{hostname: hostname}

  client.startTls()
  client.authenticate(NewAuth(user, password))

  client.Message("ratnikov@gmail.com", "Write me something and I will write back! (Please send 2 messages at first....)")

  client.read()

  for {
    raw := client.read()

    var recipient, received string

    if match := regexp.MustCompile("to=\"([^/\"]*)/").FindStringSubmatch(raw); len(match) > 1 {
      recipient = match[1]
    }

    if match := regexp.MustCompile("(.*)").FindStringSubmatch(raw); len(match) > 1 {
      received = match[1]
    }

    message := "You wrote: " + received

    fmt.Printf("Sending message %s to %s", message, recipient)

    client.Message(recipient, message)
  }

  return client, nil
}

func (client *Client) startTls() {
  var plain_conn net.Conn
  var err os.Error

  if plain_conn, err = net.Dial("tcp", "", client.hostname + ":5222"); err != nil {
    die("Failed to establish plain connection: %s", err)
  }

  write(plain_conn, "<?xml version='1.0'?>")
  write(plain_conn, "<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")

  log("Read: %s", read(plain_conn))

  // assuming need to start tls
  write(plain_conn, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls' />")
  log("Read: %s", read(plain_conn))

  // assuming the server asked to proceed
  if client.conn, err = tls.Dial("tcp", "", client.hostname + ":https", nil); err != nil {
    die("Failed to establish tls connection (%s)", err)
  }
}

func (client *Client) authenticate(auth *Auth) {
  client.write("<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")

  // get stream response with id back
  client.read()

  // get auth mechanisms...
  client.read()

  // assuming we can do plain authentication
  client.write("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN' xmlns:ga='http://www.google.com/talk/protocol/auth' ga:client-uses-full-bind-result='true'>%s</auth>", auth.Base64())

  // get "success" response
  client.read()

  // re-start the stream
  client.write("<stream:stream to='gmail.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>")

  client.read() // get stream acknowledgement
  client.read() // get session information

  // identify as xmpp-bot1029
  client.write("<iq type='set' id='xmpp-bot1029'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>Home</resource></bind></iq>")
  client.read() // get return as to what we're bound to... or something...

  // anyhow, assuming authentication is complete
}

func (client *Client) read() string {
  msg := read(client.conn)
  log(">> " + msg)
  return msg
}

func (client *Client) write(format string, args ...interface{}) int {
  log("<< " + format, args...)
  return write(client.conn, format, args...)
}

func (client *Client) Message(recipient, msg string) {
  client.write("<message type='chat' id='xmpp-bot1029' to='%s'>%s</message>", recipient, msg)
}
<|endoftext|>