http-message.c 6.1 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;
Simon Morlat's avatar
Simon Morlat committed
65
	belle_http_request_t *obj=belle_http_request_new();
Simon Morlat's avatar
Simon Morlat committed
66 67 68
	belle_sip_header_t *header;
	
	obj->method=belle_sip_strdup(method);
jehan's avatar
jehan committed
69
	obj->req_uri=(belle_generic_uri_t*)belle_sip_object_ref(url);
Simon Morlat's avatar
Simon Morlat committed
70 71 72 73 74 75
	
	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
76 77 78
	return obj;
}

79 80 81 82 83 84 85 86
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
87 88 89 90 91
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
92
	if (l){
Simon Morlat's avatar
Simon Morlat committed
93
		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
94 95
		req->listener=l;
	}
Simon Morlat's avatar
Simon Morlat committed
96
}
Simon Morlat's avatar
Simon Morlat committed
97

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
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
113 114 115 116
belle_http_request_listener_t * belle_http_request_get_listener(const belle_http_request_t *req){
	return req->listener;
}

jehan's avatar
jehan committed
117 118 119
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
120

jehan's avatar
jehan committed
121
void belle_http_request_set_uri(belle_http_request_t* request, belle_generic_uri_t* uri) {
122
	SET_OBJECT_PROPERTY(request,req_uri,uri);
Simon Morlat's avatar
Simon Morlat committed
123
}
jehan's avatar
jehan committed
124

Simon Morlat's avatar
Simon Morlat committed
125
void belle_http_request_set_response(belle_http_request_t *req, belle_http_response_t *resp){
126
	SET_OBJECT_PROPERTY(req,response,resp);
Simon Morlat's avatar
Simon Morlat committed
127
}
jehan's avatar
jehan committed
128

Simon Morlat's avatar
Simon Morlat committed
129 130 131
belle_http_response_t *belle_http_request_get_response(belle_http_request_t *req){
	return req->response;
}
jehan's avatar
jehan committed
132 133 134 135 136 137 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

/*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)
164
													,belle_http_response_get_reason_phrase(resp)?belle_http_response_get_reason_phrase(resp):"");
jehan's avatar
jehan committed
165 166 167
	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;
168
	
jehan's avatar
jehan committed
169 170 171 172 173 174 175 176 177
	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)