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

Document IDs containing / are unretrievable #268

Closed
DRK3 opened this issue Jan 11, 2021 · 7 comments · Fixed by #269 or #270
Closed

Document IDs containing / are unretrievable #268

DRK3 opened this issue Jan 11, 2021 · 7 comments · Fixed by #269 or #270

Comments

@DRK3
Copy link

DRK3 commented Jan 11, 2021

If you store a document with an ID that contains one or more / characters, then it won't be retrievable later with the same ID.

To replicate: put a document under ID https://example.com, then try to retrieve it later. You'll get an error after doing row.ScanDoc telling you that it's missing.

Note: This works correctly in v2.0.0. but not in v3 or v4. I used CouchDB v3.1.0.

It looks like an issue with the URL encoding. From the CouchDB logs, it looks like Kivik v2 converts https://example.com to https%3A%2F%2Fexample.com for both Put and Get requests. In Kivik v3 and newer, https://example.com gets converted to https:%2F%2Fexample.com for the Put, but for the Get it converts it to https:%252F%252Fexample.com which does not URL decode back to the original document ID.

Let me know if I can provide any more info. Thanks!

@DRK3 DRK3 changed the title Issue with document IDs containing / Document IDs containing / are unretrievable Jan 11, 2021
@DRK3
Copy link
Author

DRK3 commented Jan 11, 2021

Note: other special characters like % are also affected

@flimzy
Copy link
Member

flimzy commented Jan 15, 2021

Thanks for the report! I'll try to get to this as quickly as I can. In the meantime, if this is urgent, and you're so inclined, feel free to submit a PR.

@flimzy flimzy added the bug label Jan 15, 2021
@flimzy
Copy link
Member

flimzy commented Jan 15, 2021

I'm not able to reproduce the behavior you've described. When passing https://example.com/ to Get(), the encoding appears to be correct.

Is it possible that you could create minimal code to reproduce the error condition?

@DRK3
Copy link
Author

DRK3 commented Jan 18, 2021

Hi @flimzy,

Sure - try this code:

package couchdb_test

import (
	"context"
	"testing"

	_ "github.com/go-kivik/couchdb/v3"
	"github.com/go-kivik/kivik/v3"
)

func TestKivik(t *testing.T) {
	// No error!
	err := PutThenGet("testdb1", "someDocumentID")
	if err != nil {
		println(err.Error())
		t.Fail()
	}

	// Produces a "Not Found: missing" error with v3...
	// ...but if you change the imports to _ "github.com/go-kivik/couchdb" and "github.com/go-kivik/kivik" then it works!
	err = PutThenGet("testdb2", "https://example.com")
	if err != nil {
		println(err.Error())
		t.Fail()
	}
}

func PutThenGet(dbName, docID string) error {
	client, err := kivik.New("couch", "admin:password@localhost:5984")
	if err != nil {
		return err
	}

	err = client.CreateDB(context.Background(), dbName)
	if err != nil {
		return err
	}

	db := client.DB(context.Background(), dbName)
	err = db.Err()
	if err != nil {
		return err
	}

	_, err = db.Put(context.Background(), docID, []byte(`{"JSONKey":"JSONValue"}`))
	if err != nil {
		return err
	}

	row := db.Get(context.Background(), docID)

	document := make(map[string]interface{})

	err = row.ScanDoc(&document)
	if err != nil {
		return err
	}

	return nil
}

@flimzy
Copy link
Member

flimzy commented Jan 26, 2021

Thank you very much! And my apologies for the delay in responding. A fix is forthcoming.

@flimzy
Copy link
Member

flimzy commented Jan 26, 2021

v3.2.6 should fix this. Please let me know if you discover this not to be the case!

@DRK3
Copy link
Author

DRK3 commented Feb 5, 2021

@flimzy Sorry for the slow response! It works for me too. Thanks for all the hard work!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants