Changeset 5725:a6b8cb206c2b in roaraudio
- Timestamp:
- 11/01/12 03:56:14 (11 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- plugins/universal
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
plugins/universal/Makefile
r5721 r5725 24 24 %$(SHARED_SUFFIX): %.o 25 25 $(CC) $(LDFLAGS) -o $@ $+ $(LIBS) 26 27 protocol-http$(SHARED_SUFFIX): protocol-http.o 28 $(CC) $(LDFLAGS) -o $@ $+ $(LIBS) $(lib_uste) -
plugins/universal/protocol-http.c
r5722 r5725 25 25 26 26 #include <roaraudio.h> 27 #ifdef ROAR_HAVE_LIBUSTE 28 #include <uste.h> 29 #endif 27 30 28 31 struct resource_handle; … … 86 89 87 90 static int header_send(struct roar_buffer ** obuffer, int status, const char * msg, const char * content_type, ssize_t len); 91 static void send_errorpage(struct http_client * self, struct roar_buffer ** obuffer, int error, const char * msg); 88 92 89 93 static int slow_zero_stream(struct http_client * self, struct roar_buffer ** obuffer) { … … 129 133 } 130 134 135 #ifdef ROAR_HAVE_LIBUSTE 136 static uste_var_t __res_vio_handle_uste_build_headers(struct http_client * self) { 137 uste_var_t root = uste_var_new_kv(); 138 uste_var_t var; 139 ssize_t i; 140 141 if ( root == NULL ) 142 return NULL; 143 144 uste_var_set_key(root, "header"); 145 146 for (i = 0; i < self->headerslen; i++) { 147 var = uste_var_new_str(self->headers[i].value == NULL ? "" : self->headers[i].value); 148 if ( self->headers[i].key != NULL ) 149 uste_var_set_key(var, self->headers[i].key); 150 uste_var_push(root, var); 151 uste_var_unref(var); 152 } 153 154 return root; 155 } 156 static uste_var_t __res_vio_handle_uste_build_rootkv(struct http_client * self) { 157 uste_var_t root = uste_var_new_kv(); 158 uste_var_t subroot, subsubroot; 159 uste_var_t var; 160 161 if ( root == NULL ) 162 return NULL; 163 164 #define __new_member_prefix(prefix,name) \ 165 if ( prefix->name != NULL ) { \ 166 var = uste_var_new_str(prefix->name); \ 167 uste_var_set_key(var, #name); \ 168 uste_var_push(subsubroot, var); \ 169 uste_var_unref(var); \ 170 } 171 #define __new_member(name) __new_member_prefix(self,name) 172 173 subroot = uste_var_new_kv(); 174 if ( subroot != NULL ) { 175 uste_var_set_key(subroot, "__client__"); 176 uste_var_push(root, subroot); 177 178 var = uste_var_new_int(self->clientid); 179 uste_var_set_key(var, "clientid"); 180 uste_var_push(subroot, var); 181 uste_var_unref(var); 182 183 subsubroot = uste_var_new_kv(); 184 if ( subsubroot != NULL ) { 185 uste_var_set_key(subsubroot, "http"); 186 uste_var_push(subroot, subsubroot); 187 188 __new_member(method); 189 __new_member(proto); 190 __new_member(uri); 191 __new_member(path); 192 __new_member(query_string); 193 194 var = __res_vio_handle_uste_build_headers(self); 195 uste_var_push(subsubroot, var); 196 uste_var_unref(var); 197 198 uste_var_unref(subsubroot); 199 } 200 201 uste_var_unref(subroot); 202 } 203 204 subroot = uste_var_new_kv(); 205 if ( subroot != NULL ) { 206 uste_var_set_key(subroot, "__host__"); 207 uste_var_push(root, subroot); 208 209 subsubroot = subroot; 210 __new_member_prefix(self->pluginpara, appname); 211 __new_member_prefix(self->pluginpara, abiversion); 212 213 uste_var_unref(subroot); 214 } 215 216 return root; 217 } 218 219 static void __res_vio_handle_uste(struct http_client * self, struct roar_buffer ** obuffer, const char * content_type) { 220 struct roar_buffer * buffer = NULL; 221 uste_renderer_t renderer; 222 uste_parser_t parser; 223 uste_var_t rootkv; 224 uste_node_t root; 225 int err; 226 227 228 parser = uste_parser_new(self->input.vio); 229 err = roar_error; 230 roar_vio_close(self->input.vio); 231 if ( parser == NULL ) { 232 send_errorpage(self, obuffer, err, NULL); 233 return; 234 } 235 236 if ( uste_parser_parse(parser) == -1 ) { 237 send_errorpage(self, obuffer, roar_error, NULL); 238 return; 239 } 240 241 root = uste_parser_get_rootnode(parser); 242 err = roar_error; 243 uste_parser_unref(parser); 244 245 if ( root == NULL ) { 246 send_errorpage(self, obuffer, err, NULL); 247 return; 248 } 249 250 renderer = uste_renderer_new(); 251 err = roar_error; 252 if ( renderer == NULL ) { 253 uste_node_unref(root); 254 send_errorpage(self, obuffer, err, NULL); 255 return; 256 } 257 258 uste_stdfunc_register_all(renderer); 259 260 rootkv = __res_vio_handle_uste_build_rootkv(self); 261 err = roar_error; 262 if ( rootkv == NULL ) { 263 uste_node_unref(root); 264 uste_renderer_unref(renderer); 265 send_errorpage(self, obuffer, err, NULL); 266 return; 267 } 268 269 uste_renderer_set_rootvar(renderer, rootkv); 270 uste_var_unref(rootkv); 271 272 buffer = uste_node_render(root, renderer); 273 err = roar_error; 274 uste_node_unref(root); 275 uste_renderer_unref(renderer); 276 277 if ( buffer == NULL ) { 278 send_errorpage(self, obuffer, err, NULL); 279 return; 280 } 281 282 header_send(obuffer, 200, NULL, content_type, -1); 283 284 if ( buffer != NULL ) { 285 if ( roar_buffer_moveintoqueue(obuffer, &buffer) == -1 ) { 286 roar_buffer_free(buffer); 287 return; 288 } 289 } 290 291 self->status = STATUS_DONE; 292 } 293 #endif 294 295 static int __res_vio_check_uste(struct http_client * self, struct roar_buffer ** obuffer, const char * content_type) { 296 const size_t len = 14; 297 struct roar_buffer * buffer; 298 void * data; 299 ssize_t ret; 300 301 // TODO: use content type for some basic filtering. 302 (void)content_type; 303 304 *obuffer = NULL; 305 306 if ( roar_buffer_new_data(&buffer, len, &data) == -1 ) 307 return -1; 308 309 ret = roar_vio_read(self->input.vio, data, len); 310 311 if ( ret < 1 ) { 312 roar_buffer_free(buffer); 313 return 0; 314 } 315 316 *obuffer = buffer; 317 318 if ( ret == (ssize_t)len ) { 319 return !strncmp(data, "@@@TEMPLATE@@@", len); 320 } else { 321 if ( roar_buffer_set_len(buffer, ret) == -1 ) { 322 *obuffer = NULL; 323 roar_buffer_free(buffer); 324 return -1; 325 } 326 // is this really a nice idea? 327 return 0; 328 } 329 } 330 131 331 static int __res_vio_header_send(struct http_client * self, struct roar_buffer ** obuffer) { 332 struct roar_buffer * buffer; 132 333 struct roar_keyval * path; 133 334 char filename[1024]; … … 179 380 content_type = __res_vio_content_type_get(self); 180 381 382 if ( __res_vio_check_uste(self, &buffer, content_type) == 1 ) { 383 if ( buffer != NULL ) 384 roar_buffer_free(buffer); 385 #ifdef ROAR_HAVE_LIBUSTE 386 __res_vio_handle_uste(self, obuffer, content_type); 387 return 0; 388 #else 389 roar_vio_close(self->input.vio); 390 send_errorpage(self, obuffer, ROAR_ERROR_NOSYS, NULL); 391 return 0; 392 #endif 393 } 394 181 395 header_send(obuffer, 200, NULL, content_type, -1); 396 397 if ( buffer != NULL ) { 398 if ( roar_buffer_moveintoqueue(obuffer, &buffer) == -1 ) { 399 roar_buffer_free(buffer); 400 return -1; 401 } 402 } 182 403 183 404 self->status = STATUS_RUNNING_DATA; … … 190 411 void * data; 191 412 ssize_t ret; 413 414 if ( self->status == STATUS_DONE ) 415 return 0; 192 416 193 417 if ( roar_buffer_new_data(&buffer, len, &data) == -1 ) … … 249 473 250 474 static inline int __ret(struct http_client * self, struct roar_buffer ** obuffer) { 251 ROAR_DBG("__ret(self=%p, obuffer=%p ): self->status=%i", self,obuffer, (int)self->status);475 ROAR_DBG("__ret(self=%p, obuffer=%p{%p}): self->status=%i", self, obuffer, *obuffer, (int)self->status); 252 476 if ( *obuffer != NULL ) 253 477 return 0; … … 366 590 return -1; 367 591 368 ROAR_DBG("header_parse(self=%p): data='%*s'", self, (int)len, data);592 ROAR_DBG("header_parse(self=%p): data='%*s'", self, (int)len, (const char*)data); 369 593 370 594 if ( len < 4 ) … … 753 977 (void)client, (void)vio, (void)protopara, (void)protoparalen, (void)pluginpara; 754 978 979 ROAR_DBG("_flushed(*) = ?"); 980 755 981 if ( self->status == STATUS_RUNNING_DATA ) 756 982 resource_body_send(self, obuffer);
Note: See TracChangeset
for help on using the changeset viewer.