Beispiel #1
0
void HTTPSession::PrintPair(const ReadBuffer& key, const ReadBuffer& value)
{
    if (!conn)
        return;

    if (!headerSent)
    {
        if (type == JSON)
            json.Start();
        else
            conn->WriteHeader(HTTP_STATUS_CODE_OK);

        headerSent = true;
    }

    if (type == JSON)
        json.PrintPair(key.GetBuffer(), key.GetLength(), value.GetBuffer(), value.GetLength());
    else
    {
        conn->Write(key.GetBuffer(), key.GetLength());
        conn->Print(": ");
        conn->Write(value.GetBuffer(), value.GetLength());
        conn->Print("\n");
    }
}
void StorageMemoKeyValue::Set(ReadBuffer key_, ReadBuffer value_)
{
    if (buffer != NULL)
        free(buffer);
    
    keyLength = key_.GetLength();
    valueLength = value_.GetLength();

    buffer = (char*) malloc(GetLength());
    
    memcpy(buffer, key_.GetBuffer(), keyLength);
    memcpy(buffer + keyLength, value_.GetBuffer(), valueLength);
}
Beispiel #3
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;
}
Beispiel #4
0
void HTTPSession::Print(const ReadBuffer& line)
{
    Buffer      header;
    ReadBuffer  tmp;
    
    if (!conn)
        return;

    if (!headerSent)
    {
        if (type == JSON)
            json.Start();
        else
            conn->WriteHeader(HTTP_STATUS_CODE_OK);

        headerSent = true;
    }
    
    if (type == JSON)
    {
        tmp = "response";
        json.PrintString(tmp);
        json.PrintColon();
        json.PrintString(line);
    }
    else
    {
        conn->Write(line.GetBuffer(), line.GetLength());
        conn->Print("\n");
    }
}
void StorageMemoKeyValue::Delete(ReadBuffer key_)
{
    if (buffer != NULL)
        free(buffer);
    
    keyLength = key_.GetLength();
    valueLength = DELETE_LENGTH_VALUE;

    buffer = (char*) malloc(GetLength());
    
    memcpy(buffer, key_.GetBuffer(), keyLength);
}
Beispiel #6
0
bool Endpoint::Set(ReadBuffer ip_port, bool resolv)
{
    const char*     p;
    const char*     start;
    int             port;
    bool            ret;
    Buffer          ipbuf;
    Buffer          portbuf;

    if (!IsValidEndpoint(ReadBuffer(ip_port)))
        return false;
    
    start = p = ip_port.GetBuffer();
    
    p = RevFindInBuffer(ip_port.GetBuffer(), ip_port.GetLength(), ':');
    if (p == NULL)
    {
        Log_Trace("No ':' in host specification");
        return false;
    }

    ipbuf.Append(start, p - start);
    ipbuf.NullTerminate();
    
    p++;
    portbuf.Append(p, ip_port.GetLength() - (p - start));
    portbuf.NullTerminate();
    
    port = -1;
    port = atoi(portbuf.GetBuffer());
    if (port < 1 || port > 65535)
    {
        Log_Trace("atoi() failed to produce a sensible value");
        return false;
    }

    ret = Set(ipbuf.GetBuffer(), port, resolv);
    
    return ret;
}
Beispiel #7
0
uint64_t QuorumDatabase::GetUint64(const char* name)
{
    ReadBuffer  key(name);
    ReadBuffer  value;
    uint64_t    u64;
    unsigned    nread;
    int         ret;

    ret = paxosShard->Get(key, value);
    if (!ret)
        return false;

    nread = 0;
    u64 = BufferToUInt64(value.GetBuffer(), value.GetLength(), &nread);
    if (nread != value.GetLength())
    {
        Log_Trace();
        u64 = 0;
    }

    return u64;
}
Beispiel #8
0
bool Endpoint::IsValidEndpoint(ReadBuffer ip_port)
{
    // Valid endpoint is either <IPv4-Address>:<port> or <IPv6-Address>:<port> or <Domain-Name>:<port>
    // Valid IPv4-Address consists only from numbers and three dots between the numbers
    // Valid IPv6-Adresses: http://en.wikipedia.org/wiki/IPv6#Addressing
    // Valid domain names: http://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names

    const char  VALID_CHARS[] = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    unsigned    i;
    bool        labelStart;
    bool        isNumeric;
    bool        isHexnum;
    bool        isPort;
    bool        isIPv6;
    unsigned    numCommas;
    unsigned    numPortChars;
    char        c;
    char        prev;
    char        sep;
    char*       lastColon;

    // assuming fully numeric names
    isNumeric = true;
    isHexnum = true;
    isPort = false;
    numCommas = 0;
    numPortChars = 0;
    labelStart = true;
    isIPv6 = false;
    prev = ' ';
    sep = ' ';
    lastColon = NULL;
    for (i = 0; i < ip_port.GetLength(); i++)
    {
        c = ip_port.GetCharAt(i);

        if (c == '.' || c == ':')
        {
            if (i == 0)
            {
                // IPv4 and DNS must not start with comma or colon
                if (c == '.')
                    return false;

                isIPv6 = true;
                isHexnum = true;
            }

            // labels must not end with hyphens
            if (prev == VALID_CHARS[0])
                return false;
            
            if (c == '.')
            {
                labelStart = true;
                numCommas++;
                sep = c;
            }
            
            if (c == ':')
            {
                // cannot mix IPv4 and IPv6 addresses this way
                // this however is legal in IPv6: ::ffff:192.0.2.128
                if (isHexnum && sep != '.')
                {
                    isIPv6 = true;
                    sep = ':';
                    isPort = true;
                    numPortChars = 0;
                }
                else
                {
                    if (isPort && !isIPv6)
                        return false;
                    isPort = true;
                    numPortChars = 0;
                }

                lastColon = ip_port.GetBuffer() + i;
            }
        }
        else
        {        
            // labels must not start with hyphens
            if (labelStart && c == VALID_CHARS[0])
                return false;
            
            if (isPort)
            {
                if (!isdigit(c))
                {
                    if (isIPv6)
                        isPort = false;
                    else
                        return false;
                }
                else
                    numPortChars++;
            }
            
            if (isNumeric && !isdigit(c))
                isNumeric = false;
            
            if (isHexnum && !isxdigit(c))
            {
                if (isIPv6)
                    return false;
                isHexnum = false;
            }
            
            if (strchr(VALID_CHARS, c) == NULL)
                return false;

            labelStart = false;
        }
        
        prev = c;
    }

    if (isNumeric && numCommas != 3)
        return false;
    if (isIPv6 && numCommas != 0 && numCommas != 3)
        return false;
    if (numPortChars < 1 || numPortChars > 5)
        return false;
    
    return true;
}
Beispiel #9
0
void Buffer::Append(ReadBuffer other)
{
    Append(other.GetBuffer(), other.GetLength());
}
Beispiel #10
0
void Buffer::Write(const ReadBuffer other)
{
    Write(other.GetBuffer(), other.GetLength());
}