http-message.c 6.23 KB
Newer Older
Simon Morlat's avatar
Simon Morlat committed
1 2 3 4 5 6
/*
	belle-sip - SIP (RFC3261) library.
    Copyright (C) 2010  Belledonne Communications SARL

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation, either version 2 of the License, or
Simon Morlat's avatar
Simon Morlat committed
8 9 10 11 12 13 14 15 16 17
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
18 19
#include "grammars/belle_sip_messageLexer.h"
#include "grammars/belle_sip_messageParser.h"
Simon Morlat's avatar
Simon Morlat committed
20 21 22 23
#include "belle_sip_internal.h"



jehan's avatar
jehan committed
24 25 26
static void belle_http_request_init(belle_http_request_t *req){
	/*nop*/
}
Simon Morlat's avatar
Simon Morlat committed
27 28 29 30 31
static void belle_http_request_listener_destroyed(belle_http_request_t *req){
	req->listener=NULL;
}

static void belle_http_request_destroy(belle_http_request_t *req){
jehan's avatar
jehan committed
32 33
	if (req->req_uri) belle_sip_object_unref(req->req_uri);
	DESTROY_STRING(req,method)
Simon Morlat's avatar
Simon Morlat committed
34
	belle_http_request_set_listener(req,NULL);
35
	belle_http_request_set_channel(req,NULL);
36
	SET_OBJECT_PROPERTY(req,orig_uri,NULL);
37
	SET_OBJECT_PROPERTY(req,response,NULL);
Simon Morlat's avatar
Simon Morlat committed
38 39 40
}

static void belle_http_request_clone(belle_http_request_t *obj, const belle_http_request_t *orig){
jehan's avatar
jehan committed
41 42 43
	if (orig->req_uri) obj->req_uri=(belle_generic_uri_t*)belle_sip_object_clone((belle_sip_object_t*)orig->req_uri);
	CLONE_STRING(belle_http_request,method,obj,orig)
}
Simon Morlat's avatar
Simon Morlat committed
44

jehan's avatar
jehan committed
45 46 47 48 49
static belle_sip_error_code belle_http_request_marshal(const belle_http_request_t* request, char* buff, size_t buff_size, size_t *offset) {
	belle_sip_error_code error=belle_sip_snprintf(buff,buff_size,offset,"%s ",belle_http_request_get_method(request));
	if (error!=BELLE_SIP_OK) return error;
	error=belle_generic_uri_marshal(belle_http_request_get_uri(request),buff,buff_size,offset);
	if (error!=BELLE_SIP_OK) return error;
Simon Morlat's avatar
Simon Morlat committed
50
	error=belle_sip_snprintf(buff,buff_size,offset," %s","HTTP/1.1\r\n");
jehan's avatar
jehan committed
51 52 53
	if (error!=BELLE_SIP_OK) return error;
	error=belle_sip_headers_marshal(BELLE_SIP_MESSAGE(request),buff,buff_size,offset);
	if (error!=BELLE_SIP_OK) return error;
54

jehan's avatar
jehan committed
55
	return error;
Simon Morlat's avatar
Simon Morlat committed
56
}
jehan's avatar
jehan committed
57 58 59
GET_SET_STRING(belle_http_request,method);
BELLE_NEW(belle_http_request,belle_sip_message)
BELLE_PARSE(belle_sip_messageParser,belle_,http_request)
Simon Morlat's avatar
Simon Morlat committed
60 61 62



Simon Morlat's avatar
Simon Morlat committed
63 64
belle_http_request_t *belle_http_request_create(const char *method, belle_generic_uri_t *url, ...){
	va_list vl;
65
	belle_http_request_t *obj;
Simon Morlat's avatar
Simon Morlat committed
66
	belle_sip_header_t *header;
67 68 69 70 71 72 73

	if (belle_generic_uri_get_host(url) == NULL) {
		belle_sip_error("%s: NULL host in url", __FUNCTION__);
		return NULL;
	}

	obj=belle_http_request_new();
Simon Morlat's avatar
Simon Morlat committed
74
	obj->method=belle_sip_strdup(method);
jehan's avatar
jehan committed
75
	obj->req_uri=(belle_generic_uri_t*)belle_sip_object_ref(url);
76

Simon Morlat's avatar
Simon Morlat committed
77 78 79 80 81
	va_start(vl,url);
	while((header=va_arg(vl,belle_sip_header_t*))!=NULL){
		belle_sip_message_add_header(BELLE_SIP_MESSAGE(obj),header);
	}
	va_end(vl);
Simon Morlat's avatar
Simon Morlat committed
82 83 84
	return obj;
}

85 86 87 88 89 90 91 92
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;
}

Simon Morlat's avatar
Simon Morlat committed
93 94 95 96 97
void belle_http_request_set_listener(belle_http_request_t *req, belle_http_request_listener_t *l){
	if (req->listener){
		 belle_sip_object_weak_unref(req->listener,(belle_sip_object_destroy_notify_t)belle_http_request_listener_destroyed,req);
		 req->listener=NULL;
	}
Simon Morlat's avatar
Simon Morlat committed
98
	if (l){
Simon Morlat's avatar
Simon Morlat committed
99
		belle_sip_object_weak_ref(l,(belle_sip_object_destroy_notify_t)belle_http_request_listener_destroyed,req);
Simon Morlat's avatar
Simon Morlat committed
100 101
		req->listener=l;
	}
Simon Morlat's avatar
Simon Morlat committed
102
}
Simon Morlat's avatar
Simon Morlat committed
103

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
static void notify_http_request_of_channel_destruction(belle_http_request_t *obj, belle_sip_channel_t *chan_being_destroyed){
	obj->channel=NULL;
}

void belle_http_request_set_channel(belle_http_request_t *req, belle_sip_channel_t* chan){
	if (req->channel){
		belle_sip_object_weak_unref(req->channel, (belle_sip_object_destroy_notify_t)notify_http_request_of_channel_destruction, req);
		req->channel=NULL;
	}
	if (chan){
		belle_sip_object_weak_ref(chan, (belle_sip_object_destroy_notify_t)notify_http_request_of_channel_destruction, req);
		req->channel=chan;
	}
}

Simon Morlat's avatar
Simon Morlat committed
119 120 121 122
belle_http_request_listener_t * belle_http_request_get_listener(const belle_http_request_t *req){
	return req->listener;
}

jehan's avatar
jehan committed
123 124 125
belle_generic_uri_t *belle_http_request_get_uri(const belle_http_request_t *req){
	return req->req_uri;
}
Simon Morlat's avatar
Simon Morlat committed
126

jehan's avatar
jehan committed
127
void belle_http_request_set_uri(belle_http_request_t* request, belle_generic_uri_t* uri) {
128
	SET_OBJECT_PROPERTY(request,req_uri,uri);
Simon Morlat's avatar
Simon Morlat committed
129
}
jehan's avatar
jehan committed
130

Simon Morlat's avatar
Simon Morlat committed
131
void belle_http_request_set_response(belle_http_request_t *req, belle_http_response_t *resp){
132
	SET_OBJECT_PROPERTY(req,response,resp);
Simon Morlat's avatar
Simon Morlat committed
133
}
jehan's avatar
jehan committed
134

Simon Morlat's avatar
Simon Morlat committed
135 136 137
belle_http_response_t *belle_http_request_get_response(belle_http_request_t *req){
	return req->response;
}
jehan's avatar
jehan committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169

/*response*/


struct belle_http_response{
	belle_sip_message_t base;
	char *http_version;
	int status_code;
	char *reason_phrase;
};


void belle_http_response_destroy(belle_http_response_t *resp){
	if (resp->http_version) belle_sip_free(resp->http_version);
	if (resp->reason_phrase) belle_sip_free(resp->reason_phrase);
}

static void belle_http_response_init(belle_http_response_t *resp){
}

static void belle_http_response_clone(belle_http_response_t *resp, const belle_http_response_t *orig){
	if (orig->http_version) resp->http_version=belle_sip_strdup(orig->http_version);
	resp->status_code=orig->status_code;
	if (orig->reason_phrase) resp->reason_phrase=belle_sip_strdup(orig->reason_phrase);
}

belle_sip_error_code belle_http_response_marshal(belle_http_response_t *resp, char* buff, size_t buff_size, size_t *offset) {
	belle_sip_error_code error=belle_sip_snprintf(	buff
													,buff_size
													,offset
													,"HTTP/1.1 %i %s\r\n"
													,belle_http_response_get_status_code(resp)
170
													,belle_http_response_get_reason_phrase(resp)?belle_http_response_get_reason_phrase(resp):"");
jehan's avatar
jehan committed
171 172 173
	if (error!=BELLE_SIP_OK) return error;
	error=belle_sip_headers_marshal(BELLE_SIP_MESSAGE(resp),buff,buff_size,offset);
	if (error!=BELLE_SIP_OK) return error;
174

jehan's avatar
jehan committed
175 176 177 178 179 180 181 182 183
	return error;
}

BELLE_NEW(belle_http_response,belle_sip_message)
BELLE_PARSE(belle_sip_messageParser,belle_,http_response)
GET_SET_STRING(belle_http_response,reason_phrase);
GET_SET_INT(belle_http_response,status_code,int)