66
77#include < Poco/Exception.h>
88#include < Poco/Net/HTTPClientSession.h>
9+ #if !defined(WORKAROUND_DISABLE_SSL)
10+ #include < Poco/Net/HTTPSClientSession.h>
11+ #endif
912#include < Poco/Net/HTTPRequest.h>
1013#include < Poco/Timezone.h>
1114#include < Poco/URI.h>
@@ -19,6 +22,29 @@ Statement::Statement(Connection & connection)
1922 : ChildType(connection)
2023{
2124 allocateImplicitDescriptors ();
25+
26+ // Create independent HTTP session for this statement to avoid concurrent access issues
27+ auto & conn = getParent ();
28+
29+ #if !defined(WORKAROUND_DISABLE_SSL)
30+ const auto is_ssl = (Poco::UTF8::icompare (conn.getProto (), " https" ) == 0 );
31+ statement_session = (
32+ is_ssl ? std::make_unique<Poco::Net::HTTPSClientSession>() :
33+ std::make_unique<Poco::Net::HTTPClientSession>()
34+ );
35+ #else
36+ statement_session = std::make_unique<Poco::Net::HTTPClientSession>();
37+ #endif
38+
39+ statement_session->setHost (conn.getServer ());
40+ statement_session->setPort (conn.getPort ());
41+ statement_session->setKeepAlive (true );
42+ statement_session->setTimeout (
43+ Poco::Timespan (conn.getConnectionTimeout (), 0 ),
44+ Poco::Timespan (conn.getTimeout (), 0 ),
45+ Poco::Timespan (conn.getTimeout (), 0 )
46+ );
47+ statement_session->setKeepAliveTimeout (Poco::Timespan (86400 , 0 ));
2248}
2349
2450Statement::~Statement () {
@@ -108,9 +134,9 @@ void Statement::requestNextPackOfResultSets(std::unique_ptr<ResultMutator> && mu
108134
109135 auto & connection = getParent ();
110136
111- if (connection. session && response && in)
137+ if (statement_session && response && in)
112138 if (in->fail () || !in->eof ())
113- connection. session ->reset ();
139+ statement_session ->reset ();
114140
115141 const auto [prepared_query, query_parameters] = prepareHttpRequest ();
116142 Poco::URI uri = connection.getUri ();
@@ -142,25 +168,25 @@ void Statement::requestNextPackOfResultSets(std::unique_ptr<ResultMutator> && mu
142168 for (int i = 1 ;; ++i) {
143169 try {
144170 for (; redirect_count < connection.redirect_limit ; ++redirect_count) {
145- connection. session ->sendRequest (request) << prepared_query;
171+ statement_session ->sendRequest (request) << prepared_query;
146172 response = std::make_unique<Poco::Net::HTTPResponse>();
147- in = &connection. session ->receiveResponse (*response);
173+ in = &statement_session ->receiveResponse (*response);
148174 auto status = response->getStatus ();
149175 if (status != Poco::Net::HTTPResponse::HTTP_PERMANENT_REDIRECT && status != Poco::Net::HTTPResponse::HTTP_TEMPORARY_REDIRECT) {
150176 break ;
151177 }
152- connection. session ->reset (); // reset keepalived connection
178+ statement_session ->reset (); // reset keepalived connection
153179 auto newLocation = response->get (" Location" );
154180 LOG (" Redirected to " << newLocation << " , redirect index=" << redirect_count + 1 << " /" << connection.redirect_limit );
155181 uri = newLocation;
156- connection. session ->setHost (uri.getHost ());
157- connection. session ->setPort (uri.getPort ());
182+ statement_session ->setHost (uri.getHost ());
183+ statement_session ->setPort (uri.getPort ());
158184 request.setHost (uri.getHost ());
159185 request.setURI (uri.getPathEtc ());
160186 }
161187 break ;
162188 } catch (const Poco::IOException & e) {
163- connection. session ->reset (); // reset keepalived connection
189+ statement_session ->reset (); // reset keepalived connection
164190 LOG (" Http request try=" << i << " /" << connection.retry_count << " failed: " << e.what () << " : " << e.message ());
165191 if (i > connection.retry_count )
166192 throw ;
@@ -376,9 +402,9 @@ bool Statement::advanceToNextResultSet() {
376402
377403void Statement::closeCursor () {
378404 auto & connection = getParent ();
379- if (connection. session && response && in) {
405+ if (statement_session && response && in) {
380406 if (in->fail () || !in->eof ())
381- connection. session ->reset ();
407+ statement_session ->reset ();
382408 }
383409
384410 result_reader.reset ();
0 commit comments