Exemple #1
0
void printStat(HashTable *hashT)
{
	printf("\n****************************************************************\n");
	printf("%d elements\n", HTLoad(hashT));
	printf("%.5f load-factor\n", loadFactor(hashT));
	printf("%d filled cells\n", HTLoad(hashT));
	printf("%.5f collision level\n", (double)elemQuant(hashT) / (double)HTLoad(hashT));
	printf("****************************************************************\n");
}
Exemple #2
0
/*
**	Client side authentication AFTER filter
**	---------------------------------------
**	The client side authentication filter uses the 
**	user dialog messages registered in the HTAlert module.
**	By default these are the ones used by the line mode browser but you can
**	just register something else.
*/
PUBLIC int HTAuthFilter (HTRequest * request, HTResponse * response,
			 void * param, int status)
{
    /*
    ** Ask the authentication module to call the right challenge parser
    ** that understands this scheme
    */
    if (HTAA_afterFilter(request, response, param, status) == HT_OK) {

	/*
	** Start request with new credentials. As with the redirection filter
	** we reuse the same request object which means that we must
	** keep this around until the redirected request has terminated
	*/
	HTLoad(request, NO);

	/*
	**  We return HT_ERROR to make sure that this is the last handler to be
	**  called. We do this as we don't want any other filter to delete the 
	**  request object now when we have just started a new one ourselves
	*/
	return HT_ERROR;
    }
    return HT_OK;
}
Exemple #3
0
void addString(HashTable *hashT, char* string)
{
	if (HTLoad(hashT) != hashT->size)
	{
		int hash = polynomeHash(string, hashT->size);
		{

		}
		hashT->table[hash] = string;
	}
}
Exemple #4
0
/*	Partial Response MIME parser stream
**	-----------------------------------
**	In case we sent a Range conditional GET we may get back a partial
**	response. This response must be appended to the already existing
**	cache entry before presented to the user.
**	We do this by continuing to load the new object into a temporary 
**	buffer and at the same time start the cache load of the already
**	existing object. When we have loaded the cache we merge the two
**	buffers.
*/
PUBLIC HTStream * HTMIMEPartial (HTRequest *	request,
				 void *		param,
				 HTFormat	input_format,
				 HTFormat	output_format,
				 HTStream *	output_stream)
{
#ifndef NO_CACHE
    HTParentAnchor * anchor = HTRequest_anchor(request);
    HTFormat format = HTAnchor_format(anchor);
    HTStream * pipe = NULL;

    /*
    **  The merge stream is a place holder for where we can put data when it
    **  arrives. We have two feeds: one from the cache and one from the net.
    **  We call the stream stack already now to get the right output stream.
    **  We can do this as we already know the content type from when we got the
    **  first part of the object.
    */
    HTStream * merge = HTMerge(HTStreamStack(format,
					     output_format, output_stream,
					     request, YES), 2);

    /*
    **  Now we create the MIME parser stream in partial data mode. We also
    **  set the target to our merge stream.
    */
    HTStream * me = HTMIMEConvert(request, param, input_format,
				  output_format, output_stream);
    me->mode |= HT_MIME_PARTIAL;
    me->target = merge;

#if 0
    /* JK: this doesn't work because this work is repeated before */
    /*
    **  Create the cache append stream, and a Tee stream
    */
    {
	HTStream * append = HTStreamStack(WWW_CACHE_APPEND, output_format,
					  output_stream, request, NO);
	if (append) me->target = HTTee(me->target, append, NULL);
    }
#endif

    /*
    **  Create the pipe buffer stream to buffer the data that we read
    **  from the network
    */
    if ((pipe = HTPipeBuffer(me->target, 0))) me->target = pipe;

    /*
    **  Now start the second load from the cache. First we read this data from
    **  the cache and then we flush the data that we have read from the net.
    */
    {
	HTRequest * cache_request = HTRequest_new();

	/*
	**  Set the output format to source and the output stream to the
	**  merge stream. As we have already set up the stream pipe, we just 
	**  load it as source.
	*/
	HTRequest_setOutputFormat(cache_request, WWW_SOURCE);
	HTRequest_setOutputStream(cache_request, merge);

	/*
	**  Bind the anchor to the new request and also register a local
	**  AFTER filter to flush the pipe buffer so that we can get
	**  rest of the data through. 
	*/
	HTRequest_setAnchor(cache_request, (HTAnchor *) anchor);
	HTRequest_addBefore(cache_request, HTCacheLoadFilter, NULL, NULL,
			    HT_FILTER_FIRST, YES);
	HTRequest_addAfter(cache_request, HTCacheFlushFilter, NULL, pipe,
			   HT_ALL, HT_FILTER_FIRST, YES);

	HTTRACE(STREAM_TRACE, "Partial..... Starting cache load\n");
	HTLoad(cache_request, NO);
    }
    return me;
#else
    return NULL;
#endif
}
Exemple #5
0
PRIVATE int FileEvent (SOCKET soc, void * pVoid, HTEventType type)
{
    file_info *file = pVoid;			      /* Specific access information */
    int status = HT_ERROR;
    HTNet * net = file->net;
    HTRequest * request = HTNet_request(net);
    HTParentAnchor * anchor = HTRequest_anchor(request);

    /*
    ** Initiate a new file structure and bind to request structure
    ** This is actually state FILE_BEGIN, but it can't be in the state
    ** machine as we need the structure first.
    */
    if (type == HTEvent_CLOSE) {				      /* Interrupted */
	HTRequest_addError(request, ERR_FATAL, NO, HTERR_INTERRUPTED,
			   NULL, 0, "HTLoadFile");
	FileCleanup(request, HT_INTERRUPTED);
	return HT_OK;
    }


    /* Now jump into the machine. We know the state from the previous run */
    while (1) {
	switch (file->state) {
	case FS_BEGIN:

	    /* We only support safe (GET, HEAD, etc) methods for the moment */
	    if (!HTMethod_isSafe(HTRequest_method(request))) {
		HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_ALLOWED,
				   NULL, 0, "HTLoadFile");
		file->state = FS_ERROR;
		break;
	    }

	    /* Check whether we have access to local disk at all */
	    if (HTLib_secure()) {
		HTTRACE(PROT_TRACE, "LoadFile.... No access to local file system\n");
		file->state = FS_TRY_FTP;
		break;
	    }
	    file->local = HTWWWToLocal(HTAnchor_physical(anchor), "",
				       HTRequest_userProfile(request));
	    if (!file->local) {
		file->state = FS_TRY_FTP;
		break;
	    }

	    /* Create a new host object and link it to the net object */
	    {
		HTHost * host = NULL;
		if ((host = HTHost_new("localhost", 0)) == NULL) return HT_ERROR;
		HTNet_setHost(net, host);
		if (HTHost_addNet(host, net) == HT_PENDING) {
		    HTTRACE(PROT_TRACE, "HTLoadFile.. Pending...\n");
		    /* move to the hack state */
		    file->state = FS_PENDING;
		    return HT_OK;
		}
	    }
	    file->state = FS_DO_CN;
	    break;

	case FS_PENDING:
	    /*
	    ** 2000/08/10 JK : This is a funny state. Because of the
	    ** internal libwww stacks, when doing multiple local
	    ** requests (e.g., while using the Robot), we need to ask
	    ** again for the host object. If we had jumped directly to
	    ** the FS_DO_CN state, libwww would have blocked because
	    ** of socket starvation.
	    ** This state is similar to FS_BEGINNING, but just requests 
	    ** the host object. 
	    ** YES. THIS IS AN UGLY HACK!!
	    */
	    {
		HTHost * host = NULL;
		if ((host = HTHost_new("localhost", 0)) == NULL) return HT_ERROR;
		HTNet_setHost(net, host);
		if (HTHost_addNet(host, net) == HT_PENDING) {
		    HTTRACE(PROT_TRACE, "HTLoadFile.. Pending...\n");
		    file->state = FS_PENDING;
		    return HT_OK;
		}
	    }
	    file->state = FS_DO_CN;
	    break;

	case FS_DO_CN:
	    /*
	    ** If we have to do content negotiation then find the object that
	    ** fits best into either what the client has indicated in the
	    ** accept headers or what the client has registered on its own.
	    ** The object chosen can in fact be a directory! However, content
	    ** negotiation only makes sense if we can read the directory!
	    ** We stat the file in order to find the size and to see it if
	    ** exists.
	    */
	    if (HTRequest_negotiation(request) &&
		HTMethod_isSafe(HTRequest_method(request))) {
 		char * conneg = HTMulti(request, file->local,&file->stat_info);
		if (conneg) {
		    HT_FREE(file->local);
		    file->local = conneg;
		    HTAnchor_setPhysical(anchor, conneg);
		    HTTRACE(PROT_TRACE, "Load File... Found `%s\'\n" _ conneg);
		} else {
		    HTTRACE(PROT_TRACE, "Load File... Not found - even tried content negotiation\n");
		    HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_FOUND,
				       NULL, 0, "HTLoadFile");
		    file->state = FS_ERROR;
		    break;
		}
	    } else {
		if (HT_STAT(file->local, &file->stat_info) == -1) {
		    HTTRACE(PROT_TRACE, "Load File... Not found `%s\'\n" _ file->local);
		    HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_FOUND,
				       NULL, 0, "HTLoadFile");
		    file->state = FS_ERROR;
		    break;
		}
	    }

	    /*
	    ** Check to see if the 'localname' is in fact a directory.
	    ** Note that we can't do a HEAD on a directory
	    */
	    if (((file->stat_info.st_mode) & S_IFMT) == S_IFDIR) {
		if (HTRequest_method(request) == METHOD_GET)
		    file->state = FS_PARSE_DIR;
		else {
		    HTRequest_addError(request, ERR_INFO, NO, HTERR_NO_CONTENT,
				       NULL, 0, "HTLoadFile");
		    file->state = FS_NO_DATA;
		}
		break;
	    }

	    /*
	    ** If empty file then only serve it if it is editable. We also get
	    ** the bindings for the file suffixes in lack of better bindings
	    */
	    {
		BOOL editable = HTEditable(file->local, &file->stat_info);
		if (file_suffix_binding) HTBind_getAnchorBindings(anchor);
		if (editable) HTAnchor_appendAllow(anchor, METHOD_PUT);

		/* Set the file size */
		if (file->stat_info.st_size)
		    HTAnchor_setLength(anchor, file->stat_info.st_size);

		/* Set the file last modified time stamp */
		if (file->stat_info.st_mtime > 0)
		    HTAnchor_setLastModified(anchor, file->stat_info.st_mtime);

		/* Check to see if we can edit it */
		if (!editable && !file->stat_info.st_size) {
		    HTRequest_addError(request, ERR_INFO, NO, HTERR_NO_CONTENT,
				       NULL, 0, "HTLoadFile");
		    file->state = FS_NO_DATA;
		} else {
		    file->state = (HTRequest_method(request)==METHOD_GET) ? 
			FS_NEED_OPEN_FILE : FS_GOT_DATA;
		}
	    }
	    break;

	  case FS_NEED_OPEN_FILE:
	    status = HTFileOpen(net, file->local, HT_FB_RDONLY);
	    if (status == HT_OK) {
		/* 
		** Create the stream pipe FROM the channel to the application.
		** The target for the input stream pipe is set up using the
		** stream stack.
		*/
		{
		    HTStream * rstream = HTStreamStack(HTAnchor_format(anchor),
						       HTRequest_outputFormat(request),
						       HTRequest_outputStream(request),
						       request, YES);
		    HTNet_setReadStream(net, rstream);
		    HTRequest_setOutputConnected(request, YES);
		}

		/*
		** Create the stream pipe TO the channel from the application
		** and hook it up to the request object
		*/
		{
		    HTOutputStream * output = HTNet_getOutput(net, NULL, 0);
		    HTRequest_setInputStream(request, (HTStream *) output);
		}

		/*
		** Set up concurrent read/write if this request isn't the
		** source for a PUT or POST. As source we don't start reading
		** before all destinations are ready. If destination then
		** register the input stream and get ready for read
		*/
		if (HTRequest_isSource(request) && !HTRequest_destinationsReady(request))
		    return HT_OK;
		HTRequest_addError(request, ERR_INFO, NO, HTERR_OK, NULL, 0,
				   "HTLoadFile");
		file->state = FS_NEED_BODY;

		/* If we are _not_ using preemptive mode and we are Unix fd's
		** then return here to get the same effect as when we are
		** connecting to a socket. That way, HTFile acts just like any
		** other protocol module even though we are in fact doing
		** blocking connect
		*/
		if (HTEvent_isCallbacksRegistered()) {
		    if (!HTRequest_preemptive(request)) {
			if (!HTNet_preemptive(net)) {
			    HTTRACE(PROT_TRACE, "HTLoadFile.. Returning\n");
			    HTHost_register(HTNet_host(net), net, HTEvent_READ);
			} else if (!file->timer) {
			    HTTRACE(PROT_TRACE, "HTLoadFile.. Returning\n");
			    file->timer =
				HTTimer_new(NULL, ReturnEvent, file, 1, YES, NO);
			}
			return HT_OK;
		    }
		}
	    } else if (status == HT_WOULD_BLOCK || status == HT_PENDING)
		return HT_OK;
	    else {
		HTRequest_addError(request, ERR_INFO, NO, HTERR_INTERNAL,
				   NULL, 0, "HTLoadFile");
		file->state = FS_ERROR;		       /* Error or interrupt */
	    }
	    break;

	  case FS_NEED_BODY:
	    status = HTHost_read(HTNet_host(net), net);
	    if (status == HT_WOULD_BLOCK)
		return HT_OK;
	    else if (status == HT_LOADED || status == HT_CLOSED) {
		file->state = FS_GOT_DATA;
	    } else {
		HTRequest_addError(request, ERR_INFO, NO, HTERR_FORBIDDEN,
				   NULL, 0, "HTLoadFile");
		file->state = FS_ERROR;
	    }
	    break;

	  case FS_PARSE_DIR:
	    status = HTFile_readDir(request, file);
	    if (status == HT_LOADED)
		file->state = FS_GOT_DATA;
	    else
		file->state = FS_ERROR;
	    break;

	  case FS_TRY_FTP:
	    {
		char *url = HTAnchor_physical(anchor);
		HTAnchor *anchor;
		char *newname = NULL;
		StrAllocCopy(newname, "ftp:");
		if (!strncmp(url, "file:", 5))
		    StrAllocCat(newname, url+5);
		else
		    StrAllocCat(newname, url);
		anchor = HTAnchor_findAddress(newname);
		HTRequest_setAnchor(request, anchor);
		HT_FREE(newname);
		FileCleanup(request, HT_IGNORE);
		return HTLoad(request, YES);
	    }
	    break;

	  case FS_GOT_DATA:
	    FileCleanup(request, HT_LOADED);
	    return HT_OK;
	    break;

	  case FS_NO_DATA:
	    FileCleanup(request, HT_NO_DATA);
	    return HT_OK;
	    break;

	  case FS_RETRY:
	    FileCleanup(request, HT_RETRY);
	    return HT_OK;
	    break;

	  case FS_ERROR:
	    FileCleanup(request, HT_ERROR);
	    return HT_OK;
	    break;
	}
    } /* End of while(1) */
}
Exemple #6
0
PRIVATE int ServEvent (SOCKET soc, void * pVoid, HTEventType type)
{
    https_info * http = (https_info *)pVoid;
    int status = HT_ERROR;
    HTNet * net = http->net;
    HTRequest * request = HTNet_request(net);

    if (!net || !request) {
        HTTRACE(PROT_TRACE, "Serv HTTP... Invalid argument\n");
        return HT_ERROR;
    }

    if (type == HTEvent_CLOSE) {			      /* Interrupted */
        ServerCleanup(request, net, HT_INTERRUPTED);
        return HT_OK;
    } else
        http = (https_info *) HTNet_context(net);	/* Get existing copy */

    /* Now jump into the machine. We know the state from the previous run */
    while (1) {
        switch (http->state) {
        case HTTPS_BEGIN:
        {
            /*
            ** Create the request to handle the request and inherit the old
            ** context
            */
            HTRequest * client = HTRequest_new();
            void * context = HTRequest_context(request);
            if (context) HTRequest_setContext(client, context);
            HTRequest_setOutputConnected(client, NO);
            HTRequest_setGnHd(client, HTRequest_gnHd(request));
            HTRequest_setRsHd(client, HTRequest_rsHd(request));
            HTRequest_setEnHd(client, HTRequest_enHd(request));
            HTList_addObject(http->clients, client);

            /*
            ** Create the HTTP output stream for generating the reply
            ** FROM the client request to the channel
            */
            {
                HTOutputStream * output = HTNet_getOutput(net, NULL, 0);
                HTStream * app = HTTPReply_new(client, http,(HTStream*)output);
                HTRequest_setOutputStream(client, app);
                HTRequest_setOutputFormat(client, WWW_SOURCE);
            }
            http->state = HTTPS_NEED_REQUEST;
        }
        break;

        case HTTPS_NEED_REQUEST:
            if (type == HTEvent_READ || type == HTEvent_BEGIN) {
                status = HTHost_read(net->host, net);
                if (status == HT_WOULD_BLOCK)
                    return HT_OK;
                else if (status == HT_CLOSED)
                    http->state = HTTPS_OK;
                else if (status==HT_LOADED || status==HT_PAUSE) {
                    http->state = HTTPS_LOAD_CLIENT;
                } else
                    http->state = HTTPS_ERROR;
            } else
                http->state = HTTPS_ERROR;
            break;

        case HTTPS_LOAD_CLIENT:
        {
            HTRequest * client = HTList_removeFirstObject(http->clients);
            HTLoad(client, NO);
            http->state = HTTPS_BEGIN;
            break;
        }

        case HTTPS_OK:
            ServerCleanup(request, net, HT_IGNORE);
            return HT_OK;

        case HTTPS_ERROR:
            ServerCleanup(request, net, HT_ERROR);
            return HT_OK;
        }
    }
}
Exemple #7
0
double loadFactor(HashTable *hashT)
{
	return (double)HTLoad(hashT) / (double)hashT->size;
}