+static void
+curl_handle_finished (struct Plugin *plugin)
+{
+ struct Session *ps = NULL;
+ struct HTTP_PeerContext *pc = NULL;
+ struct CURLMsg *msg;
+ struct HTTP_Message * cur_msg = NULL;
+ int msgs_in_queue;
+ char * tmp;
+ long http_result;
+
+ do
+ {
+ msg = curl_multi_info_read (plugin->multi_handle, &msgs_in_queue);
+ if ((msgs_in_queue == 0) || (msg == NULL))
+ break;
+ /* get session for affected curl handle */
+ GNUNET_assert ( msg->easy_handle != NULL );
+ curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &tmp);
+ ps = (struct Session *) tmp;
+ GNUNET_assert ( ps != NULL );
+ pc = ps->peercontext;
+ GNUNET_assert ( pc != NULL );
+ switch (msg->msg)
+ {
+ case CURLMSG_DONE:
+ if ( (msg->data.result != CURLE_OK) &&
+ (msg->data.result != CURLE_GOT_NOTHING) )
+ {
+ /* sending msg failed*/
+ if (msg->easy_handle == ps->send_endpoint)
+ {
+#if DEBUG_CONNECTIONS
+ GNUNET_log(GNUNET_ERROR_TYPE_INFO,
+ _("Connection %X: HTTP PUT to peer `%s' (`%s') failed: `%s' `%s'\n"),
+ ps,
+ GNUNET_i2s(&pc->identity),
+ http_plugin_address_to_string(NULL, ps->addr, ps->addrlen),
+ "curl_multi_perform",
+ curl_easy_strerror (msg->data.result));
+#endif
+ ps->send_connected = GNUNET_NO;
+ ps->send_active = GNUNET_NO;
+ curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint);
+ while (ps->pending_msgs_tail != NULL)
+ {
+ cur_msg = ps->pending_msgs_tail;
+ if ( NULL != cur_msg->transmit_cont)
+ cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR);
+ ps->queue_length_cur -= cur_msg->size;
+ remove_http_message(ps,cur_msg);
+ }
+ }
+ /* GET connection failed */
+ if (msg->easy_handle == ps->recv_endpoint)
+ {
+#if DEBUG_CONNECTIONS
+ GNUNET_log(GNUNET_ERROR_TYPE_INFO,
+ _("Connection %X: HTTP GET to peer `%s' (`%s') failed: `%s' `%s'\n"),
+ ps,
+ GNUNET_i2s(&pc->identity),
+ http_plugin_address_to_string(NULL, ps->addr, ps->addrlen),
+ "curl_multi_perform",
+ curl_easy_strerror (msg->data.result));
+#endif
+ ps->recv_connected = GNUNET_NO;
+ ps->recv_active = GNUNET_NO;
+ curl_multi_remove_handle(plugin->multi_handle,ps->recv_endpoint);
+ }
+ }
+ else
+ {
+ if (msg->easy_handle == ps->send_endpoint)
+ {
+ GNUNET_assert (CURLE_OK == curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &http_result));
+#if DEBUG_CONNECTIONS
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Connection %X: HTTP PUT connection to peer `%s' (`%s') was closed with HTTP code %u\n",
+ ps,
+ GNUNET_i2s(&pc->identity),
+ http_plugin_address_to_string(NULL, ps->addr, ps->addrlen),
+ http_result);
+#endif
+ /* Calling transmit continuation */
+ while (ps->pending_msgs_tail != NULL)
+ {
+ cur_msg = ps->pending_msgs_tail;
+ if ( NULL != cur_msg->transmit_cont)
+ {
+ /* HTTP 1xx : Last message before here was informational */
+ if ((http_result >=100) && (http_result < 200))
+ cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK);
+ /* HTTP 2xx: successful operations */
+ if ((http_result >=200) && (http_result < 300))
+ cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK);
+ /* HTTP 3xx..5xx: error */
+ if ((http_result >=300) && (http_result < 600))
+ cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR);
+ }
+ ps->queue_length_cur -= cur_msg->size;
+ remove_http_message(ps,cur_msg);
+ }
+
+ ps->send_connected = GNUNET_NO;
+ ps->send_active = GNUNET_NO;
+ curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint);
+ }
+ if (msg->easy_handle == ps->recv_endpoint)
+ {
+#if DEBUG_CONNECTIONS
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Connection %X: HTTP GET connection to peer `%s' (`%s') was closed with HTTP code %u\n",
+ ps,
+ GNUNET_i2s(&pc->identity),
+ http_plugin_address_to_string(NULL, ps->addr, ps->addrlen),
+ http_result);
+#endif
+ ps->recv_connected = GNUNET_NO;
+ ps->recv_active = GNUNET_NO;
+ curl_multi_remove_handle(plugin->multi_handle,ps->recv_endpoint);
+ }
+ plugin->current_connections--;
+ }
+ if ((ps->recv_connected == GNUNET_NO) && (ps->send_connected == GNUNET_NO))
+ remove_session (pc, ps, GNUNET_YES, GNUNET_SYSERR);
+ break;
+ default:
+ break;
+ }
+ }
+ while ( (msgs_in_queue > 0) );