コード例 #1
0
ファイル: http.c プロジェクト: mrphishxxx/proxenet
/**
* Add old IE support (Compatibility View) for POST requests by forcing a 2nd read on the
* server socket, to make IE send the POST body.
* Tests revealed that this mode does not change the behaviour for recent browser. Therefore,
* it can be used all the time. Option -i allows to disable it.
*
* @return 0 if successful, -1 otherwise
*/
int ie_compat_read_post_body(sock_t sock, request_t* req, proxenet_ssl_context_t* sslctx)
{
        int nb;
        size_t old_len, body_len;
        char *body, *clen;

        /* to speed-up, disregard requests without body */
        if (strcmp(req->http_infos.method, "POST")!=0 && \
            strcmp(req->http_infos.method, "PUT")!=0)
                return 0;

        /* read Content-Length header */
        clen = get_header_by_name(req->data, "Content-Length: ");
        if (!clen){
                xlog(LOG_ERROR, "%s\n", "Extending IE POST: No Content-Length");
                return -1;
        }

        /* if Content-Length is zero */
        body_len = (size_t)atoi(clen);
        proxenet_xfree(clen);

        if (body_len==0){
                return 0;
        }

        /* if everything has already been sent (i.e. end of already received buffer is not CRLF*2) */
        if (req->data[ req->size-4 ] != '\r')
                return 0;
        if (req->data[ req->size-3 ] != '\n')
                return 0;
        if (req->data[ req->size-2 ] != '\r')
                return 0;
        if (req->data[ req->size-1 ] != '\n')
                return 0;

        /* read data (if any) */
        nb = proxenet_read_all(sock, &body, sslctx);
        if (nb<0){
                xlog(LOG_ERROR, "%s\n", "Extending IE POST: failed to read");
                return -1;
        }

        /* and extend the request buffer */
        if (nb>0){
                old_len = req->size;
                req->size = old_len + (size_t)nb;
                req->data = proxenet_xrealloc(req->data, req->size);
                memcpy(req->data + old_len, body, (size_t)nb);
        }

        proxenet_xfree(body);

#ifdef DEBUG
        xlog(LOG_DEBUG, "Extending request for IE: new_size=%d (content-length=%d)\n",
             req->size, body_len);
#endif

        return 0;
}
コード例 #2
0
ファイル: http.c プロジェクト: mrphishxxx/proxenet
/**
 * Modifies the HTTP request to strip out the protocol and hostname
 * If successful, the request will be modified on output of this function as a
 * valid HTTP request :
 *
 * METHOD /PATH HTTP/1.1[...]
 *
 * @return 0 if no error was encountered, -1 otherwise.
 */
int format_http_request(request_t* req)
{
        size_t request_len = req->size;
        size_t new_request_len = 0;
        char **request = &req->data;
        char *old_ptr, *new_ptr, *ptr;
        unsigned int i;
        int offlen;

        switch(get_http_protocol(req)){
                case HTTP:
                        /* check that !NULL is done by get_http_protocol */
                        ptr = strstr(*request, HTTP_PROTO_STRING);

                        /* -1 because of \x00 added by sizeof */
                        offlen = sizeof(HTTP_PROTO_STRING)-1;
                        break;

                case HTTPS:
                        ptr = strstr(*request, HTTPS_PROTO_STRING);
                        offlen = sizeof(HTTPS_PROTO_STRING)-1;
                        break;

                case WS:
                        ptr = strstr(*request, WS_PROTO_STRING);
                        offlen = sizeof(WS_PROTO_STRING)-1;
                        break;

                case TRANSPARENT:
                        return 0;

                default:
                        return -1;
        }

        old_ptr = ptr;
        new_ptr = strchr(old_ptr + offlen, '/');
        if (!new_ptr) {
                xlog(LOG_ERROR, "%s\n", "Cannot find path (must not be implicit)");
                return -1;
        }

        new_request_len = request_len - (new_ptr-old_ptr);

#ifdef DEBUG
        xlog(LOG_DEBUG, "Formatting HTTP request (%dB->%dB)\n", request_len, new_request_len);
#endif

        for (i=0; i<new_request_len - (old_ptr-*request);i++) {
                *(old_ptr+i) = *(new_ptr+i);
        }

        req->data = proxenet_xrealloc(*request, new_request_len);
        req->size = new_request_len;

        return 0;
}
コード例 #3
0
ファイル: http.c プロジェクト: rkornmeyer/proxenet
/**
 * Modifies the HTTP request to strip out the protocol and hostname
 * If successful, the request will be modified on output of this function as a
 * valid HTTP request :
 * METHOD /PATH HTTP/1.1[...]
 *
 * @return 0 if no error was encountered, -1 otherwise.
 */
int format_http_request(char** request, size_t* request_len)
{
        size_t new_request_len = 0;
        char *old_ptr, *new_ptr, *ptr;
        unsigned int i;
        int offlen;

        /* Move to beginning of URL */
        for(ptr=*request; ptr && *ptr!=' ' && *ptr!='\x00'; ptr++);

        if(!ptr || *ptr!=' '){
                xlog(LOG_ERROR, "%s\n", "HTTP request has incorrect format");
                return -1;
        }

        ++ptr;
        if(*ptr=='/'){
                /* this indicates that the request is well formed already */
                /* this case would happen only when using in transparent mode */
                return 0;
        }

        if( strncmp(ptr, HTTP_PROTO_STRING, sizeof(HTTP_PROTO_STRING)-1)==0 ){
                offlen = sizeof(HTTP_PROTO_STRING)-1;    // -1 because of \x00 added by sizeof
        } else if( strncmp(ptr, HTTPS_PROTO_STRING, sizeof(HTTP_PROTO_STRING)-1)==0 ){
                offlen = sizeof(HTTPS_PROTO_STRING)-1;
        } else {
                xlog(LOG_ERROR, "Cannot find protocol (%s|%s) in request:\n%s\n",
                     HTTP_STRING, HTTPS_STRING, *request);
                return -1;
        }

        /* here offlen > 0 */
        old_ptr = ptr;
        new_ptr = strchr(old_ptr + offlen, '/');
        if (!new_ptr) {
                xlog(LOG_ERROR, "%s\n", "Cannot find path (must not be implicit)");
                return -1;
        }

        new_request_len = *request_len - (new_ptr-old_ptr);

#ifdef DEBUG
        xlog(LOG_DEBUG, "Formatting HTTP request (%dB->%dB)\n", *request_len, new_request_len);
#endif

        for (i=0; i<new_request_len - (old_ptr-*request);i++) {
                *(old_ptr+i) = *(new_ptr+i);
        }

        *request = proxenet_xrealloc(*request, new_request_len);
        *request_len = new_request_len;

        return 0;
}
コード例 #4
0
ファイル: socket.c プロジェクト: hugsy/proxenet
/**
 * Read all the data pending in the socket.
 * The buffer with the data is allocated by proxenet_read_all() and *MUST* be free-ed
 * by the caller.
 *
 * @return the number of bytes read, or -1 if an error occured
 */
int proxenet_read_all(sock_t sock, char** ptr, proxenet_ssl_context_t* ssl)
{
	int ret = 0;
	unsigned int total_bytes_read = 0;
	size_t malloced_size = sizeof(char) * MAX_READ_SIZE;
	char *data, *current_offset;

	current_offset = NULL;
	*ptr = NULL;

	data = (char*)proxenet_xmalloc(malloced_size+1);

	while (true) {
		current_offset = data + total_bytes_read;

		if (ssl) {
			/* ssl */
			ret = proxenet_ssl_read(ssl, current_offset, MAX_READ_SIZE);
		} else {
			/* plaintext */
			ret = proxenet_read(sock, current_offset, MAX_READ_SIZE);
		}
		if (ret < 0) {
			proxenet_xfree(data);
                        xlog(LOG_ERROR, "read(%d) = %d\n", sock, ret);
			return ret;
		}

		total_bytes_read += ret;

		if (ret == MAX_READ_SIZE) {
			/* may be more data to come */
			malloced_size += sizeof(char) * MAX_READ_SIZE;
			data = (char*)proxenet_xrealloc(data, malloced_size+1);
#ifdef DEBUG
			xlog(LOG_DEBUG, "Increasing recv buf size to %d\n", malloced_size+1);
#endif
			continue;
		}

		break;
	}

	if (total_bytes_read == 0) {
		proxenet_xfree(data);
		return -ENODATA;
	}

	*ptr = data;

	return total_bytes_read;
}
コード例 #5
0
ファイル: http.c プロジェクト: steeve85/proxenet
bool is_valid_http_request(char** request, size_t* request_len) 
{
	size_t new_request_len = -1;
	char *old_ptr, *new_ptr;
	int i = -1;
	int offlen = -1;
	
	old_ptr = new_ptr = NULL;
	old_ptr = strstr(*request, "http://");
	if (old_ptr) 
		offlen = 7;
	else {
		old_ptr = strstr(*request, "https://");
		if (old_ptr) 
			offlen = 8;
	}

	if (offlen < 0) {
		xlog(LOG_ERROR, "Cannot find protocol (http|https) in request:\n%s\n", *request);
		return false;
	}
	
	new_ptr = strchr(old_ptr + offlen, '/');
	if (!new_ptr) {
		xlog(LOG_ERROR, "%s\n", "Cannot find path (must not be implicit)");
		return false;
	}

	new_request_len = *request_len - (new_ptr-old_ptr);

#ifdef DEBUG
	xlog(LOG_DEBUG, "Adjusting buffer to %d->%d bytes\n", *request_len, new_request_len);
#endif
	
	for (i=0; i<new_request_len - (old_ptr-*request);i++)
		*(old_ptr+i) = *(new_ptr+i);
	
	*request = proxenet_xrealloc(*request, new_request_len);
	*request_len = new_request_len;

	return true;
}