Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Http 来自Go to CouchDB的大型PUT请求_Http_Go_Couchdb - Fatal编程技术网

Http 来自Go to CouchDB的大型PUT请求

Http 来自Go to CouchDB的大型PUT请求,http,go,couchdb,Http,Go,Couchdb,我和CouchDB和Golang之间一直有个棘手的问题。当发送POST/PUT请求到具有相对较大正文大小(阈值似乎约为8000字节)的CouchDB时,连接超时,我从Go收到一个“tcp:use of closed network connection”错误 最终(一两秒钟后),CouchDB会发送一个500响应和一个: {"error":"unknown_error", "reason": "noproc"} 在身体里。couchdb日志中还写入了堆栈跟踪: Stacktrace: [{co

我和CouchDB和Golang之间一直有个棘手的问题。当发送POST/PUT请求到具有相对较大正文大小(阈值似乎约为8000字节)的CouchDB时,连接超时,我从Go收到一个“tcp:use of closed network connection”错误

最终(一两秒钟后),CouchDB会发送一个500响应和一个:

{"error":"unknown_error", "reason": "noproc"}
在身体里。couchdb日志中还写入了堆栈跟踪:

Stacktrace: [{couch_db,collect_results,3,
                [{file,"couch_db.erl"},{line,833}]},
             {couch_db,write_and_commit,4,
                [{file,"couch_db.erl"},{line,845}]},
             {couch_db,update_docs,4,
                [{file,"couch_db.erl"},{line,782}]},
             {couch_db,update_doc,4,
                [{file,"couch_db.erl"},{line,426}]},
             {couch_httpd_db,update_doc,6,
                [{file,"couch_httpd_db.erl"},{line,753}]},
             {couch_httpd_db,do_db_req,2,
                [{file,"couch_httpd_db.erl"},{line,234}]},
             {couch_httpd,handle_request_int,5,
                [{file,"couch_httpd.erl"},{line,318}]},
             {mochiweb_http,headers,5,
                [{file,"mochiweb_http.erl"},{line,94}]}]
因此,我编写了一个快速单元测试来复制这个问题(并确保问题不是由我的包装造成的)。我是这样提出请求的:

client := &http.Client{}
req, err := http.NewRequest(
    "PUT",
    "http://localhost:5984/unittestdb/testdocid1",
    bytes.NewReader(testBody1), //testBody1 is 10000 bytes of json object
)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
resp, err := client.Do(req)
这重复了这个问题。。。因此,我尝试将一个大型json文档卷曲到couchdb。成功了

因此,我启动了wireshark,检查了我的代码向CouchDB发出的请求,并将其与curl发送的请求进行了比较。我注意到Curl请求中增加了一个标题:

Expect: 100-continue
我必须查一下那个头球,因为我想不起来以前见过(或者我只是不需要处理)那个头球。然后我在google上搜索Golang http客户端是否支持Expect/Continue功能,结果发现:

所以Go不支持它,至少在1.6之前不会支持它。所以我认为这一定是一件晦涩难懂的事情,不是我问题的根源。我花了几个小时随机尝试了http、客户端、传输等其他东西

最后,我在Go中手动设置http请求中的“Expect:100 continue”头(如果正文大小超过某个大小),然后。。。成功了。没有超时,没有错误,没有couchdb将堆栈跟踪加载到日志中

现在我很困惑,如果Go不支持这个,它是如何工作的?我这样做只是为了掩盖问题吗?还是我可以耸耸肩继续前行


我怀疑CouchDB方面存在问题,也许我缺少一个配置设置?

我不知道答案,但我认为您的关键规范是。整个部分都很有趣,但特别是:

“此规则有一个例外:为了与RFC 2068兼容, 服务器可以发送100(继续)状态以响应HTTP/1.1 不包含Expect请求标头的PUT或POST请求 字段中包含“100 continue”期望值。此异常为 其中之一是最大限度地减少与 未声明的等待100(继续)状态仅适用于HTTP/1.1 请求,而不是具有任何其他HTTP版本值的请求。“

这听起来像是你被夹在Go缺少的100 continue实现和CouchDB端的一些角落案例之间。(无论客户端的行为如何,我认为500内部错误都不是来自服务器的适当响应。)


如果Go客户端允许您设置,我会尝试使用HTTP/1.0作为解决方法。

如果CouchDB“将堆栈跟踪添加到日志中”,那么您应该将它们添加到问题中。好的,添加了堆栈跟踪。如果重要的话,我正在FreeBSD 10.1:)上运行CouchDB 1.6.1和Go 1.4.1。不幸的是,Go客户端请求总是使用HTTP/1.1