Hello,

I'm writing own proxy app. Some sites are not working correctly, i.e. I am not seeing any content in browser. E.g. kpomkwem.com. But when I invoke code that sends shutdown for opened sockets, content appears. I invoke this code by pressing hot key (Ctrl-C), this is handle_signal() func. Is this correct way to use shutdown for fixing issue? Second issue. I'm using Fiddler and much requests appears after pressing hot key. Why they don't appear at once? I'm using C, SDL_net 2 and TCP non-blocking sockets.

Code:
#define NUM_SS_REPLY        1000
#define NUM_UA_SOCK     100
#define SOCK_UA(ar,i)       ar[i].sock_ua
SS_REPLY    GLB_ARRAY__SS_REPLY[ NUM_SS_REPLY ] ;
UA_REQUEST  GLB_ARRAY__UA_REQ[ NUM_UA_SOCK ] ;

int nrdy  ;

while( 1 )
{
    nrdy = SDLNet_CheckSockets(GLB_SOCK_SET, -1 /*1000*/);
    if(nrdy == -1 )
        break ;
    if( !nrdy )
        continue ;

    check_listener_socket() ;
    check_user_agent_sockets() ;
    check_single_stream_socket() ;
}

//==================================================================
//  Check and handle connection request from UA ( user agent )
//==================================================================

void check_listener_socket()
{
uint32_t index ;
UA_REQUEST*ar = GLB_ARRAY__UA_REQ ;

if( !SDLNet_SocketReady( GLB_LSOCK_UA ) )
{
    puts("check_listener_socket():  GLB_LSOCK_UA is not ready!");
    return ;
}

TCPsocket sock_ua = SDLNet_TCP_Accept( GLB_LSOCK_UA ) ;         // `accept connection from browser`

if( !sock_ua)
{
    printf("ERR__TCP_Accept: %s\n", SDLNet_GetError());
    goto quit ;
} else
    printf("Accepted.\n");

for( index=0 ; (index < NUM_UA_SOCK) ; index++)
    if( STATUS(ar,index) == ST_SOCK_CLOSED )
        break ;
// to put debug here
if( index >= NUM_UA_SOCK )
{
    return ;
}

SOCK_UA( ar , index )   = sock_ua ;
STATUS( ar , index )    = ST_SOCK_AVLBL ;
SDLNet_TCP_AddSocket( GLB_SOCK_SET , SOCK_UA( ar, index ) ) ;

quit:
    return ;
}

//==================================================================
//  Check and receive data from UA
//==================================================================

void check_user_agent_sockets()
{
    UA_REQUEST *ar = GLB_ARRAY__UA_REQ ;
    uint32_t index ;

    for( index=0 ;  index < NUM_UA_SOCK ; index++)  
    {
        int ready = SDLNet_SocketReady( SOCK_UA(ar,index) );
        if( ready )
        {
            printf("index =  %i\n", index);
            handle_ua_sock_ready( index ) ;
        }
    }
}

//==================================================================

void handle_ua_sock_ready( uint32_t i )
{
    My_string _req_mstr ;
    MY_ALLOC( _req_mstr , MAXLEN )

    byte*request    = _req_mstr.c_str ;
    byte*pcrlf  = NULL ;
    RESET_BUF(request)

    UA_REQUEST*ar = GLB_ARRAY__UA_REQ ;

    // Get request from UA
    //uint32_t 
    int nrcv;   // : Slava
    nrcv = SDLNet_TCP_Recv( SOCK_UA(ar,i) , request , MAXLEN ) ;

    if( nrcv<=0 )
    {
        puts("handle_ua_sock_ready()  before handle_ua_sock_closed");
        handle_ua_sock_closed( ar , i ) ;
        puts("handle_ua_sock_ready()  after handle_ua_sock_closed");
        goto quit;
    }

    puts("1") ;
    if(                     
        ( STATUS(ar,i) == ST_TUNNEL)        
        || (MATCH( request , CONN , strlen(CONN)))  
    )                       
    {                       
        FULL_URL( ar , i ).c_str[0] = 0 ;       
        FULL_URL( ar , i ).len  = 0 ;       
        STATUS( ar , i )        = ST_TUNNEL ;   
        request[nrcv]   = 0 ;           

        send_to_server(TUNNEL_REQ ,request, nrcv, i);   
        goto quit;
    }   

    CHECK_AND_HANDLE_CONNECT_REQ(ar,i,request,nrcv )
    puts("11") ;
    if( get_hdrs_and_full_url(request, i ,(uint32_t*)&nrcv,pcrlf) == -1 )
    {
        puts("handle_ua_sock_ready()    test 2");
        goto quit ;
    }

    My_string *purl_mstr = &FULL_URL( ar , i ) ;

    log_msg( purl_mstr->c_str , purl_mstr->len , __LINE__ ) ;

    URL_ADLER32( ar, i) = my_adler_32( 1 , purl_mstr->c_str , purl_mstr->len ) ;



            fwrite( FULL_URL(ar,i).c_str , sizeof(byte), FULL_URL(ar,i).len , GLB_REQ_LOG) ;

    puts("111") ;

    logger.log_msg(request, nrcv, __LINE__);

    CHECK_AND_HANDLE_GET_HEAD_REQ( i , request , nrcv )
    CHECK_AND_HANDLE_UNSUPPORTED(ar,i,request )
    uint32_t uv = nrcv;
    CHECK_AND_HANDLE_POST_OPT_REQ(ar,i,request ,/*nrcv*/ uv)
quit:
    MY_FREE( _req_mstr )
    return ;
}

#define     CHECK_AND_HANDLE_GET_HEAD_REQ(index,req,nrcv)   \
do{                         \
    if(                     \
        MATCH(request,GET,strlen(GET))      \
        || MATCH(request,HEAD,strlen(HEAD))     \
    )                       \
    {                       \
        handle_http_GET(req , index ,nrcv) ;    \
        goto quit ;             \
    }                       \
} while(0) ;

void handle_http_GET(byte*request , uint32_t req_index  , uint32_t nrcv)
{
    // debug
    if (strstr((char*)request, "jpg") || strstr((char*)request, "png") || 
            strstr((char*)request, "css"))
    {
        int a;
        a = 1;
    }

    UA_REQUEST*req_arr = GLB_ARRAY__UA_REQ ;
    if( ! GLB_SYNC_ENABLED )
    {
        logger.log_msg(request, nrcv, __LINE__);    //
        send_to_server( DIRECT_REQ , request , nrcv, req_index ) ;
        return;
    }

    if( home_page_req( request) )
    {
        send_to_server( HTML_REQ , request , nrcv, req_index ) ;
    }

    uint32_t rep_index;
    uint32_t    nurl    = FULL_URL( req_arr , req_index ).len;
    byte*       full_url    = FULL_URL( req_arr , req_index ).c_str ;
    SS_REPLY    *rep_arr = GLB_ARRAY__SS_REPLY ;
    uint32_t        url_adler32= URL_ADLER32( req_arr , req_index ) ;  /*my_adler_32( 1, full_url , nurl ) ; */


    puts("222");
    bool bExit = false;

    for( rep_index = 0 ; rep_index < NUM_SS_REPLY ; rep_index++)
    {
        if(
            (STATUS( rep_arr , rep_index )==ST_OCCUPIED)
            && ( url_adler32 == URL_ADLER32(rep_arr , rep_index) )
        )
        {
            puts("333") ;
            My_string*purl_mstr = &FULL_URL( rep_arr,rep_index) ;

            byte msg[ MAXLEN ] ;

            sprintf( (char*)msg , "MATCHED_URL in rep_arr \n Index = %u \n url_adler32 = %u \n", rep_index , url_adler32 ) ;
            puts( (char*)msg ) ;
            log_msg( msg , strlen( (char*)msg ) , __LINE__ ) ;

            My_string reply_mstr ;
            MY_ALLOC( reply_mstr , MAXLEN )

            update_cache__and__read_in_mystr(   REPLY( rep_arr , rep_index ).c_str
                            ,REPLY( rep_arr , rep_index ).len
                            ,&reply_mstr ,req_index
                            ) ;
            uint32_t nreply = reply_mstr.len ;
            //
            logger.log_msg((byte*)"Sent to UA:", strlen("Sent to UA:"), __LINE__);
            logger.log_msg(reply_mstr.c_str, nreply, __LINE__);

            // : Slava
            int ncnt = SDLNet_TCP_Send(
                            SOCK_UA( req_arr , req_index)
                            , reply_mstr.c_str
                            , nreply
                            ) ;

            reset_reply_arr_element( rep_index ) ;

            if( ncnt != nreply )
                handle_ua_sock_closed(req_arr,req_index) ;
            else
                reset_req_arr_element( req_index ) ;

            MY_FREE( reply_mstr )
            bExit = true;
            break;
        }
    }

    if (bExit)
        return;

    puts("444");
    int8_t retval = lookup_cache_and_reply(req_index) ;
    if( retval==1 )
    {
        STATUS( req_arr , req_index ) = ST_REQ_AWAITED ;
        return;
    }
    if( retval==0 )
    {
        STATUS( req_arr , req_index ) = ST_RSP_AWAITED ;
        return;
    }
    if( retval==-1 )
        return ;

}

void handle_ua_sock_closed( UA_REQUEST*ar ,uint32_t index )
{
    printf("handle_ua_sock_closed():  index = %d\n", index);
    if( index >=NUM_UA_SOCK )
    {
        byte err[] = "ERR__INDEX_OUT_OF_BOUNDS___UA_REQ_ARRAY" ;
        log_msg( err , strlen((const char*)err) , __LINE__ );
        puts((const char*)err) ;
        return ;
    }

    SDLNet_TCP_DelSocket( GLB_SOCK_SET , SOCK_UA(ar,index));
    FULL_URL(ar, index ).c_str[0]=0 ;
    FULL_URL(ar, index ).len =0;

    if( STATUS(ar,index) == ST_TUNNEL )
        send_to_server(TUNNEL_REQ , (byte*)"exit" , strlen("exit") , index ) ;
    STATUS(ar,index) = ST_SOCK_CLOSED ;
}

//==================================================================
//  Check and receive reply from "Server"
//==================================================================

void check_single_stream_socket()
{
    puts("-- before return");
    if( !SDLNet_SocketReady(GLB_SOCK_SS) )
    {
            return ;
    }
    puts("-- before receive_data_from_server()");
    receive_data_from_server() ;
}

void receive_data_from_server()
{
    My_string payload ;

    MY_ALLOC( payload , MAXLEN )

    int ncnt;   // : Slava
    uint32_t  nreply , req_index , rep_index ;
    uint32_t aallocated, ffreed ;


    byte err[100] ;
    bool bExitFlag = false;

    puts("30001") ;

    //TCPsocket sock_ua ;
    payload.len = 0 ;
    if( get_payload(&payload) == -1 )
        goto quit ;
    UA_REQUEST*req_arr  = GLB_ARRAY__UA_REQ ;
    SS_REPLY*rep_arr        = GLB_ARRAY__SS_REPLY ;

    puts("30002") ;

 SDLNet_Read32( payload.c_str+1 ) ) ;

    uint8_t rep_type = payload.c_str[0] ;

    if( (rep_type == 1 /* TUNNEL_REQ */)
        || (rep_type == 3 /* POST_REQ */)
        || ( rep_type==4 /* DIRECT_REQ */)
    )                   /*ie req_id == req_arr index*/
    {
        puts("30003") ;

        req_index = SDLNet_Read32( payload.c_str+1 ) ;
        nreply  = payload.len-5 ;
        //
        logger.log_msg((byte*)"Sent back to UA:", strlen("Sent back to UA:"), __LINE__);
        logger.log_msg(payload.c_str + 5, nreply, __LINE__);
        // send to UA
        ncnt    = SDLNet_TCP_Send(
                        SOCK_UA( req_arr,req_index)
                        , payload.c_str+5 , nreply
                    ) ;
        if(ncnt < nreply)
        {
            sprintf((char*)err , "ERR__SOCK_WRITE :: bytes to be written: %u ;; actual num:: %u" , nreply , ncnt ) ;
            log_msg(err , strlen((char*)err) , __LINE__ ) ;
            handle_ua_sock_closed( req_arr , req_index ) ;
        }
    }
    else if( /* rep_type */ payload.c_str[0] == 2  /* HTML_REQ */)      /* < req_id == "url_adler32" > */
    {
        puts("30004") ;

        uint32_t url_adler32    = SDLNet_Read32( payload.c_str+1 ) ;

        for( req_index = 0 ; req_index < NUM_UA_SOCK ; req_index++ )
        {
            if(URL_ADLER32( req_arr , req_index) == url_adler32 )
            {

                puts("30005") ;

                My_string reply_mstr ;
                MY_ALLOC( reply_mstr , MAXLEN ) 
                update_cache__and__read_in_mystr(   payload.c_str+5 ,payload.len-5
                                ,&reply_mstr ,req_index
                                ) ;
                nreply = reply_mstr.len ;

                puts("30006") ;

                //
                logger.log_msg((byte*)"Sent back to UA:", strlen("Sent back to UA:"), __LINE__);
                logger.log_msg(reply_mstr.c_str, strlen((char*)reply_mstr.c_str), __LINE__);

                // send to UA
                ncnt = SDLNet_TCP_Send(
                            SOCK_UA( req_arr , req_index)
                            , reply_mstr.c_str              // reply_mstr
                            , nreply
                        ) ;
                if(ncnt < nreply)
                {
                    sprintf((char*)err , "ERR__SOCK_WRITE :: bytes to be written: %u ;; actual num:: %u" , nreply , ncnt ) ;
                    log_msg(err , strlen((char*)err) , __LINE__ ) ;
                    handle_ua_sock_closed( req_arr , req_index ) ;
                }
                else
                    reset_req_arr_element( req_index) ;

                MY_FREE( reply_mstr )
                bExitFlag = true;   // : Slava
                break;
            }
        }


        if (!bExitFlag) 
        {
            for( rep_index = 0 ; rep_index < NUM_SS_REPLY ; rep_index++)
            {
                if(STATUS( rep_arr , rep_index )==ST_EMPTY)
                    break ;
            }

            char* pbuf = new char[payload.len + 50];
            pbuf[payload.len + 49] = '\0';
            sprintf(pbuf, "Reply from server to storage: %s  Index = %d", 
                    payload.c_str + 5, rep_index);
            logger.log_msg((byte*)pbuf, strlen(pbuf), __LINE__);
            delete pbuf;

            My_string*pdel_mstr = &(REPLY( rep_arr , rep_index )) ;
            // : Slava
            uint32_t url_adler32 = SDLNet_Read32(payload.c_str + 1) ;
            rep_arr[rep_index].url_adler32 = url_adler32;

            if(pdel_mstr->len)
                pdel_mstr->len = 0 ;
            append( pdel_mstr , payload.c_str+5 , payload.len-5 ) ;

            puts("30007") ;

            STATUS( rep_arr , rep_index ) = ST_OCCUPIED ;
        }

    }   // else  /*</ id_type != "socket"> */
quit:
    MY_FREE( payload )
}

void handle_signal( int x)
{
    byte msg[100] ={0} ;
    sprintf( (char*)msg , "ALERT__RECEIVED_SIGNAL:: %d" , x ) ;
    log_msg( msg , strlen((char*)msg) , __LINE__ );
    puts( (char*)msg ) ;

    // debug
    if (x == 2)     // Ctrl-C pressed
    {
        UA_REQUEST*ar = GLB_ARRAY__UA_REQ;

        for (int i = 0; i < NUM_UA_SOCK; i++)
        {
            TCPsocket sock = SOCK_UA(ar, i);
            if (ar[i].status_flag != ST_SOCK_CLOSED)
            {
                shutdown(sock->channel, SD_BOTH);
            }
        }


    #ifdef SIGINT
        signal(SIGINT, handle_signal);
    #endif
    }
}
Thanks,
Vyacheslav