Пример #1
0
bool HTTPSession::ParseRequest(HTTPRequest& request, ReadBuffer& cmd, UrlParam& params)
{
    char*       qmark;
    ReadBuffer  rb;
    ReadBuffer  jsonCallback;
    ReadBuffer  mimeType;
    ReadBuffer  origin;
    
    // TODO: when adding keep-alive HTTP sessions, move this to an Init() function
    isFlushed = false;
    
    uri = request.line.uri;
    rb = request.line.uri;
    if (rb.GetCharAt(0) == '/')
        rb.Advance(1);
    
    mimeType.Reset();
    ParseType(rb);
    cmd = rb;

    qmark = NULL;
    if (rb.GetLength() > 0)
        qmark = FindInBuffer(rb.GetBuffer(), rb.GetLength() - 1, '?');

    if (qmark)
    {
        rb.Advance((unsigned) (qmark - rb.GetBuffer() + 1));
        params.Init(rb.GetBuffer(), rb.GetLength(), '&');
        cmd.SetLength((unsigned) (qmark - cmd.GetBuffer()));
        
        if (type == JSON)
        {
            HTTP_GET_OPT_PARAM(params, "callback", jsonCallback);
            json.SetCallbackPrefix(jsonCallback);
        }
        
        // mime type is overridable
        HTTP_GET_OPT_PARAM(params, "mimetype", mimeType);
        if (mimeType.GetLength() != 0)
            conn->SetContentType(mimeType);
            
        // CORS support
        // http://www.w3.org/TR/cors/
        HTTP_GET_OPT_PARAM(params, "origin", origin);
    }
    
    return true;
}
Пример #2
0
bool UrlParam::GetNamed(const char* name, int namelen, ReadBuffer& bs)
{
    int         n;
    int         len;
    
    n = GetParamIndex(name, namelen);
    if (n < 0)
        return false;
    
    len = GetParamLen(n) - (namelen + 1);
    if (len == -1)
        len = 0;        // param without value
    
    bs.SetBuffer((char*) GetParam(n) + (namelen + 1));
    bs.SetLength(len);

    return true;
}
Пример #3
0
void MessageConnection::OnRead()
{
    bool            yield, closed;
    unsigned        pos, msglength, nread, msgbegin, msgend, required;
    uint64_t        start;
    Stopwatch       sw;
    ReadBuffer      msg;

    if (!readActive)
    {
        if (resumeRead.IsActive())
            STOP_FAIL(1, "Program bug: resumeRead.IsActive() should be false.");
        EventLoop::Add(&resumeRead);
        return;
    }

    sw.Start();

    Log_Trace("Read buffer: %B", tcpread.buffer);

    tcpread.requested = IO_READ_ANY;
    pos = 0;
    start = NowClock();
    yield = false;

    while(true)
    {
        msglength = BufferToUInt64(tcpread.buffer->GetBuffer() + pos,
                                   tcpread.buffer->GetLength() - pos, &nread);

        if (msglength > tcpread.buffer->GetSize() - NumDigits(msglength) - 1)
        {
            Log_Trace();
            required = msglength + NumDigits(msglength) + 1;
            if (required > MESSAGING_MAX_SIZE)
            {
                Log_Trace();
                OnClose();
                return;
            }
            tcpread.buffer->Allocate(required);
            break;
        }

        if (nread == 0 || (unsigned) tcpread.buffer->GetLength() - pos <= nread)
            break;

        if (tcpread.buffer->GetCharAt(pos + nread) != ':')
        {
            Log_Trace("Message protocol error");
            OnClose();
            return;
        }

        msgbegin = pos + nread + 1;
        msgend = pos + nread + 1 + msglength;

        if ((unsigned) tcpread.buffer->GetLength() < msgend)
        {
            // read more
            //tcpread.requested = msgend - pos;
            break;
        }

        msg.SetBuffer(tcpread.buffer->GetBuffer() + msgbegin);
        msg.SetLength(msglength);
        closed = OnMessage(msg);
        if (closed)
            return;

        pos = msgend;

        // if the user called Close() in OnMessageRead()
        if (state != CONNECTED)
            return;

        if (tcpread.buffer->GetLength() == msgend)
            break;

        if (NowClock() - start >= YIELD_TIME || !readActive)
        {
            // let other code run every YIELD_TIME msec
            yield = true;
            if (resumeRead.IsActive())
                STOP_FAIL(1, "Program bug: resumeRead.IsActive() should be false.");
            EventLoop::Add(&resumeRead);
            break;
        }
    }

    if (pos > 0)
    {
        memmove(tcpread.buffer->GetBuffer(), tcpread.buffer->GetBuffer() + pos,
                tcpread.buffer->GetLength() - pos);
        tcpread.buffer->Shorten(pos);
    }

    if (state == CONNECTED
            && !tcpread.active && !yield)
        IOProcessor::Add(&tcpread);

    sw.Stop();
    Log_Trace("time spent in OnRead(): %U", sw.Elapsed());
}