Esempio n. 1
0
void cg_http_packet_read_headers(CgHttpPacket *httpPkt, CgSocket *sock, char *lineBuf, size_t lineBufSize)
{
	CgStringTokenizer *strTok;
	CgHttpHeader *header;
	ssize_t readLen;
	char *name, *value;
	
	cg_log_debug_l4("Entering...\n");

	while (1) {
		readLen = cg_socket_readline(sock, lineBuf, lineBufSize);
		if (readLen <= 2)
			break;
		name = NULL;
		value = NULL;
		strTok = cg_string_tokenizer_new(lineBuf, CG_HTTP_HEADERLINE_DELIM);
		if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE)
			name = cg_string_tokenizer_nexttoken(strTok);
		if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE) {
			value = cg_string_tokenizer_nextalltoken(strTok);
			cg_strrtrim(value, CG_HTTP_HEADERLINE_DELIM, cg_strlen(CG_HTTP_HEADERLINE_DELIM));
		}
		if (0 < cg_strlen(name)) {
			if (cg_strlen(value) == 0)
				value = "";
			header = cg_http_header_new();
			cg_http_header_setname(header, name);
			cg_http_header_setvalue(header, value);
			cg_http_packet_addheader(httpPkt, header);
		}
		cg_string_tokenizer_delete(strTok);
	}

	cg_log_debug_l4("Leaving...\n");
}
CgXmlNode *cg_soap_request_getbodynode(CgSoapRequest *soapReq)
{
    CgXmlNode *envNode;
    CgXmlNode *bodyNode = NULL;
  CgXmlAttribute *attr;
  char *name;
  CgStringTokenizer *tok;
  char *nsPrefix;
  size_t bodyLen;
  char *body;

    cg_log_debug_l4("Entering...\n");

    envNode = cg_soap_request_getenvelopenode(soapReq);
    if (envNode == NULL)
        return NULL;
    if (cg_xml_node_haschildnodes(envNode) == FALSE)
        return NULL;

        /* We cannot assume the namespace prefix for Body is 's'.
           According to spec, it could be anything... */
        for (attr = cg_xml_node_getattributes(envNode); attr != NULL;
             attr = cg_xml_attribute_next(attr)) {
                /* First, find the namespace declaration attribute. */
                /* Note: We must take a copy of the attr name.
                   Tokenizer doesn't do it (by default) */
                name = cg_strdup( cg_xml_attribute_getname(attr) );
                tok = cg_string_tokenizer_new(name, ":");

                nsPrefix = cg_string_tokenizer_nexttoken(tok);
                if ( -1 != cg_strstr(nsPrefix, "xmlns")) {
                        /* This attribute is a namespace declaration. Check is
                           it the one defined for SOAP. */
                        if (cg_strcmp(cg_xml_attribute_getvalue(attr), CG_SOAP_XMLNS_URL) == 0) {
                                /* This namespace declaration is correct.
                                   Use it to find the body node... */
                                if (cg_string_tokenizer_hasmoretoken(tok)) {
                                        /* There is a prefix */
                                        nsPrefix = cg_string_tokenizer_nexttoken(tok);
                                        bodyLen = cg_strlen(nsPrefix) +
                                                cg_strlen(CG_SOAP_DELIM) +
                                                cg_strlen(CG_SOAP_BODY) + 1; /* +1 for trailing '\0'*/
                                        body = (char*)malloc(bodyLen);

                    if ( NULL == body )
                    {
                        cg_log_debug_s("Memory allocation failure!\n");
                        return NULL;
                    }
#if defined(HAVE_SNPRINTF)
                                        snprintf(body, bodyLen, "%s%s%s", nsPrefix,
                                                 CG_SOAP_DELIM, CG_SOAP_BODY);
#else
                                        sprintf(body, "%s%s%s", nsPrefix, CG_SOAP_DELIM, CG_SOAP_BODY);
#endif
                                        bodyNode = cg_xml_node_getchildnode(envNode, body);
                                        free(body);
                                }
                                else {
                                        /* No prefix */
                                        bodyNode = cg_xml_node_getchildnode(envNode, CG_SOAP_BODY);
                                }
                                /* Free memory before leaving the loop */
                                cg_string_tokenizer_delete(tok);
                                free(name);
                                break;
                        }
                }
                cg_string_tokenizer_delete(tok);
                free(name);
        }

    cg_log_debug_l4("Leaving...\n");

    return bodyNode;
}
Esempio n. 3
0
BOOL cg_http_request_read(CgHttpRequest *httpReq, CgSocket *sock)
{
    char lineBuf[CG_HTTP_READLINE_BUFSIZE];
    CgStringTokenizer *strTok;
    int readLen;
    CgNetURI *uri = NULL;
    BOOL failed = FALSE;

    cg_log_debug_l4("Entering...\n");

    cg_http_request_clear(httpReq);

    /* If first character(s) is \n or \r\n we ignore it(them) and read second line. */
    do {
        readLen = cg_socket_readline(sock, lineBuf, sizeof(lineBuf));
    } while (readLen >= 1 && readLen <=2);

    if (readLen <= 0)
        return FALSE;

    strTok = cg_string_tokenizer_new(lineBuf, CG_HTTP_STATUSLINE_DELIM);
    if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE)
        cg_http_request_setmethod(httpReq, cg_string_tokenizer_nexttoken(strTok));
    else
        failed = TRUE;
    if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE)
        cg_http_request_seturi(httpReq, cg_string_tokenizer_nexttoken(strTok));
    else
        failed = TRUE;
    if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE)
        cg_http_request_setversion(httpReq, cg_string_tokenizer_nexttoken(strTok));
    else
        failed = TRUE;
    cg_string_tokenizer_delete(strTok);

    if (failed == TRUE) return FALSE;

    /* We could do some further validation for the HTTP-request? */

    /* Change URI to be relative (absolute not needed anymore) */
    uri = cg_net_uri_new();
    if (uri != NULL)
    {
        cg_net_uri_set(uri, cg_http_request_geturi(httpReq));
        if (cg_net_uri_isabsolute(uri) == TRUE &&
                cg_net_uri_getrequest(uri) != NULL)
        {
            cg_http_request_seturi(httpReq,
                                   cg_net_uri_getrequest(uri));
        }
        cg_net_uri_delete(uri);
        uri = NULL;
    }

    /* Read headers */
    cg_http_packet_clear((CgHttpPacket *)httpReq);
    cg_http_packet_read_headers((CgHttpPacket *)httpReq, sock, lineBuf, sizeof(lineBuf));

    /* HTTP-request must have Content-Length or Transfer-Encoding header
       in order to have body */
    if (cg_http_packet_hasheader((CgHttpPacket *)httpReq, CG_HTTP_CONTENT_LENGTH) ||
            cg_http_packet_hasheader((CgHttpPacket *)httpReq, CG_HTTP_TRANSFER_ENCODING))
        cg_http_packet_read_body((CgHttpPacket *)httpReq, sock, lineBuf, sizeof(lineBuf));

    cg_log_debug_l4("Leaving...\n");

    return TRUE;
}
Esempio n. 4
0
/**
 * Callback function for CURL to read each HTTP header line
 * CgStringTokenizer might have been a viable choice to do the parsing
 * of various fields. Then again, it would not have read correctly a
 * header line with, for example, the time (because of multiple use of colons):
 * Foo: 12:34:56 EEST DST
 */
static size_t cg_http_request_header_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
    char* headerLine = NULL;
    char* name = NULL;
    char* value = NULL;
    CgStringTokenizer* strTok = NULL;
    CgHttpResponse* httpRes = NULL;
    int head = 0;
    int tail = 0;

    cg_log_debug_l4("Entering...\n");

    if (stream == NULL || ptr == NULL)
    {
        return 0;
    }

    httpRes = (CgHttpResponse*) stream;
    headerLine = (char*) ptr;

    /* Read header items */
    if (cg_strncmp(headerLine, CG_HTTP_VER11, cg_strlen(CG_HTTP_VER11)) == 0
            ||
            cg_strncmp(headerLine, CG_HTTP_VER10, cg_strlen(CG_HTTP_VER10)) == 0)
    {
        /* <HTTP/version> <status code> <reason phrase> */
        strTok = cg_string_tokenizer_new(headerLine, CG_HTTP_STATUSLINE_DELIM);
        if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE)
        {
            cg_http_response_setversion(httpRes, cg_string_tokenizer_nexttoken(strTok));
        }

        if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE)
        {
            cg_http_response_setstatuscode(httpRes, atoi(cg_string_tokenizer_nexttoken(strTok)));
        }

        if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE)
        {
            value = cg_string_tokenizer_nextalltoken(strTok);
            cg_strrtrim(value, CG_HTTP_STATUSLINE_DELIM, cg_strlen(CG_HTTP_STATUSLINE_DELIM));
            cg_http_response_setreasonphrase(httpRes, value);
        }

        cg_string_tokenizer_delete(strTok);
    }
    else
    {
        /* Find the header delimiter */
        for (head = 0; head < size * nmemb; head++)
        {
            if (headerLine[head] == ':')
            {
                break;
            }
        }

        /* Unable to find a colon, this is not a valid header line */
        if (head <= 0 || head >= (size * nmemb) - 1)
        {
            return size * nmemb;
        }

        /* Take the header name */
        name = (char*) malloc(head + 1);

        if ( NULL == name )
        {
            cg_log_debug_s("Memory allocation failure!\n");
            return 0;
        }

        memcpy(name, headerLine, head);
        name[head] = '\0';

        /* Skip colon and space(s) */
        for (head++; head < size * nmemb; head++)
        {
            if (headerLine[head] != 0x20)
            {
                break;
            }
        }

        /* Unable to find anything sensible anymore */
        if (head >= (size * nmemb) - 1)
        {
            return size * nmemb;
        }

        /* Find the end of the actual value, without CRLF */
        for (tail = size * nmemb; tail > 0; tail --)
        {
            if (headerLine[tail] == '\r')
            {
                break;
            }
            else if (headerLine[tail] == '\n')
            {
                if (tail > 0 && headerLine[tail - 1] == '\r')
                {
                    tail--;
                    break;
                }
            }
        }

        /* Unable to find CRLF */
        if (tail <= head)
        {
            free(name);
            return size * nmemb;
        }

        /* Take the header value */
        value = (char*) malloc(tail - head + 1);

        if ( NULL == value )
        {
            cg_log_debug_s("Memory allocation failure!\n");
            return 0;
        }

        memcpy(value, headerLine + head, tail - head);
        value[tail - head] = '\0';

        /* Set the header value to the response */
        cg_http_response_setheadervalue(httpRes, name, value);

        free(name);
        free(value);
    }

    return size * nmemb;

    cg_log_debug_l4("Leaving...\n");
}