Changeset 5725:a6b8cb206c2b in roaraudio


Ignore:
Timestamp:
11/01/12 03:56:14 (11 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

added working uste support

Location:
plugins/universal
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • plugins/universal/Makefile

    r5721 r5725  
    2424%$(SHARED_SUFFIX): %.o 
    2525        $(CC) $(LDFLAGS) -o $@ $+ $(LIBS) 
     26 
     27protocol-http$(SHARED_SUFFIX): protocol-http.o 
     28        $(CC) $(LDFLAGS) -o $@ $+ $(LIBS) $(lib_uste) 
  • plugins/universal/protocol-http.c

    r5722 r5725  
    2525 
    2626#include <roaraudio.h> 
     27#ifdef ROAR_HAVE_LIBUSTE 
     28#include <uste.h> 
     29#endif 
    2730 
    2831struct resource_handle; 
     
    8689 
    8790static int header_send(struct roar_buffer ** obuffer, int status, const char * msg, const char * content_type, ssize_t len); 
     91static void send_errorpage(struct http_client * self, struct roar_buffer ** obuffer, int error, const char * msg); 
    8892 
    8993static int slow_zero_stream(struct http_client * self, struct roar_buffer ** obuffer) { 
     
    129133} 
    130134 
     135#ifdef ROAR_HAVE_LIBUSTE 
     136static 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} 
     156static 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 
     219static 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 
     295static 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 
    131331static int __res_vio_header_send(struct http_client * self, struct roar_buffer ** obuffer) { 
     332 struct roar_buffer * buffer; 
    132333 struct roar_keyval * path; 
    133334 char filename[1024]; 
     
    179380  content_type = __res_vio_content_type_get(self); 
    180381 
     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 
    181395 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 } 
    182403 
    183404 self->status = STATUS_RUNNING_DATA; 
     
    190411 void * data; 
    191412 ssize_t ret; 
     413 
     414 if ( self->status == STATUS_DONE ) 
     415  return 0; 
    192416 
    193417 if ( roar_buffer_new_data(&buffer, len, &data) == -1 ) 
     
    249473 
    250474static 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); 
    252476 if ( *obuffer != NULL ) 
    253477  return 0; 
     
    366590  return -1; 
    367591 
    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); 
    369593 
    370594 if ( len < 4 ) 
     
    753977 (void)client, (void)vio, (void)protopara, (void)protoparalen, (void)pluginpara; 
    754978 
     979 ROAR_DBG("_flushed(*) = ?"); 
     980 
    755981 if ( self->status == STATUS_RUNNING_DATA ) 
    756982  resource_body_send(self, obuffer); 
Note: See TracChangeset for help on using the changeset viewer.