static void check_ready_packets( qqclient* qq ) { qqpacketmgr* mgr = &qq->packetmgr; if( !loop_is_empty(&mgr->sent_loop) || loop_is_empty(&mgr->ready_loop) ) return; //if tcp, we send one by one, otherwise send them all if( loop_is_empty(&mgr->sent_loop) ) //good luck, get a packet and send it. { qqpacket* p = loop_pop_from_head( &mgr->ready_loop ); if( p && p->buf ){ //remove p from ready packets if( p->head!=0x02 || p->tail !=0x03 ){ DBG("Fatal error: p->command=%x p->head: %x p->tail: %x", p->command, p->head, p->tail ); delete_func( p ); return; } int ret = qqsocket_send( qq->socket, p->buf->data, p->buf->len ); // DBG("[%d] out packet cmd: %x", p->command ); if( ret != p->buf->len ){ DBG("send packet failed. ret(%d)!=p->len(%d)", ret, p->buf->len ); delete_func( p ); qqclient_set_process( qq, P_ERROR ); }else{ if( p->need_ack ){ p->time_alive = time(NULL); loop_push_to_tail( &mgr->sent_loop, p ); }else{ delete_func( p ); } } }else{ DBG("no packet. "); } } }
static void work_http( connection* conn ) { int i; virtual_host * host; //check if the connection cannot work. if( conn->state != C_READY ) return; conn->state = C_REQUESTING; http_request( conn ); if( conn->state != C_REQUESTING ) return; //response conn->code = 200; conn->state = C_RESPONSING; /* Check Host and then set root directory. */ host = loop_search( &conn->server->loop_vhost, conn->host, vhost_searcher ); if( !host ){ host = loop_search( &conn->server->loop_vhost, "*", vhost_searcher ); } if( host ){ //read root conn->root_dir = host->root_dir; if( !loop_is_empty( &host->loop_rewrite ) ) loop_search( &host->loop_rewrite, (void*)conn, loop_rewrite_match ); http_parse_uri( conn ); DBG("[%s]%s%s", conn->client->ip_string, conn->host, conn->uri ); _RESPONSE: http_parse_path( conn ); conn->document_type = http_doctype( conn->server, conn->extension ); if( !conn->document_type ){ http_error( conn, 404, "<h1>File not found.</h1>" ); }else if( conn->extension[0] && strstr( conn->server->asp_exts, conn->extension ) ) { //php do ... exec_asp( conn ); }else if( host->proxy && ( !host->proxy_exts[0] || strstr( host->proxy_exts, conn->extension ) ) ) { // uses proxy server proxy_request( conn, host->proxy_ip, host->proxy_port ); }else if( access(conn->full_path, 0)==0 ){ if( is_dir(conn->full_path) ){ char* tmp; NEW( tmp, PATH_LEN+32 ); if( conn->script_name[strlen(conn->script_name)-1] != '/' ){ //Are you sure that script starts with '/'? sprintf( tmp, "http://%s%s/", conn->host, conn->script_name ); http_redirect( conn, tmp ); }else{ if( tmp ){ for( i = 0; i<10; i++ ) { if( !conn->server->default_pages[i][0] ) { i=10; break; } sprintf( tmp, "%s/%s", conn->full_path, conn->server->default_pages[i] ); if( access( tmp, 0 ) == 0 ) { //091004 by Huang Guan. sprintf( conn->script_name, "%s%s", conn->script_name, conn->server->default_pages[i] ); DEL( tmp ); goto _RESPONSE; } } } if( i == 10 ){ // List Directory if( host->list ){ int ret; NEW( conn->data_send, MAX_DATASEND+4 ); strcpy( conn->extension, "html" ); conn->document_type = http_doctype( conn->server, conn->extension ); ret = listdir( conn->data_send, MAX_DATASEND, conn->full_path, conn->script_name ); conn->data_size = ret; }else{ http_error( conn, 403, "<h1>Forbidden</h1>" ); } } } DEL( tmp ); }else{ http_sendfile( conn, conn->full_path ); } }else if( strncmp(conn->current_dir, "/system", 7)==0 && conn->root_dir==host->root_dir ){ strcpy(conn->script_name, conn->script_name+7); conn->root_dir = conn->client->server->root_dir; goto _RESPONSE; }else{ http_error( conn, 404, "<h1>File not found.</h1>" ); } }else{ http_error( conn, 403, "<h1>Unknown host name.</h1>" ); } if( conn->state == C_RESPONSING ) http_response( conn ); conn->requests ++; if( conn->form_data ) DEL( conn->form_data ); if( conn->data_send ) DEL( conn->data_send ); if( conn->session ) conn->session->reference --; conn->session = NULL; //next request if( conn->keep_alive ){ conn->state = C_READY; }else{ conn->state = C_END; } }