IMSDroid的tiny http stack是专用于其tiny xcap的,以下是摘自http://doubango.org/API/tinyHTTP/ 关于tinyHTTP的概述:
The HTTP/HTTPS stack is a basic thread-safe client API and is used in conjunction with the XCAP protocol. Almost all HTTP methods such as OPTIONS, HEAD, GET, DELETE, POST, CONNET, TRACE or PUT … are supported for outgoing requests. Only response messages will be correctly handled by the stack.
因此httpStack的创建以及启动都出现在Xcap中,在tinyXCAP/src/txcap.c中,函数tsk_object_t* _txcap_stack_create 通过以下两句分别创建http stack及http session:
/* HTTP/HTTPS stack and session */
stack->http_stack = thttp_stack_create(callback,
THTTP_STACK_SET_NULL());
stack->http_session = thttp_session_create(stack->http_stack ,
THTTP_SESSION_SET_NULL());
在txcap.c中,函数txcap_stack_start通过thttp_stack_start(stack->http_stack)来启动http stack。
具体实现是在tinyHTTP/src/thttp.c的thttp_stack_start函数中,关键代码如下:
if(!stack->transport){
stack->transport = tnet_transport_create(stack->local_ip, stack->local_port, tnet_socket_type_tcp_ipv46, "HTTP/HTTPS transport");
tnet_transport_set_callback(stack->transport, TNET_TRANSPORT_CB_F(thttp_transport_layer_stream_cb), self);
}
if(!(ret = tnet_transport_start(stack->transport))){
// Sets TLS certificates
if(stack->tls.ca){
tsk_strupdate(&stack->transport->tls.ca, stack->tls.ca);
tsk_strupdate(&stack->transport->tls.pvk, stack->tls.pvk);
tsk_strupdate(&stack->transport->tls.pbk, stack->tls.pbk);
}
stack->started = tsk_true;
}
设置好call back然后启动transport.
tnet_transport_start的具体实现在tinyNET/src/tnet_transport.c中,这个函数进而会调用tsk_runnable_start(TSK_RUNNABLE(transport), tnet_transport_event_def_t)),
在tinySAK/src/tsk_runnable.c中,函数tsk_runnable_start通过tsk_thread_create创建一个新的线程并执行run函数,具体run函数的定义在tnet_transport.c中:
static void *run(void* self)
{
int ret = 0;
tsk_list_item_t *curr;
tnet_transport_t *transport = self;
TSK_DEBUG_INFO("Transport::run() - enter");
//TSK_DEBUG_ERROR("HttpService: Runnable interface implementation.");
/* create main thread */
if((ret = tsk_thread_create(transport->mainThreadId, tnet_transport_mainthread, transport))){ /* More important than "tsk_runnable_start" ==> start it first. */
TSK_FREE(transport->context); /* Otherwise (tsk_thread_create is ok) will be freed when mainthread exit. */
TSK_DEBUG_FATAL("Failed to create main thread [%d]", ret);
return tsk_null;
}
TSK_RUNNABLE_RUN_BEGIN(transport);
if((curr = TSK_RUNNABLE_POP_FIRST_SAFE(TSK_RUNNABLE(transport)))){
const tnet_transport_event_t *e = (const tnet_transport_event_t*)curr->data;
if(transport->callback){
//TSK_DEBUG_ERROR("HttpService: transport callback.");
transport->callback(e);
}
tsk_object_unref(curr);
}
TSK_RUNNABLE_RUN_END(transport);
TSK_DEBUG_INFO("Transport::run() - exit");
return tsk_null;
}
当有事件的时候,会执行具体的call back: tinyHTTP/src/thttp.c中的thttp_transport_layer_stream_cb,在解析出消息以后执行状态机。