couchdb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Samuel Tardieu (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (COUCHDB-2583) ensure_full_commit requires empty but typed content or it will unexpectedly drops the connection
Date Mon, 16 Feb 2015 12:44:12 GMT

    [ https://issues.apache.org/jira/browse/COUCHDB-2583?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14322718#comment-14322718
] 

Samuel Tardieu commented on COUCHDB-2583:
-----------------------------------------

Concerning the content-type for the empty content, I understand your point for the general
situation, but in the {{application/json}} case, the empty string is not a valid JSON representation
(while it would be for `application/x-www-form-urlencoded` since an empty string would represent
the empty JSON object). One could object that if a content-type is present, a value of said
content should be parsable (even if it is from the empty string, which is not possible in
the JSON case).

I run the following code (which I created to try to test the issue). Note that the local server
has an {{admin:admin}} administrator set, remove the {{Authorization}} line to check on an
admin-party server.

{code:title=test.py}
#! /usr/bin/python
#

from socket import *

s = socket(AF_INET, SOCK_STREAM)
s.connect(('localhost',5984))
headers = """Host: localhost:5984
Authorization: Basic YWRtaW46YWRtaW4=
Accept: application/json"""
request = """PUT /testdb1 HTTP/1.1
%(headers)s
Content-Length: 0

PUT /testdb2 HTTP/1.1
%(headers)s
Content-Length: 0

POST /testdb1/_ensure_full_commit HTTP/1.1
%(headers)s
Content-Type: application/json
Content-Length: 2

{}

PUT /testdb3 HTTP/1.1
%(headers)s
Content-Length: 0

""" % {"headers": headers}
s.send(request)

while True:
    p = s.recv(1500)
    if not p:
        break
    print(p)
{code}

When run against my 1.6.1 server, I get:

{code:title=Output}
HTTP/1.1 412 Precondition Failed
Server: CouchDB/1.6.1 (Erlang OTP/17)
Date: Mon, 16 Feb 2015 12:34:27 GMT
Content-Type: application/json
Content-Length: 95
Cache-Control: must-revalidate

{"error":"file_exists","reason":"The database could not be created, the file already exists."}

HTTP/1.1 412 Precondition Failed
Server: CouchDB/1.6.1 (Erlang OTP/17)
Date: Mon, 16 Feb 2015 12:34:27 GMT
Content-Type: application/json
Content-Length: 95
Cache-Control: must-revalidate

{"error":"file_exists","reason":"The database could not be created, the file already exists."}

HTTP/1.1 201 Created
Server: CouchDB/1.6.1 (Erlang OTP/17)
Date: Mon, 16 Feb 2015 12:34:27 GMT
Content-Type: application/json
Content-Length: 53
Cache-Control: must-revalidate

{"ok":true,"instance_start_time":"1424085277160411"}

{code}
[and the test program exits because the connection has been closed from the server side]

Note that the connection is dropped after the result from the {{_ensure_full_commit}} method
call. If I change the call to use {{Content-Length: 0}} (instead of 2) and remove the empty
JSON object, I get:

{code:title=Alternative}
HTTP/1.1 412 Precondition Failed
Server: CouchDB/1.6.1 (Erlang OTP/17)
Date: Mon, 16 Feb 2015 12:36:36 GMT
Content-Type: application/json
Content-Length: 95
Cache-Control: must-revalidate

{"error":"file_exists","reason":"The database could not be created, the file already exists."}

HTTP/1.1 412 Precondition Failed
Server: CouchDB/1.6.1 (Erlang OTP/17)
Date: Mon, 16 Feb 2015 12:36:36 GMT
Content-Type: application/json
Content-Length: 95
Cache-Control: must-revalidate

{"error":"file_exists","reason":"The database could not be created, the file already exists."}

HTTP/1.1 201 Created
Server: CouchDB/1.6.1 (Erlang OTP/17)
Date: Mon, 16 Feb 2015 12:36:36 GMT
Content-Type: application/json
Content-Length: 53
Cache-Control: must-revalidate

{"ok":true,"instance_start_time":"1424085277160411"}
HTTP/1.1 412 Precondition Failed
Server: CouchDB/1.6.1 (Erlang OTP/17)
Date: Mon, 16 Feb 2015 12:36:36 GMT
Content-Type: application/json
Content-Length: 95
Cache-Control: must-revalidate

{"error":"file_exists","reason":"The database could not be created, the file already exists."}

{code}

and the program hangs there because the connection is still not dropped (as expected) and
is waiting for the next command.

> ensure_full_commit requires empty but typed content or it will unexpectedly drops the
connection
> ------------------------------------------------------------------------------------------------
>
>                 Key: COUCHDB-2583
>                 URL: https://issues.apache.org/jira/browse/COUCHDB-2583
>             Project: CouchDB
>          Issue Type: Bug
>      Security Level: public(Regular issues) 
>          Components: HTTP Interface
>    Affects Versions: 1.6.1
>            Reporter: Samuel Tardieu
>
> When given an non-empty (but valid) JSON content, some methods such as {{_ensure_full_commit}}
will abruptly drop a persistent connection instead of waiting for a new HTTP request even
though no error is signaled in CouchDB logs:
> {code:title=Request}
> POST /testdb1/_ensure_full_commit HTTP/1.1
> Host: localhost:5984
> Accept: application/json
> Content-Type: application/json
> Content-Length: 2
> {}
> {code}
> {code:title=Response}
> HTTP/1.1 201 Created
> Server: CouchDB/1.6.1 (Erlang OTP/17)
> Date: Mon, 16 Feb 2015 11:49:11 GMT
> Content-Type: application/json
> Content-Length: 53
> Cache-Control: must-revalidate
> {"ok":true,"instance_start_time":"1424085277160411"}
> {code}
> [connection is closed without warning by CouchDB at this point]
> To remedy that, one could try to give an empty content, but some frameworks (such as
spray.io) will systematically omit the {{Content-Type}} header in this case since it makes
little sense to type empty content. However, CouchDB will reject the request even though it
does *not* want any content:
> {code:title=Request}
> POST /testdb1/_ensure_full_commit HTTP/1.1
> Host: localhost:5984
> Accept: application/json
> Content-Length: 0
> {code}
> {code:title=Response}
> HTTP/1.1 415 Unsupported Media Type
> Server: CouchDB/1.6.1 (Erlang OTP/17)
> Date: Mon, 16 Feb 2015 11:55:52 GMT
> Content-Type: application/json
> Content-Length: 78
> Cache-Control: must-revalidate
> {"error":"bad_content_type","reason":"Content-Type must be application/json"}
> {code}
> This makes it impossible to use those methods with such frameworks. CouchDB should not
drop the connection and ignore the data if {{Content-Length}} is not 0, nor require that data
be typed with {{application/json}} if it is going to ignore it anyway or if it requires it
to be empty.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message