Пример #1
0
int HttpClient::sendRequest(int times, HttpStat& stat, StringBuffer& req)
{
    StringBuffer request;
    if(req.length() <= 2)
    {
        throw MakeStringException(-1, "request too short");
    }

    bool endofheaders = false;
    char c0 = req.charAt(0);
    char c1 = req.charAt(1);
    if(c0 == '\n')
        request.append("\r\n");
    else
        request.append(c0);

    if(c1 == '\n')
    {
        if(c0 == '\r')
            request.append(c1);
        else
        {
            request.append("\r\n");
            if(c0 == '\n')
                endofheaders = true;
        }
    }
    else
        request.append(c1);

    unsigned seq = 2;
    while(seq < req.length() && !endofheaders)
    {
        char c = req.charAt(seq);
        if(c == '\n')
        {
            char c1 = req.charAt(seq - 1);
            char c2 = req.charAt(seq - 2);
            if(c1 == '\n' || (c1 == '\r' && c2 == '\n'))
                endofheaders = true;

            if(c1 != '\r')
                request.append("\r\n");
            else
                request.append(c);
        }
        else
            request.append(c);
        seq++;
    }

    if(seq < req.length())
        request.append(req.length() - seq, req.str() + seq);

    if(httptest_tracelevel > 5)
        fprintf(m_ofile, ">>sending out request to %s:%d for %d times\n", m_host.str(), m_port, times);

    unsigned start = msTick();
    int slowest = 0;
    int fastest = 2147483647;
    for(int i = 0; i < times; i++)
    {
        SocketEndpoint ep;
        ep.set(m_host.str(), m_port);
        Owned<ISocket> socket;
        try
        {
            socket.setown(ISocket::connect(ep));
            if(m_use_ssl && m_ssctx.get() != NULL)
            {
                Owned<ISecureSocket> securesocket = m_ssctx->createSecureSocket(socket.getLink());
                int res = securesocket->secure_connect();
                if(res >= 0)
                {
                    socket.set(securesocket.get());
                }
            }
        }
        catch(IException *excpt)
        {
            StringBuffer errMsg;
            DBGLOG("Error connecting to %s:%d - %d:%s", m_host.str(), m_port, excpt->errorCode(), excpt->errorMessage(errMsg).str());
            continue;
        }
        catch(...)
        {
            DBGLOG("can't connect to %s:%d", m_host.str(), m_port);
            continue;
        }

        if(socket.get() == NULL)
        {
            StringBuffer urlstr;
            DBGLOG(">>Can't connect to %s", ep.getUrlStr(urlstr).str());
            continue;
        }

        if(m_delay > 0)
            sleep(m_delay);

        if(httptest_tracelevel > 5)
            fprintf(m_ofile, ">>sending out request:\n");
        if(httptest_tracelevel > 10)
            fprintf(m_ofile, "%s%s%s\n", sepstr, request.str(), sepstr);

        unsigned start1 = msTick();

        socket->write(request.str(), request.length());

        if(httptest_tracelevel > 5)
            fprintf(m_ofile, ">>receiving response:\n");

        StringBuffer buf;
        Owned<IByteOutputStream> ostream = createOutputStream(buf);
        stat.totalresplen += receiveData(socket.get(), ostream.get(), true);
        if(httptest_tracelevel > 10)
            fprintf(m_ofile, "%s%s%s\n", sepstr, buf.str(), sepstr);

        char tmpbuf[256];
        unsigned int sizeread;
        do
        {
            socket->read(tmpbuf, 0, 256, sizeread);
        }
        while(sizeread > 0);

        socket->shutdown();
        socket->close();
        fflush(m_ofile);
        unsigned end1 = msTick();
        int duration = end1 - start1;
        if(duration <= fastest)
            fastest = duration;
        if(duration > slowest)
            slowest = duration;

        if(i % 100 == 0)
            fprintf(stderr, "sent out %d\n", i);
    }

    unsigned end = msTick();
    stat.msecs = end - start;
    stat.numrequests = times;
    stat.totalreqlen = times * request.length();
    stat.slowest = slowest;
    stat.fastest = fastest;

    return 0;
}
Пример #2
0
    virtual int run()
    {
        Thread::Link();

        int ret = 0;
        try
        {
            char peername[256];
            int clientport = m_client->peer_name(peername, 256);

            char inbuf[1024];
            char outbuf[1024];
            memset(inbuf, 0, 1024);
            memset(outbuf, 0, 1024);

            unsigned int len = 0;
            unsigned int lenread = 0;
            m_client->read(inbuf, 8, 8, lenread);
            if(lenread != 8)
            {
                DBGLOG("didn't get the first 8 bytes, invalid socks request.");
                return -1;
            }

            len += lenread;
            m_client->read(inbuf + len, 0, 1, lenread);
            StringBuffer username;
            while(lenread > 0)
            {
                len += lenread;
                if(len >= 1023)
                {
                    len = 0;
                }
                if(inbuf[len - 1] == '\0')
                {
                    break;
                }
                char c = inbuf[len - 1];
                username.append(c);
                m_client->read(inbuf + len, 0, 1, lenread);
            }
            
            if(http_tracelevel >= 5)
                fprintf(m_ofile, "\n>>receivd SOCKS request from %s:%d, user %s\n", peername, clientport, username.str());

            outbuf[0] = '\0';
            outbuf[1] = (char)0x5a;

            m_client->write(outbuf, 8);

            char ubyte = inbuf[2];
            char lbyte = inbuf[3];
            unsigned short port = (unsigned short)ubyte;
            port = port << 8;
            port += lbyte;

            // TBD IPV6 (should use serialize/deserialize)

            IpAddress ip;
            ip.setNetAddress(4,inbuf+4);        
                                                

            StringBuffer ipstr;
            ip.getIpText(ipstr);
            if(http_tracelevel >= 5)
                fprintf(m_ofile, "\n>>The request is for %s:%d\n", ipstr.str(), port);      

            SocketEndpoint ep;
            ep.set(port, ip);
            m_remotesocket.setown(ISocket::connect(ep));

            m_client->set_nonblock(false);
            m_remotesocket->set_nonblock(false);
            CReadWriteThread t1(m_client.get(), m_remotesocket.get(), m_ofile);
            CReadWriteThread t2(m_remotesocket.get(), m_client.get(), m_ofile);
            t1.start();
            t2.start();
            t1.join();
            t2.join();
            m_remotesocket->shutdown();
            m_remotesocket->close();
            m_client->shutdown();
            m_client->close();
        }
        catch(IException *excpt)
        {
            StringBuffer errMsg;
            DBGLOG("%s", excpt->errorMessage(errMsg).str());
            ret = -1;
        }
        catch(...)
        {
            DBGLOG("unknown exception");
            ret = -1;
        }

        Thread::Release();

        return 0;
    }
Пример #3
0
bool CHttpProtocol::notifySelected(ISocket *sock,unsigned selected, IPersistentHandler* persistentHandler, bool shouldClose)
{
    try
    {
        char name[256];
        int port = sock->name(name, 255);

        CEspApplicationPort *apport = queryApplicationPort(port);

        if(apport == NULL)
            throw MakeStringException(-1, "binding not found!");
        
        if(apport != NULL)
        {
            Owned<ISocket> accepted;
            if (persistentHandler == nullptr)
                accepted.setown(sock->accept());
            else
                accepted.set(sock);
            if (accepted.get() != NULL)
            {
                char peername[256];
                int port = accepted->peer_name(peername, 256);

    #if defined(_DEBUG)
                DBGLOG("HTTP connection from %s:%d on %s socket", peername, port, persistentHandler?"persistent":"new");
    #endif          

                if(m_maxConcurrentThreads > 0)
                {
                    // Using Threading pool instead of generating one thread per request.
                    void ** holder = new void*[7];
                    holder[0] = (void*)(accepted.getLink());
                    holder[1] = (void*)apport;
                    int maxEntityLength = getMaxRequestEntityLength();
                    holder[2] = (void*)&maxEntityLength;
                    bool useSSL = false;
                    holder[3] = (void*)&useSSL;
                    ISecureSocketContext* ctx = NULL;
                    holder[4] = (void*)ctx;
                    holder[5] = (void*)persistentHandler;
                    holder[6] = (void*)&shouldClose;
                    try
                    {
                        http_thread_pool->start((void*)holder, "", m_threadCreateTimeout > 0?m_threadCreateTimeout*1000:0);
                    }
                    catch(...)
                    {
                        IERRLOG("Error starting thread from http thread pool.");
                        if(accepted.get())
                        {
                            accepted->close();
                            //Assumption here is that if start() throws exception, that means the new 
                            //thread hasn't been started, so there's no other thread holding a link.
                            CInterface* ci = dynamic_cast<CInterface*>(accepted.get());
                            if(ci && ci->IsShared())
                                accepted->Release();
                        }
                        delete [] holder;
                        throw;
                    }
                    delete [] holder;
                }
                else
                {
                    /* create one thread per request */
                    CHttpThread *workthread = new CHttpThread(accepted.getLink(), apport, CEspProtocol::getViewConfig(), false, nullptr, persistentHandler);
                    workthread->setMaxRequestEntityLength(getMaxRequestEntityLength());
                    workthread->setShouldClose(shouldClose);
                    workthread->start();
                    workthread->Release();
                }
            }
        }
        else
        {
            throw MakeStringException(-1, "can't acquire bindings IEspHttpBinding interface (via dynamic_cast)!");
        }
    }
    catch (IException *e) 
    {
        StringBuffer estr;
        IERRLOG("Exception(%d, %s) in CHttpProtocol::notifySelected()", e->errorCode(), e->errorMessage(estr).str());
        e->Release();
    }
    catch(...)
    {
        IERRLOG("Unknown Exception in CHttpProtocol::notifySelected()");
    }

    return false;
}