Commit 8e7e210a authored by Ghislain MARY's avatar Ghislain MARY

Implement cancellation of HTTP requests.

parent 3cdbbd91
...@@ -35,6 +35,9 @@ BELLESIP_EXPORT belle_http_request_t *belle_http_request_create(const char *meth ...@@ -35,6 +35,9 @@ BELLESIP_EXPORT belle_http_request_t *belle_http_request_create(const char *meth
BELLESIP_EXPORT belle_http_request_t* belle_http_request_new(); BELLESIP_EXPORT belle_http_request_t* belle_http_request_new();
BELLESIP_EXPORT belle_http_request_t* belle_http_request_parse(const char* raw); BELLESIP_EXPORT belle_http_request_t* belle_http_request_parse(const char* raw);
BELLESIP_EXPORT int belle_http_request_is_cancelled(const belle_http_request_t *req);
BELLESIP_EXPORT void belle_http_request_cancel(belle_http_request_t *req);
BELLESIP_EXPORT belle_generic_uri_t* belle_http_request_get_uri(const belle_http_request_t* request); BELLESIP_EXPORT belle_generic_uri_t* belle_http_request_get_uri(const belle_http_request_t* request);
BELLESIP_EXPORT void belle_http_request_set_uri(belle_http_request_t* request, belle_generic_uri_t* uri); BELLESIP_EXPORT void belle_http_request_set_uri(belle_http_request_t* request, belle_generic_uri_t* uri);
BELLESIP_EXPORT const char* belle_http_request_get_method(const belle_http_request_t* request); BELLESIP_EXPORT const char* belle_http_request_get_method(const belle_http_request_t* request);
......
...@@ -29,6 +29,8 @@ BELLESIP_EXPORT int belle_http_provider_set_tls_verify_policy(belle_http_provide ...@@ -29,6 +29,8 @@ BELLESIP_EXPORT int belle_http_provider_set_tls_verify_policy(belle_http_provide
BELLESIP_EXPORT int belle_http_provider_send_request(belle_http_provider_t *obj, belle_http_request_t *req, belle_http_request_listener_t *listener); BELLESIP_EXPORT int belle_http_provider_send_request(belle_http_provider_t *obj, belle_http_request_t *req, belle_http_request_listener_t *listener);
BELLESIP_EXPORT void belle_http_provider_cancel_request(belle_http_provider_t *obj, belle_http_request_t *req);
BELLE_SIP_END_DECLS BELLE_SIP_END_DECLS
#endif #endif
...@@ -616,8 +616,10 @@ struct belle_http_request{ ...@@ -616,8 +616,10 @@ struct belle_http_request{
belle_http_request_listener_t *listener; belle_http_request_listener_t *listener;
belle_generic_uri_t *orig_uri;/*original uri before removing host and user/passwd*/ belle_generic_uri_t *orig_uri;/*original uri before removing host and user/passwd*/
belle_http_response_t *response; belle_http_response_t *response;
belle_sip_channel_t *channel;
int auth_attempt_count; int auth_attempt_count;
int background_task_id; int background_task_id;
int cancelled;
}; };
void belle_http_request_set_listener(belle_http_request_t *req, belle_http_request_listener_t *l); void belle_http_request_set_listener(belle_http_request_t *req, belle_http_request_listener_t *l);
......
...@@ -75,6 +75,14 @@ belle_http_request_t *belle_http_request_create(const char *method, belle_generi ...@@ -75,6 +75,14 @@ belle_http_request_t *belle_http_request_create(const char *method, belle_generi
return obj; return obj;
} }
int belle_http_request_is_cancelled(const belle_http_request_t *req) {
return req->cancelled;
}
void belle_http_request_cancel(belle_http_request_t *req) {
req->cancelled = TRUE;
}
void belle_http_request_set_listener(belle_http_request_t *req, belle_http_request_listener_t *l){ void belle_http_request_set_listener(belle_http_request_t *req, belle_http_request_listener_t *l){
if (req->listener){ if (req->listener){
belle_sip_object_weak_unref(req->listener,(belle_sip_object_destroy_notify_t)belle_http_request_listener_destroyed,req); belle_sip_object_weak_unref(req->listener,(belle_sip_object_destroy_notify_t)belle_http_request_listener_destroyed,req);
......
...@@ -134,6 +134,10 @@ static void http_channel_context_handle_response_headers(belle_http_channel_cont ...@@ -134,6 +134,10 @@ static void http_channel_context_handle_response_headers(belle_http_channel_cont
belle_sip_error("Receiving http response headers not matching any request."); belle_sip_error("Receiving http response headers not matching any request.");
return; return;
} }
if (belle_http_request_is_cancelled(req)) {
belle_sip_warning("Receiving http response headers for a cancelled request.");
return;
}
code=belle_http_response_get_status_code(response); code=belle_http_response_get_status_code(response);
if (code!=401 && code!=407){ if (code!=401 && code!=407){
/*else notify the app about the response headers received*/ /*else notify the app about the response headers received*/
...@@ -155,6 +159,10 @@ static void http_channel_context_handle_response(belle_http_channel_context_t *c ...@@ -155,6 +159,10 @@ static void http_channel_context_handle_response(belle_http_channel_context_t *c
belle_sip_error("Receiving http response not matching any request."); belle_sip_error("Receiving http response not matching any request.");
return; return;
} }
if (belle_http_request_is_cancelled(req)) {
belle_sip_warning("Receiving http response for a cancelled request.");
return;
}
connection=belle_sip_message_get_header((belle_sip_message_t *)response,"Connection"); connection=belle_sip_message_get_header((belle_sip_message_t *)response,"Connection");
if (connection && strstr(belle_sip_header_get_unparsed_value(connection),"close")!=NULL) if (connection && strstr(belle_sip_header_get_unparsed_value(connection),"close")!=NULL)
chan->about_to_be_closed=TRUE; chan->about_to_be_closed=TRUE;
...@@ -374,6 +382,10 @@ static void belle_http_end_background_task(void* data) { ...@@ -374,6 +382,10 @@ static void belle_http_end_background_task(void* data) {
} }
} }
static void notify_http_request_of_channel_destruction(belle_http_request_t *obj, belle_sip_channel_t *chan_being_destroyed){
obj->channel=NULL;
}
int belle_http_provider_send_request(belle_http_provider_t *obj, belle_http_request_t *req, belle_http_request_listener_t *listener){ int belle_http_provider_send_request(belle_http_provider_t *obj, belle_http_request_t *req, belle_http_request_listener_t *listener){
belle_sip_channel_t *chan; belle_sip_channel_t *chan;
belle_sip_hop_t *hop=belle_sip_hop_new_from_generic_uri(req->orig_uri ? req->orig_uri : req->req_uri); belle_sip_hop_t *hop=belle_sip_hop_new_from_generic_uri(req->orig_uri ? req->orig_uri : req->req_uri);
...@@ -404,6 +416,8 @@ int belle_http_provider_send_request(belle_http_provider_t *obj, belle_http_requ ...@@ -404,6 +416,8 @@ int belle_http_provider_send_request(belle_http_provider_t *obj, belle_http_requ
split_request_url(req); split_request_url(req);
fix_request(req); fix_request(req);
belle_sip_object_weak_ref(chan, (belle_sip_object_destroy_notify_t)notify_http_request_of_channel_destruction, req);
req->channel=chan;
if( req->background_task_id != 0){ if( req->background_task_id != 0){
req->background_task_id = belle_sip_begin_background_task("belle-sip http", belle_http_end_background_task, req); req->background_task_id = belle_sip_begin_background_task("belle-sip http", belle_http_end_background_task, req);
} }
...@@ -412,6 +426,26 @@ int belle_http_provider_send_request(belle_http_provider_t *obj, belle_http_requ ...@@ -412,6 +426,26 @@ int belle_http_provider_send_request(belle_http_provider_t *obj, belle_http_requ
return 0; return 0;
} }
static void reenqueue_request(belle_http_request_t *req, belle_http_provider_t *prov){
belle_http_provider_send_request(prov,req,req->listener);
}
void belle_http_provider_cancel_request(belle_http_provider_t *obj, belle_http_request_t *req){
belle_sip_list_t *outgoing_messages;
belle_http_request_cancel(req);
if (req->channel){
// Keep the list of the outgoing messages of the channel...
outgoing_messages = belle_sip_list_copy_with_data(req->channel->outgoing_messages,(void* (*)(void*))belle_sip_object_ref);
provider_remove_channel(obj, req->channel);
// ... close the channel...
belle_sip_channel_force_close(req->channel);
// ... and reenqueue the previously queued outgoing messages into a new channel
belle_sip_list_for_each2(outgoing_messages,(void (*)(void*,void*))reenqueue_request,obj);
belle_sip_list_free_with_data(outgoing_messages,belle_sip_object_unref);
}
}
int belle_http_provider_set_tls_verify_policy(belle_http_provider_t *obj, belle_tls_verify_policy_t *verify_ctx){ int belle_http_provider_set_tls_verify_policy(belle_http_provider_t *obj, belle_tls_verify_policy_t *verify_ctx){
SET_OBJECT_PROPERTY(obj,verify_ctx,verify_ctx); SET_OBJECT_PROPERTY(obj,verify_ctx,verify_ctx);
return 0; return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment