Esempio n. 1
0
void*
xmlNanoHTTPMethodRedir(const char *URL, const char *method, const char *input,
                  char **contentType, char **redir,
		  const char *headers, int ilen ) {
    xmlNanoHTTPCtxtPtr ctxt;
    char *bp, *p;
    int blen, ret;
    int head;
    int nbRedirects = 0;
    char *redirURL = NULL;
#ifdef DEBUG_HTTP
    int xmt_bytes;
#endif
    
    if (URL == NULL) return(NULL);
    if (method == NULL) method = "GET";
    xmlNanoHTTPInit();

retry:
    if (redirURL == NULL)
	ctxt = xmlNanoHTTPNewCtxt(URL);
    else {
	ctxt = xmlNanoHTTPNewCtxt(redirURL);
	ctxt->location = xmlMemStrdup(redirURL);
    }

    if ( ctxt == NULL ) {
	return ( NULL );
    }

    if ((ctxt->protocol == NULL) || (strcmp(ctxt->protocol, "http"))) {
	__xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, "Not a valid HTTP URI");
        xmlNanoHTTPFreeCtxt(ctxt);
	if (redirURL != NULL) xmlFree(redirURL);
        return(NULL);
    }
    if (ctxt->hostname == NULL) {
	__xmlIOErr(XML_FROM_HTTP, XML_HTTP_UNKNOWN_HOST,
	           "Failed to identify host in URI");
        xmlNanoHTTPFreeCtxt(ctxt);
	if (redirURL != NULL) xmlFree(redirURL);
        return(NULL);
    }
    if (proxy) {
	blen = strlen(ctxt->hostname) * 2 + 16;
	ret = xmlNanoHTTPConnectHost(proxy, proxyPort);
    }
    else {
	blen = strlen(ctxt->hostname);
	ret = xmlNanoHTTPConnectHost(ctxt->hostname, ctxt->port);
    }
    if (ret < 0) {
        xmlNanoHTTPFreeCtxt(ctxt);
	if (redirURL != NULL) xmlFree(redirURL);
        return(NULL);
    }
    ctxt->fd = ret;

    if (input == NULL)
	ilen = 0;
    else
	blen += 36;

    if (headers != NULL)
	blen += strlen(headers) + 2;
    if (contentType && *contentType)
	blen += strlen(*contentType) + 16;
    if (ctxt->query != NULL)
	blen += strlen(ctxt->query) + 1;
    blen += strlen(method) + strlen(ctxt->path) + 24;
#ifdef HAVE_ZLIB_H
    blen += 23;
#endif
    bp = (char*)xmlMallocAtomic(blen);
    if ( bp == NULL ) {
        xmlNanoHTTPFreeCtxt( ctxt );
	xmlHTTPErrMemory("allocating header buffer");
	return ( NULL );
    }

    p = bp;

    if (proxy) {
	if (ctxt->port != 80) {
	    p += snprintf( p, blen - (p - bp), "%s http://%s:%d%s", 
			method, ctxt->hostname,
		 	ctxt->port, ctxt->path );
	}
	else 
	    p += snprintf( p, blen - (p - bp), "%s http://%s%s", method,
	    		ctxt->hostname, ctxt->path);
    }
    else
	p += snprintf( p, blen - (p - bp), "%s %s", method, ctxt->path);

    if (ctxt->query != NULL)
	p += snprintf( p, blen - (p - bp), "?%s", ctxt->query);

    p += snprintf( p, blen - (p - bp), " HTTP/1.0\r\nHost: %s\r\n", 
		    ctxt->hostname);

#ifdef HAVE_ZLIB_H
    p += snprintf(p, blen - (p - bp), "Accept-Encoding: gzip\r\n");
#endif

    if (contentType != NULL && *contentType) 
	p += snprintf(p, blen - (p - bp), "Content-Type: %s\r\n", *contentType);

    if (headers != NULL)
	p += snprintf( p, blen - (p - bp), "%s", headers );

    if (input != NULL)
	snprintf(p, blen - (p - bp), "Content-Length: %d\r\n\r\n", ilen );
    else
	snprintf(p, blen - (p - bp), "\r\n");

#ifdef DEBUG_HTTP
    xmlGenericError(xmlGenericErrorContext,
	    "-> %s%s", proxy? "(Proxy) " : "", bp);
    if ((blen -= strlen(bp)+1) < 0)
	xmlGenericError(xmlGenericErrorContext,
		"ERROR: overflowed buffer by %d bytes\n", -blen);
#endif
    ctxt->outptr = ctxt->out = bp;
    ctxt->state = XML_NANO_HTTP_WRITE;
    blen = strlen( ctxt->out );
#ifdef DEBUG_HTTP
    xmt_bytes = xmlNanoHTTPSend(ctxt, ctxt->out, blen );
    if ( xmt_bytes != blen )
        xmlGenericError( xmlGenericErrorContext,
			"xmlNanoHTTPMethodRedir:  Only %d of %d %s %s\n",
			xmt_bytes, blen,
			"bytes of HTTP headers sent to host",
			ctxt->hostname );
#else
    xmlNanoHTTPSend(ctxt, ctxt->out, blen );
#endif

    if ( input != NULL ) {
#ifdef DEBUG_HTTP
        xmt_bytes = xmlNanoHTTPSend( ctxt, input, ilen );

	if ( xmt_bytes != ilen )
	    xmlGenericError( xmlGenericErrorContext,
	    		"xmlNanoHTTPMethodRedir:  Only %d of %d %s %s\n",
			xmt_bytes, ilen,
			"bytes of HTTP content sent to host",
			ctxt->hostname );
#else
	xmlNanoHTTPSend( ctxt, input, ilen );
#endif
    }

    ctxt->state = XML_NANO_HTTP_READ;
    head = 1;

    while ((p = xmlNanoHTTPReadLine(ctxt)) != NULL) {
        if (head && (*p == 0)) {
	    head = 0;
	    ctxt->content = ctxt->inrptr;
	    xmlFree(p);
	    break;
	}
	xmlNanoHTTPScanAnswer(ctxt, p);

#ifdef DEBUG_HTTP
	xmlGenericError(xmlGenericErrorContext, "<- %s\n", p);
#endif
        xmlFree(p);
    }

    if ((ctxt->location != NULL) && (ctxt->returnValue >= 300) &&
        (ctxt->returnValue < 400)) {
#ifdef DEBUG_HTTP
	xmlGenericError(xmlGenericErrorContext,
		"\nRedirect to: %s\n", ctxt->location);
#endif
	while ( xmlNanoHTTPRecv(ctxt) > 0 ) ;
        if (nbRedirects < XML_NANO_HTTP_MAX_REDIR) {
	    nbRedirects++;
	    if (redirURL != NULL)
		xmlFree(redirURL);
	    redirURL = xmlMemStrdup(ctxt->location);
	    xmlNanoHTTPFreeCtxt(ctxt);
	    goto retry;
	}
	xmlNanoHTTPFreeCtxt(ctxt);
	if (redirURL != NULL) xmlFree(redirURL);
#ifdef DEBUG_HTTP
	xmlGenericError(xmlGenericErrorContext,
		"xmlNanoHTTPMethodRedir: Too many redirects, aborting ...\n");
#endif
	return(NULL);
    }

    if (contentType != NULL) {
	if (ctxt->contentType != NULL)
	    *contentType = xmlMemStrdup(ctxt->contentType);
	else
	    *contentType = NULL;
    }

    if ((redir != NULL) && (redirURL != NULL)) {
	*redir = redirURL;
    } else {
	if (redirURL != NULL)
	    xmlFree(redirURL);
	if (redir != NULL)
	    *redir = NULL;
    }

#ifdef DEBUG_HTTP
    if (ctxt->contentType != NULL)
	xmlGenericError(xmlGenericErrorContext,
		"\nCode %d, content-type '%s'\n\n",
	       ctxt->returnValue, ctxt->contentType);
    else
	xmlGenericError(xmlGenericErrorContext,
		"\nCode %d, no content-type\n\n",
	       ctxt->returnValue);
#endif

    return((void *) ctxt);
}
Esempio n. 2
0
static int
xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt)
{
#ifdef HAVE_POLL_H
    struct pollfd p;
#else
    fd_set rfd;
    struct timeval tv;
#endif


    while (ctxt->state & XML_NANO_HTTP_READ) {
        if (ctxt->in == NULL) {
            ctxt->in = (char *) xmlMallocAtomic(65000 * sizeof(char));
            if (ctxt->in == NULL) {
                xmlHTTPErrMemory("allocating input");
                ctxt->last = -1;
                return (-1);
            }
            ctxt->inlen = 65000;
            ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in;
        }
        if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) {
            int delta = ctxt->inrptr - ctxt->in;
            int len = ctxt->inptr - ctxt->inrptr;

            memmove(ctxt->in, ctxt->inrptr, len);
            ctxt->inrptr -= delta;
            ctxt->content -= delta;
            ctxt->inptr -= delta;
        }
        if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) {
            int d_inptr = ctxt->inptr - ctxt->in;
            int d_content = ctxt->content - ctxt->in;
            int d_inrptr = ctxt->inrptr - ctxt->in;
            char *tmp_ptr = ctxt->in;

            ctxt->inlen *= 2;
            ctxt->in = (char *) xmlRealloc(tmp_ptr, ctxt->inlen);
            if (ctxt->in == NULL) {
                xmlHTTPErrMemory("allocating input buffer");
                xmlFree(tmp_ptr);
                ctxt->last = -1;
                return (-1);
            }
            ctxt->inptr = ctxt->in + d_inptr;
            ctxt->content = ctxt->in + d_content;
            ctxt->inrptr = ctxt->in + d_inrptr;
        }
        ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0);
        if (ctxt->last > 0) {
            ctxt->inptr += ctxt->last;
            return (ctxt->last);
        }
        if (ctxt->last == 0) {
            return (0);
        }
        if (ctxt->last == -1) {
            switch (socket_errno()) {
                case EINPROGRESS:
                case EWOULDBLOCK:
#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
                case EAGAIN:
#endif
                    break;

                case ECONNRESET:
                case ESHUTDOWN:
                    return (0);

                default:
                    __xmlIOErr(XML_FROM_HTTP, 0, "recv failed\n");
                    return (-1);
            }
        }
#ifdef HAVE_POLL_H
        p.fd = ctxt->fd;
        p.events = POLLIN;
        if ((poll(&p, 1, timeout * 1000) < 1)
#if defined(EINTR)
            && (errno != EINTR)
#endif
            )
            return (0);
#else /* !HAVE_POLL_H */
#ifndef _WINSOCKAPI_
        if (ctxt->fd > FD_SETSIZE)
            return 0;
#endif

        tv.tv_sec = timeout;
        tv.tv_usec = 0;
        FD_ZERO(&rfd);

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4018)
#endif

        FD_SET(ctxt->fd, &rfd);

#ifdef _MSC_VER
#pragma warning(pop)
#endif

        if ((select(ctxt->fd + 1, &rfd, NULL, NULL, &tv) < 1)
#if defined(EINTR)
            && (errno != EINTR)
#endif
            )
            return (0);
#endif /* !HAVE_POLL_H */
    }
    return (0);
}
Esempio n. 3
0
/**
 * xmlBufResize:
 * @buf:  the buffer to resize
 * @size:  the desired size
 *
 * Resize a buffer to accommodate minimum size of @size.
 *
 * Returns  0 in case of problems, 1 otherwise
 */
int
xmlBufResize(xmlBufPtr buf, size_t size)
{
    unsigned int newSize;
    xmlChar* rebuf = NULL;
    size_t start_buf;

    if ((buf == NULL) || (buf->error))
        return(0);
    CHECK_COMPAT(buf)

    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);

    /* Don't resize if we don't have to */
    if (size < buf->size)
        return 1;

    /* figure out new size */
    switch (buf->alloc){
	case XML_BUFFER_ALLOC_IO:
	case XML_BUFFER_ALLOC_DOUBLEIT:
	    /*take care of empty case*/
	    newSize = (buf->size ? buf->size*2 : size + 10);
	    while (size > newSize) {
	        if (newSize > UINT_MAX / 2) {
	            xmlBufMemoryError(buf, "growing buffer");
	            return 0;
	        }
	        newSize *= 2;
	    }
	    break;
	case XML_BUFFER_ALLOC_EXACT:
	    newSize = size+10;
	    break;
        case XML_BUFFER_ALLOC_HYBRID:
            if (buf->use < BASE_BUFFER_SIZE)
                newSize = size;
            else {
                newSize = buf->size * 2;
                while (size > newSize) {
                    if (newSize > UINT_MAX / 2) {
                        xmlBufMemoryError(buf, "growing buffer");
                        return 0;
                    }
                    newSize *= 2;
                }
            }
            break;

	default:
	    newSize = size+10;
	    break;
    }

    if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
        start_buf = buf->content - buf->contentIO;

        if (start_buf > newSize) {
	    /* move data back to start */
	    memmove(buf->contentIO, buf->content, buf->use);
	    buf->content = buf->contentIO;
	    buf->content[buf->use] = 0;
	    buf->size += start_buf;
	} else {
	    rebuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + newSize);
	    if (rebuf == NULL) {
		xmlBufMemoryError(buf, "growing buffer");
		return 0;
	    }
	    buf->contentIO = rebuf;
	    buf->content = rebuf + start_buf;
	}
    } else {
	if (buf->content == NULL) {
	    rebuf = (xmlChar *) xmlMallocAtomic(newSize);
	} else if (buf->size - buf->use < 100) {
	    rebuf = (xmlChar *) xmlRealloc(buf->content, newSize);
        } else {
	    /*
	     * if we are reallocating a buffer far from being full, it's
	     * better to make a new allocation and copy only the used range
	     * and free the old one.
	     */
	    rebuf = (xmlChar *) xmlMallocAtomic(newSize);
	    if (rebuf != NULL) {
		memcpy(rebuf, buf->content, buf->use);
		xmlFree(buf->content);
		rebuf[buf->use] = 0;
	    }
	}
	if (rebuf == NULL) {
	    xmlBufMemoryError(buf, "growing buffer");
	    return 0;
	}
	buf->content = rebuf;
    }
    buf->size = newSize;
    UPDATE_COMPAT(buf)

    return 1;
}
Esempio n. 4
0
/**
 * exsltCryptoRc4DecryptFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * computes the sha1 hash of a string and returns as hex
 */
static void
exsltCryptoRc4DecryptFunction (xmlXPathParserContextPtr ctxt, int nargs) {

    int key_len = 0, key_size = 0;
    int str_len = 0, bin_len = 0, ret_len = 0;
    xmlChar *key = NULL, *str = NULL, *padkey = NULL, *bin =
	NULL, *ret = NULL;
    xsltTransformContextPtr tctxt = NULL;

    if (nargs != 2) {
	xmlXPathSetArityError (ctxt);
	return;
    }
    tctxt = xsltXPathGetTransformContext(ctxt);

    str = xmlXPathPopString (ctxt);
    str_len = xmlUTF8Strlen (str);

    if (str_len == 0) {
	xmlXPathReturnEmptyString (ctxt);
	xmlFree (str);
	return;
    }

    key = xmlXPathPopString (ctxt);
    key_len = xmlUTF8Strlen (key);

    if (key_len == 0) {
	xmlXPathReturnEmptyString (ctxt);
	xmlFree (key);
	xmlFree (str);
	return;
    }

    padkey = xmlMallocAtomic (RC4_KEY_LENGTH + 1);
    if (padkey == NULL) {
	xsltTransformError(tctxt, NULL, tctxt->inst,
	    "exsltCryptoRc4EncryptFunction: Failed to allocate padkey\n");
	tctxt->state = XSLT_STATE_STOPPED;
	xmlXPathReturnEmptyString (ctxt);
	goto done;
    }
    memset(padkey, 0, RC4_KEY_LENGTH + 1);
    key_size = xmlUTF8Strsize (key, key_len);
    if ((key_size > RC4_KEY_LENGTH) || (key_size < 0)) {
	xsltTransformError(tctxt, NULL, tctxt->inst,
	    "exsltCryptoRc4EncryptFunction: key size too long or key broken\n");
	tctxt->state = XSLT_STATE_STOPPED;
	xmlXPathReturnEmptyString (ctxt);
	goto done;
    }
    memcpy (padkey, key, key_size);

/* decode hex to binary */
    bin_len = str_len;
    bin = xmlMallocAtomic (bin_len);
    if (bin == NULL) {
	xsltTransformError(tctxt, NULL, tctxt->inst,
	    "exsltCryptoRc4EncryptFunction: Failed to allocate string\n");
	tctxt->state = XSLT_STATE_STOPPED;
	xmlXPathReturnEmptyString (ctxt);
	goto done;
    }
    ret_len = exsltCryptoHex2Bin (str, str_len, bin, bin_len);

/* decrypt the binary blob */
    ret = xmlMallocAtomic (ret_len);
    if (ret == NULL) {
	xsltTransformError(tctxt, NULL, tctxt->inst,
	    "exsltCryptoRc4EncryptFunction: Failed to allocate result\n");
	tctxt->state = XSLT_STATE_STOPPED;
	xmlXPathReturnEmptyString (ctxt);
	goto done;
    }
    PLATFORM_RC4_DECRYPT (ctxt, padkey, bin, ret_len, ret, ret_len);

    xmlXPathReturnString (ctxt, ret);

done:
    if (key != NULL)
	xmlFree (key);
    if (str != NULL)
	xmlFree (str);
    if (padkey != NULL)
	xmlFree (padkey);
    if (bin != NULL)
	xmlFree (bin);
}
Esempio n. 5
0
/**
 * exsltCryptoRc4EncryptFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * computes the sha1 hash of a string and returns as hex
 */
static void
exsltCryptoRc4EncryptFunction (xmlXPathParserContextPtr ctxt, int nargs) {

    int key_len = 0, key_size = 0;
    int str_len = 0, bin_len = 0, hex_len = 0;
    xmlChar *key = NULL, *str = NULL, *padkey = NULL;
    xmlChar *bin = NULL, *hex = NULL;

    if ((nargs < 1) || (nargs > 3)) {
	xmlXPathSetArityError (ctxt);
	return;
    }

    str = xmlXPathPopString (ctxt);
    str_len = xmlUTF8Strlen (str);

    if (str_len == 0) {
	xmlXPathReturnEmptyString (ctxt);
	xmlFree (str);
	return;
    }

    key = xmlXPathPopString (ctxt);
    key_len = xmlUTF8Strlen (str);

    if (key_len == 0) {
	xmlXPathReturnEmptyString (ctxt);
	xmlFree (key);
	xmlFree (str);
	return;
    }

    padkey = xmlMallocAtomic (RC4_KEY_LENGTH);
    key_size = xmlUTF8Strsize (key, key_len);
    memcpy (padkey, key, key_size);
    memset (padkey + key_size, '\0', sizeof (padkey));

/* encrypt it */
    bin_len = str_len;
    bin = xmlStrdup (str);
    if (bin == NULL) {
	xmlXPathReturnEmptyString (ctxt);
	goto done;
    }
    PLATFORM_RC4_ENCRYPT (ctxt, padkey, str, str_len, bin, bin_len);

/* encode it */
    hex_len = str_len * 2 + 1;
    hex = xmlMallocAtomic (hex_len);
    if (hex == NULL) {
	xmlXPathReturnEmptyString (ctxt);
	goto done;
    }

    exsltCryptoBin2Hex (bin, str_len, hex, hex_len);
    xmlXPathReturnString (ctxt, hex);

done:
    if (key != NULL)
	xmlFree (key);
    if (str != NULL)
	xmlFree (str);
    if (padkey != NULL)
	xmlFree (padkey);
    if (bin != NULL)
	xmlFree (bin);
}