@@ -268,7 +268,7 @@ func (dbclient *CouchDatabase) CreateDatabaseIfNotExist() (*DBOperationResponse,
268
268
maxRetries := dbclient .CouchInstance .conf .MaxRetries
269
269
270
270
//process the URL with a PUT, creates the database
271
- resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodPut , connectURL .String (), nil , "" , "" , maxRetries )
271
+ resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodPut , connectURL .String (), nil , "" , "" , maxRetries , true )
272
272
if err != nil {
273
273
return nil , err
274
274
}
@@ -309,7 +309,7 @@ func (dbclient *CouchDatabase) GetDatabaseInfo() (*DBInfo, *DBReturn, error) {
309
309
//get the number of retries
310
310
maxRetries := dbclient .CouchInstance .conf .MaxRetries
311
311
312
- resp , couchDBReturn , err := dbclient .CouchInstance .handleRequest (http .MethodGet , connectURL .String (), nil , "" , "" , maxRetries )
312
+ resp , couchDBReturn , err := dbclient .CouchInstance .handleRequest (http .MethodGet , connectURL .String (), nil , "" , "" , maxRetries , true )
313
313
if err != nil {
314
314
return nil , couchDBReturn , err
315
315
}
@@ -347,7 +347,7 @@ func (couchInstance *CouchInstance) VerifyCouchConfig() (*ConnectionInfo, *DBRet
347
347
maxRetriesOnStartup := couchInstance .conf .MaxRetriesOnStartup
348
348
349
349
resp , couchDBReturn , err := couchInstance .handleRequest (http .MethodGet , connectURL .String (), nil ,
350
- couchInstance .conf .Username , couchInstance .conf .Password , maxRetriesOnStartup )
350
+ couchInstance .conf .Username , couchInstance .conf .Password , maxRetriesOnStartup , true )
351
351
352
352
if err != nil {
353
353
return nil , couchDBReturn , fmt .Errorf ("Unable to connect to CouchDB, check the hostname and port: %s" , err .Error ())
@@ -396,7 +396,7 @@ func (dbclient *CouchDatabase) DropDatabase() (*DBOperationResponse, error) {
396
396
//get the number of retries
397
397
maxRetries := dbclient .CouchInstance .conf .MaxRetries
398
398
399
- resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodDelete , connectURL .String (), nil , "" , "" , maxRetries )
399
+ resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodDelete , connectURL .String (), nil , "" , "" , maxRetries , true )
400
400
if err != nil {
401
401
return nil , err
402
402
}
@@ -436,7 +436,7 @@ func (dbclient *CouchDatabase) EnsureFullCommit() (*DBOperationResponse, error)
436
436
//get the number of retries
437
437
maxRetries := dbclient .CouchInstance .conf .MaxRetries
438
438
439
- resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodPost , connectURL .String (), nil , "" , "" , maxRetries )
439
+ resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodPost , connectURL .String (), nil , "" , "" , maxRetries , true )
440
440
if err != nil {
441
441
logger .Errorf ("Failed to invoke _ensure_full_commit Error: %s\n " , err .Error ())
442
442
return nil , err
@@ -500,6 +500,9 @@ func (dbclient *CouchDatabase) SaveDoc(id string, rev string, couchDoc *CouchDoc
500
500
//Set up a default boundary for use by multipart if sending attachments
501
501
defaultBoundary := ""
502
502
503
+ //Create a flag for shared connections. This is set to false for zero length attachments
504
+ keepConnectionOpen := true
505
+
503
506
//check to see if attachments is nil, if so, then this is a JSON only
504
507
if couchDoc .Attachments == nil {
505
508
@@ -519,6 +522,13 @@ func (dbclient *CouchDatabase) SaveDoc(id string, rev string, couchDoc *CouchDoc
519
522
return "" , err3
520
523
}
521
524
525
+ //If there is a zero length attachment, do not keep the connection open
526
+ for _ , attach := range couchDoc .Attachments {
527
+ if attach .Length < 1 {
528
+ keepConnectionOpen = false
529
+ }
530
+ }
531
+
522
532
//Set the data buffer to the data from the create multi-part data
523
533
data = multipartData .Bytes ()
524
534
@@ -531,7 +541,8 @@ func (dbclient *CouchDatabase) SaveDoc(id string, rev string, couchDoc *CouchDoc
531
541
maxRetries := dbclient .CouchInstance .conf .MaxRetries
532
542
533
543
//handle the request for saving the JSON or attachments
534
- resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodPut , saveURL .String (), data , rev , defaultBoundary , maxRetries )
544
+ resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodPut , saveURL .String (), data ,
545
+ rev , defaultBoundary , maxRetries , keepConnectionOpen )
535
546
if err != nil {
536
547
return "" , err
537
548
}
@@ -662,7 +673,7 @@ func (dbclient *CouchDatabase) ReadDoc(id string) (*CouchDoc, string, error) {
662
673
//get the number of retries
663
674
maxRetries := dbclient .CouchInstance .conf .MaxRetries
664
675
665
- resp , couchDBReturn , err := dbclient .CouchInstance .handleRequest (http .MethodGet , readURL .String (), nil , "" , "" , maxRetries )
676
+ resp , couchDBReturn , err := dbclient .CouchInstance .handleRequest (http .MethodGet , readURL .String (), nil , "" , "" , maxRetries , true )
666
677
if err != nil {
667
678
if couchDBReturn != nil && couchDBReturn .StatusCode == 404 {
668
679
logger .Debug ("Document not found (404), returning nil value instead of 404 error" )
@@ -815,7 +826,7 @@ func (dbclient *CouchDatabase) ReadDocRange(startKey, endKey string, limit, skip
815
826
//get the number of retries
816
827
maxRetries := dbclient .CouchInstance .conf .MaxRetries
817
828
818
- resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodGet , rangeURL .String (), nil , "" , "" , maxRetries )
829
+ resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodGet , rangeURL .String (), nil , "" , "" , maxRetries , true )
819
830
if err != nil {
820
831
return nil , err
821
832
}
@@ -913,7 +924,7 @@ func (dbclient *CouchDatabase) DeleteDoc(id, rev string) error {
913
924
//get the number of retries
914
925
maxRetries := dbclient .CouchInstance .conf .MaxRetries
915
926
916
- resp , couchDBReturn , err := dbclient .CouchInstance .handleRequest (http .MethodDelete , deleteURL .String (), nil , rev , "" , maxRetries )
927
+ resp , couchDBReturn , err := dbclient .CouchInstance .handleRequest (http .MethodDelete , deleteURL .String (), nil , rev , "" , maxRetries , true )
917
928
if err != nil {
918
929
fmt .Printf ("couchDBReturn=%v" , couchDBReturn )
919
930
if couchDBReturn != nil && couchDBReturn .StatusCode == 404 {
@@ -950,7 +961,7 @@ func (dbclient *CouchDatabase) QueryDocuments(query string) (*[]QueryResult, err
950
961
//get the number of retries
951
962
maxRetries := dbclient .CouchInstance .conf .MaxRetries
952
963
953
- resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodPost , queryURL .String (), []byte (query ), "" , "" , maxRetries )
964
+ resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodPost , queryURL .String (), []byte (query ), "" , "" , maxRetries , true )
954
965
if err != nil {
955
966
return nil , err
956
967
}
@@ -1036,7 +1047,7 @@ func (dbclient *CouchDatabase) BatchRetrieveIDRevision(keys []string) ([]*DocMet
1036
1047
//get the number of retries
1037
1048
maxRetries := dbclient .CouchInstance .conf .MaxRetries
1038
1049
1039
- resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodPost , batchURL .String (), jsonKeys , "" , "" , maxRetries )
1050
+ resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodPost , batchURL .String (), jsonKeys , "" , "" , maxRetries , true )
1040
1051
if err != nil {
1041
1052
return nil , err
1042
1053
}
@@ -1131,7 +1142,7 @@ func (dbclient *CouchDatabase) BatchUpdateDocuments(documents []*CouchDoc) ([]*B
1131
1142
//get the number of retries
1132
1143
maxRetries := dbclient .CouchInstance .conf .MaxRetries
1133
1144
1134
- resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodPost , batchURL .String (), jsonKeys , "" , "" , maxRetries )
1145
+ resp , _ , err := dbclient .CouchInstance .handleRequest (http .MethodPost , batchURL .String (), jsonKeys , "" , "" , maxRetries , true )
1135
1146
if err != nil {
1136
1147
return nil , err
1137
1148
}
@@ -1166,7 +1177,7 @@ func (dbclient *CouchDatabase) BatchUpdateDocuments(documents []*CouchDoc) ([]*B
1166
1177
// if it returns an error, it ensures that the response body is closed, else it is the
1167
1178
// callee's responsibility to close response correctly
1168
1179
func (couchInstance * CouchInstance ) handleRequest (method , connectURL string , data []byte , rev string ,
1169
- multipartBoundary string , maxRetries int ) (* http.Response , * DBReturn , error ) {
1180
+ multipartBoundary string , maxRetries int , keepConnectionOpen bool ) (* http.Response , * DBReturn , error ) {
1170
1181
1171
1182
logger .Debugf ("Entering handleRequest() method=%s url=%v" , method , connectURL )
1172
1183
@@ -1192,6 +1203,13 @@ func (couchInstance *CouchInstance) handleRequest(method, connectURL string, dat
1192
1203
return nil , nil , err
1193
1204
}
1194
1205
1206
+ //set the request to close on completion if shared connections are not allowSharedConnection
1207
+ //Current CouchDB has a problem with zero length attachments, do not allow the connection to be reused.
1208
+ //Apache JIRA item for CouchDB https://issues.apache.org/jira/browse/COUCHDB-3394
1209
+ if ! keepConnectionOpen {
1210
+ req .Close = true
1211
+ }
1212
+
1195
1213
//add content header for PUT
1196
1214
if method == http .MethodPut || method == http .MethodPost || method == http .MethodDelete {
1197
1215
0 commit comments