Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XL/fs: Internal Server Error for PutObject with a name longer than 255 bytes #1501

Closed
hnakamur opened this issue May 6, 2016 · 2 comments
Closed
Assignees
Milestone

Comments

@hnakamur
Copy link

hnakamur commented May 6, 2016

First of all, thanks for sharing a great software!

I tested putting an object with a name longer than 255 bytes.
Then it took about 20 seconds to get the results and the error
was "500 Internal Server Error".

I believe another error should be defined in minio/api-errors.go and the server returns it immediately.

My test environment:

$ go version
go version go1.6.2 linux/amd64
$ cd $GOPATH/src/github.com/minio/minio && git rev-parse HEAD
e4d89d8156927b2c60f5e719a78f0750a270f540

I tested with the following code.

package main

import (
    "bytes"
    "encoding/json"
    "io/ioutil"
    "os"
    "os/exec"
    "path/filepath"
    "strings"
    "testing"
    "time"

    "github.com/minio/minio-go"
)

func startMinio(addr, configDir, storageDir string) (*exec.Cmd, error) {
    err := os.MkdirAll(configDir, 0700)
    if err != nil {
        return nil, err
    }
    err = os.MkdirAll(storageDir, 0700)
    if err != nil {
        return nil, err
    }
    cmd := exec.Command("minio", "--config-dir", configDir, "server", "--address", addr, storageDir)
    err = cmd.Start()

    // NOTE: We need to wait some time for clients to work properly.
    // If clients connect to the server too soon, I got the
    // "The access key ID you provided does not exist in our records." error
    // when I call APIs like ListBuckets or MakeBucket
    time.Sleep(time.Second)

    return cmd, err
}

func stopMinio(cmd *exec.Cmd) error {
    return cmd.Process.Kill()
}

type Config struct {
    Credential Credential `json:"credential"`
    Region     string     `json:"region"`
}

type Credential struct {
    AccessKey string `json:"accessKey"`
    SecretKey string `json:"secretKey"`
}

func readConfig(configDir string) (config Config, err error) {
    configPath := filepath.Join(configDir, "config.json")
    file, err := os.Open(configPath)
    if err != nil {
        return
    }
    defer file.Close()

    decoder := json.NewDecoder(file)
    err = decoder.Decode(&config)
    return
}

func startMinioForTest(t *testing.T, addr string) (cmd *exec.Cmd, baseDir string, config Config, err error) {
    baseDir, err = ioutil.TempDir("", "minio-test")
    if err != nil {
        return
    }
    t.Logf("startMinioForTest created baseDir=%s", baseDir)

    configDir := filepath.Join(baseDir, "config")
    storageDir := filepath.Join(baseDir, "storage")
    cmd, err = startMinio(addr, configDir, storageDir)
    if err != nil {
        return
    }
    t.Logf("startMinioForTest started minio server. pid=%d, listenAddr=%s", cmd.Process.Pid, addr)
    config, err = readConfig(configDir)
    return
}

func stopMinioForTest(t *testing.T, addr string, cmd *exec.Cmd, baseDir string) {
    err := stopMinio(cmd)
    if err != nil {
        t.Errorf("failed to stop minio server with pid=%d, listenAddress=%s", cmd.Process.Pid, addr)
    }
    t.Logf("stopMinioForTest stopped minio server with pid=%d, listenAddress=%s", cmd.Process.Pid, addr)
    err = os.RemoveAll(baseDir)
    if err != nil {
        t.Errorf("failed to remove directory %s: err=%s", baseDir, err)
    }
    t.Logf("stopMinioForTest removed baseDir=%s", baseDir)
}

func newClient(addr string, config Config) (*minio.Client, error) {
    return minio.New(addr, config.Credential.AccessKey, config.Credential.SecretKey, true)
}

const listenAddr = "127.0.0.1:19999"

func TestPutAndTextFileWithTooLongDirName(t *testing.T) {
    cmd, baseDir, config, err := startMinioForTest(t, listenAddr)
    if err != nil {
        t.Fatal(err)
    }
    defer stopMinioForTest(t, listenAddr, cmd, baseDir)

    client, err := newClient(listenAddr, config)
    if err != nil {
        t.Error(err)
    }

    bucketName := "bucket1.example.com"
    err = client.MakeBucket(bucketName, config.Region)
    if err != nil {
        t.Error(err)
    }

    objectName := strings.Repeat("a", 256)
    contentType := "text/plain"
    var buf bytes.Buffer
    content := "hello world\ngoodbye world\n"
    buf.WriteString(content)
    _, err = client.PutObject(bucketName, objectName, &buf, contentType)
    if err == nil {
        t.Error("should have an error")
    }
    // NOTE: This error should not be "500 Internal Server Error"
    wantedError := "500 Internal Server Error"
    if err.Error() != wantedError {
        t.Errorf("unexpected error, got %s; want %s", err.Error(), wantedError)
    }
}
@harshavardhana
Copy link
Member

I tested putting an object with a name longer than 255 bytes.
Then it took about 20 seconds to get the results and the error
was "500 Internal Server Error".

I believe another error should be defined in minio/api-errors.go and the server returns it immediately.

My test environment:

$ go version
go version go1.6.2 linux/amd64
$ cd $GOPATH/src/github.com/minio/minio && git rev-parse HEAD
e4d89d8

Thanks for the kind words! - "Internal Server Error" is retried on client side i.e minio-go, so perhaps that is the reason it must have waited for long.

Name longer than 255Bytes perhaps would be the result of filesystem replying a message based on the file path length. Will incorporate your test script thanks for reproducing this issue for us.

@harshavardhana harshavardhana added this to the XL Standalone milestone May 6, 2016
balamurugana added a commit to balamurugana/minio that referenced this issue May 7, 2016
When errFileNameTooLong error is returned from posix, xl.CreateFile()
treats the error specially by returning the same error immediately.

Fixes minio#1501
balamurugana added a commit to balamurugana/minio that referenced this issue May 8, 2016
When errFileNameTooLong error is returned from posix, xl.CreateFile()
treats the error specially by returning the same error immediately.

Fixes minio#1501
balamurugana added a commit to balamurugana/minio that referenced this issue May 8, 2016
When errFileNameTooLong error is returned from posix, xl.CreateFile()
treats the error specially by returning the same error immediately.

Fixes minio#1501
balamurugana added a commit to balamurugana/minio that referenced this issue May 8, 2016
When errFileNameTooLong error is returned from posix, xl.CreateFile()
treats the error specially by returning the same error immediately.

Fixes minio#1501
@harshavardhana harshavardhana changed the title Internet Server Error for PutObject with a name longer than 255 bytes Internal Server Error for PutObject with a name longer than 255 bytes May 11, 2016
@harshavardhana harshavardhana changed the title Internal Server Error for PutObject with a name longer than 255 bytes server: Internal Server Error for PutObject with a name longer than 255 bytes May 11, 2016
@harshavardhana harshavardhana changed the title server: Internal Server Error for PutObject with a name longer than 255 bytes XL/fs: Internal Server Error for PutObject with a name longer than 255 bytes May 11, 2016
balamurugana added a commit to balamurugana/minio that referenced this issue May 11, 2016
When errFileNameTooLong error is returned from posix, xl.CreateFile()
treats the error specially by returning the same error immediately.

Fixes minio#1501
@balamurugana
Copy link
Member

See also golang/go#3358

harshavardhana pushed a commit that referenced this issue May 11, 2016
When errFileNameTooLong error is returned from posix, xl.CreateFile()
treats the error specially by returning the same error immediately.

Fixes #1501
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 21, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants