コード例 #1
0
ファイル: HTTPServ.c プロジェクト: Rjoydip/libwww
PUBLIC int HTServHTTP (SOCKET soc, HTRequest * request)
{
    HTNet * net = HTRequest_net(request);
    https_info * http;			    /* Specific protocol information */

    /*
    ** Initiate a new https object and bind to request object
    ** This is actually state HTTPS_BEGIN, but it can't be in the state
    ** machine as we need the object first (chicken and egg problem).
    */
    HTTRACE(PROT_TRACE, "Serv HTTP... on socket %d\n" _ soc);
    if ((http = (https_info *) HT_CALLOC(1, sizeof(https_info))) == NULL)
        HT_OUTOFMEM("HTServHTTP");
    http->server = request;
    http->state = HTTPS_BEGIN;
    http->clients = HTList_new();
    HTNet_setContext(net, http);

    /*
    ** Create the stream pipe FROM the channel to the server request.
    */
    net->readStream = HTTPReceive_new(request, http);
    HTRequest_setOutputConnected(request, YES);
    http->state = HTTPS_BEGIN;

    HTNet_setEventCallback(net, ServEvent);
    HTNet_setEventParam(net, http);  /* callbacks get http* */

    return ServEvent(soc, http, HTEvent_BEGIN);		/* get it started - ops is ignored */
}
コード例 #2
0
ファイル: HTFile.c プロジェクト: BackupTheBerlios/texlive
/*	FileCleanup
**	-----------
**      This function closes the connection and frees memory.
**      Returns YES on OK, else NO
*/
PRIVATE int FileCleanup (HTRequest *req, int status)
{
    HTNet * net = HTRequest_net(req);
    file_info * file = (file_info *) HTNet_context(net);
    HTStream * input = HTRequest_inputStream(req);

    /* Free stream with data TO Local file system */
    if (input) {
        if (status == HT_INTERRUPTED)
            (*input->isa->abort)(input, NULL);
        else
            (*input->isa->_free)(input);
        HTRequest_setInputStream(req, NULL);
    }

    /*
    **  Remove if we have registered a timer function as a callback
    */
    if (file->timer) {
	HTTimer_delete(file->timer);
	file->timer = NULL;
    }

    if (file) {
	HT_FREE(file->local);
	HT_FREE(file);
    }
    HTNet_delete(net, status);
    return YES;
}
コード例 #3
0
ファイル: HTNews.c プロジェクト: ChatanW/WebDaM
/*	HTNewsCleanup
**	-------------
**      This function closes the connection and frees memory.
**      Returns YES on OK, else NO
*/
PRIVATE int HTNewsCleanup (HTRequest * req, int status)
{
    HTNet * net = HTRequest_net(req);
    news_info *news = (news_info *) HTNet_context(net);
    HTStream * input = HTRequest_inputStream(req);

    /* Free stream with data TO network */
    if (!HTRequest_isDestination(req))
	HTRequest_removeDestination(req);
    else if (input) {
	if (status == HT_INTERRUPTED)
	    (*input->isa->abort)(input, NULL);
	else
	    (*input->isa->_free)(input);
	HTRequest_setInputStream(req, NULL);
    }

    /* Remove the request object and our own context structure for nntp */
    HTNet_delete(net, status);
    if (news) {
	HT_FREE(news->name);
	HTChunk_delete(news->cmd);
	HT_FREE(news);
    }
    return YES;
}
コード例 #4
0
ファイル: HTMIMImp.c プロジェクト: Hiroyuki-Nagata/libwww
PUBLIC int HTMIME_acceptRanges (HTRequest * request, HTResponse * response,
				char * token, char * value)
{
    if (value) {
	HTNet * net = HTRequest_net(request);
	HTHost * host = HTNet_host(net);
	HTHost_setRangeUnits(host, value);
    }
    return HT_OK;
}
コード例 #5
0
ファイル: HTFile.c プロジェクト: BackupTheBerlios/texlive
PUBLIC int HTLoadFile (SOCKET soc, HTRequest * request)
{
    file_info *file;			      /* Specific access information */
    HTNet * net = HTRequest_net(request);
    HTParentAnchor * anchor = HTRequest_anchor(request);

    HTTRACE(PROT_TRACE, "HTLoadFile.. Looking for `%s\'\n" _ 
			    HTAnchor_physical(anchor));
    if ((file = (file_info *) HT_CALLOC(1, sizeof(file_info))) == NULL)
	HT_OUTOFMEM("HTLoadFILE");
    file->state = FS_BEGIN;
    file->net = net;
    HTNet_setContext(net, file);
    HTNet_setEventCallback(net, FileEvent);
    HTNet_setEventParam(net, file);  /* callbacks get http* */

    return FileEvent(soc, file, HTEvent_BEGIN);	    /* get it started - ops is ignored */
}
コード例 #6
0
ファイル: HTNews.c プロジェクト: ChatanW/WebDaM
PUBLIC int HTLoadNews (SOCKET soc, HTRequest * request)
{
    news_info *news;
    HTParentAnchor *anchor = HTRequest_anchor(request);
    HTNet * net = HTRequest_net(request);
    char * url = HTAnchor_physical(anchor);

    HTTRACE(PROT_TRACE, "NNTP........ Looking for `%s\'\n" _ url);
    if ((news = (news_info *) HT_CALLOC(1, sizeof(news_info))) == NULL)
	HT_OUTOFMEM("HTLoadNews");
    news->cmd = HTChunk_new(128);
    news->state = NEWS_BEGIN;
    news->net = net;
    HTNet_setContext(net, news);
    HTNet_setEventCallback(net, NewsEvent);
    HTNet_setEventParam(net, news);  /* callbacks get http* */

    return NewsEvent(soc, news, HTEvent_BEGIN);		/* get it started - ops is ignored */
}
コード例 #7
0
ファイル: HTMIMImp.c プロジェクト: Hiroyuki-Nagata/libwww
PUBLIC int HTMIME_connection (HTRequest * request, HTResponse * response,
			      char * token, char * value)
{
    /*
    **  Walk through the set of connection directives and add them to the
    **  response association list for connection directives
    */
    char * name_val;
    while ((name_val = HTNextPair(&value)) != NULL) {
	char * name = HTNextField(&name_val);
	char * val = HTNextField(&name_val);

	/*
	**  If we have a name then look if it is concerning persistent
	**  connections. If so, then we handle it here, otherwise we leave it
	**  to somebody else by simply adding it to the list of connection
	**  tokens.
	*/
	if (name) {
	    HTNet * net = HTRequest_net(request);
	    HTHost * host = HTNet_host(net);
	    if (!strcasecomp(name, "close")) {			 /* HTTP/1.1 */
		HTTRACE(STREAM_TRACE, "MIMEParser.. Close received...\n");
		HTHost_setCloseNotification(host, YES);
	    } else if (!strcasecomp(name, "keep-alive")) {       /* HTTP/1.0 */

		/*
		**  In case this is an HTTP/1.1 server sending keep-alive then
		**  ignore it.
		*/
		if (HTHost_version(host) < HTTP_11) {
		    HTNet_setPersistent(net, YES, HT_TP_SINGLE);
		    HTTRACE(STREAM_TRACE, "MIMEParser.. HTTP/1.0 Keep Alive\n");
		} else 
		    HTTRACE(STREAM_TRACE, "MIMEParser.. HTTP/1.0 Keep Alive ignored\n");
	    } else
		HTResponse_addConnection(response, name, val ? val : "");
	}
    }
    return HT_OK;
}
コード例 #8
0
ファイル: HTSocket.c プロジェクト: ChatanW/WebDaM
PUBLIC int HTLoadSocket (SOCKET soc, HTRequest * request)
{
    raw_info * raw;			    /* Specific protocol information */
    HTNet * net = HTRequest_net(request);
    HTTRACE(PROT_TRACE, "Load socket. Setting up socket for accept\n");
    if ((raw = (raw_info *) HT_CALLOC(1, sizeof(raw_info))) == NULL)
      HT_OUTOFMEM("HTLoadSocket");
    raw->state = RAW_BEGIN;
    raw->net = net;
    raw->request = request;
    HTNet_setContext(net, raw);
    HTNet_setEventCallback(net, SocketEvent);
    HTNet_setEventParam(net, raw);

    /* Start listening on a socket */
    if (HTHost_listen(NULL, net, HTAnchor_physical(HTRequest_anchor(request))) == HT_ERROR)
	return SocketEvent(soc, raw, HTEvent_CLOSE);

    /* Get it started - ops is ignored */
    return SocketEvent(soc, raw, HTEvent_BEGIN);
}
コード例 #9
0
ファイル: HTMIME.c プロジェクト: BackupTheBerlios/texlive
/*	MIME header parser stream.
**	-------------------------
**	This stream parses a complete MIME header and if a content type header
**	is found then the stream stack is called. Any left over data is pumped
**	right through the stream
*/
PUBLIC HTStream* HTMIMEConvert (HTRequest *	request,
				void *		param,
				HTFormat	input_format,
				HTFormat	output_format,
				HTStream *	output_stream)
{
    HTStream * me;
    if ((me = (HTStream *) HT_CALLOC(1, sizeof(* me))) == NULL)
        HT_OUTOFMEM("HTMIMEConvert");
    me->isa = &HTMIME;       
    me->request = request;
    me->response = HTRequest_response(request);
    me->net = HTRequest_net(request);
    me->target = output_stream;
    me->target_format = output_format;
    me->save_stream = LocalSaveStream ? LocalSaveStream : HTBlackHoleConverter;
    me->token = HTChunk_new(256);
    me->value = HTChunk_new(256);
    me->hash = 0;
    me->EOLstate = EOL_BEGIN;
    me->haveToken = NO;
    return me;
}
コード例 #10
0
ファイル: HTSocket.c プロジェクト: ChatanW/WebDaM
PRIVATE int RawCleanup (HTRequest * request, int status)
{
    HTNet * net = HTRequest_net(request);
    raw_info * raw = (raw_info *) HTNet_context(net);

    HTTRACE(PROT_TRACE, "Raw clean... Called with status %d, net %p\n" _ status _ net);

    if (status == HT_INTERRUPTED) {
    	HTAlertCallback * cbf = HTAlert_find(HT_PROG_INTERRUPT);
    	if (cbf) (*cbf)(request, HT_PROG_INTERRUPT,
	    HT_MSG_NULL, NULL, NULL, NULL);
    } else if (status == HT_TIMEOUT) {
    	HTAlertCallback * cbf = HTAlert_find(HT_PROG_TIMEOUT);
    	if (cbf) (*cbf)(request, HT_PROG_TIMEOUT,
	    HT_MSG_NULL, NULL, NULL, NULL);
    }	

    /* Delete the Net object */
    HTNet_delete(net, HT_ERROR);

    HT_FREE(raw);
    return YES;
}
コード例 #11
0
ファイル: HTNews.c プロジェクト: ChatanW/WebDaM
PRIVATE int NewsEvent (SOCKET soc, void * pVoid, HTEventType type)
{
    news_info *news = (news_info *)pVoid;
    int status = HT_ERROR;
    HTNet * net = news->net;
    HTRequest * request = HTNet_request(net);
    HTParentAnchor * anchor = HTRequest_anchor(request);
    char * url = HTAnchor_physical(anchor);
    HTHost * host = HTNet_host(net);
    
    /*
    ** Initiate a new nntp structure and bind to request structure
    ** This is actually state NNTP_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, "HTLoadHTTP");
	HTNewsCleanup(request, HT_INTERRUPTED);
	return HT_OK;
    } else
	news = (news_info *) HTNet_context(net);		/* Get existing copy */

    /* Now jump into the machine. We know the state from the previous run */
    while (1) {
        switch (news->state) {
          case NEWS_BEGIN:
	    news->state = (!strchr(url, '@') && strchr(url, '*')) ?
		NEWS_SEEK_CACHE : NEWS_NEED_CONNECTION;
	    break;

	case NEWS_SEEK_CACHE:
	    if (HTNewsCache_before(request, NULL, 0) == HT_LOADED)
		news->state = NEWS_SUCCESS;
	    else
		news->state = NEWS_NEED_CONNECTION;
	    break;

	  case NEWS_NEED_CONNECTION: 		/* Let's set up a connection */
	    if (!strncasecomp(url, "news:", 5)) {
		HTUserProfile * up = HTRequest_userProfile(request);
		char * newshost = HTUserProfile_news(up);
		StrAllocCopy(news->name, url+5);
		if (newshost) {
		    char *newshack = NULL;    /* Then we can use HTParse :-) */
		    StrAllocCopy(newshack, "news://");
		    StrAllocCat(newshack, newshost);
		    status = HTHost_connect(host, net, (char *) newshack);
		    host = HTNet_host(net);
		    HT_FREE(newshack);
		} else
		    news->state = NEWS_ERROR;
	    } else if (!strncasecomp(url, "nntp:", 5)) {
		news->name = HTParse(url, "", PARSE_PATH);
		status = HTHost_connect(host, net, url);
		host = HTNet_host(net);
	    } else {
		HTTRACE(PROT_TRACE, "News........ Huh?");
		news->state = NEWS_ERROR;
            }
            if (status == HT_OK) {
		BOOL greeting = NO;

		/* Set up the persistent connection */
		if (!HTNet_persistent(net)) {
		    HTNet_setPersistent(net, YES, HT_TP_SINGLE);
		    greeting = YES;
		}

		/*
		** Check the protocol class to see if we have connected to a
		** the right class of server, in this case HTTP.
		*/
		{
		    HTHost * host = HTNet_host(net);
		    char * s_class = HTHost_class(host);
		    if (s_class && strcasecomp(s_class, "nntp")) {
			HTRequest_addError(request, ERR_FATAL, NO, HTERR_CLASS,
					   NULL, 0, "HTLoadNews");
			news->state = NEWS_ERROR;
			break;
		    }
		    HTHost_setClass(host, "nntp");
		}

		/* 
		** 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 = HTNewsStatus_new(request, news, host);
		    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);
		}

		news->state = greeting ? NEWS_NEED_GREETING : NEWS_NEED_SWITCH;

	    } else if (status == HT_WOULD_BLOCK || status == HT_PENDING)
		return HT_OK;
	    else
		news->state = NEWS_ERROR;
	    break;

	  case NEWS_NEED_GREETING:
	    status = HTHost_read(HTNet_host(net), net);
	    if (status == HT_WOULD_BLOCK)
		return HT_OK;
	    else if (status == HT_LOADED) {
		if (news->repcode/100 == 2)
		    news->state = NEWS_NEED_SWITCH;
		else
		    news->state = NEWS_ERROR;
	    } else
		news->state = NEWS_ERROR;
	    break;

	  case NEWS_NEED_SWITCH:
	  {
	      HTMethod method = HTRequest_method(request);
	      /*
	      ** Find out what to ask the news server. Syntax of address is
	      **	xxx@yyy		Article
	      **	<xxx@yyy>	Same article
	      **	xxxxx		News group (no "@")
	      */
	      if (method == METHOD_GET) {
		  if (strchr(url, '@')) {				  /* ARTICLE */
		      if (*(news->name) != '<') {		  /* Add '<' and '>' */
			  char *newart;
			  if ((newart = (char  *) HT_MALLOC(strlen(news->name)+3)) == NULL)
			      HT_OUTOFMEM("HTLoadNews");
			  sprintf(newart, "<%s>", news->name);
			  HT_FREE(news->name);
			  news->name = newart;
		      }
		      news->state = NEWS_NEED_ARTICLE;
		  } else if (strchr(url, '*'))
		      news->state = NEWS_NEED_LIST;
		  else
		      news->state = NEWS_NEED_GROUP;
	      } else if (method == METHOD_POST)
		  news->state = NEWS_NEED_POST;
	      else {
		  HTRequest_addError(request, ERR_FATAL, NO,
				     HTERR_NOT_IMPLEMENTED,NULL, 0,"HTLoadNews");
		  news->state = NEWS_ERROR;
	      }
	      HTUnEscape(news->name);
	      HTCleanTelnetString(news->name);
	  }
	  break;

	  case NEWS_NEED_ARTICLE:
	    if (!news->sent) {
		status = SendCommand(request, news, "ARTICLE", news->name);
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
		else if (status == HT_ERROR)
		    news->state = NEWS_ERROR;
		news->format = WWW_MIME;

		/*
		** Set the default content type to plain text as news servers
		** almost never send any useful information about the length
		** of the body or the type - the success of MIME!
		*/
		HTAnchor_setFormat(anchor, WWW_PLAINTEXT);
		news->sent = YES;
	    } else {
		status = HTHost_read(HTNet_host(net), net);
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
		else if (status == HT_OK)
		    news->state = NEWS_NEED_BODY;
		else if (status == HT_LOADED) {
		    news->state = (news->repcode/100 == 2) ?
			NEWS_SUCCESS : NEWS_ERROR;
		} else
		    news->state = NEWS_ERROR;
		news->sent = NO;
	    }
	    break;

#if HT_LISTGROUP
	  case NEWS_NEED_LGRP:
	    if (!news->sent) {
		status = SendCommand(request, news, "LIST", "NEWSGROUPS");
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
		else if (status == HT_ERROR)
		    news->state = NEWS_ERROR;
 		news->format = WWW_NNTP_LIST;
		news->sent = YES;
	    } else {
		status = HTHost_read(HTNet_host(net), net);
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
		else if (status == HT_OK)
		    news->state = NEWS_NEED_BODY;
		else if (status == HT_LOADED) {
		    news->state = (news->repcode/100 == 2) ?
			NEWS_SUCCESS : NEWS_NEED_LIST;
		} else
		    news->state = NEWS_ERROR;
		news->sent = NO;
	    }
	    break;
#endif /* HT_LISTGROUP */

	  case NEWS_NEED_LIST:
	    if (!news->sent) {
		status = SendCommand(request, news, "LIST", NULL);
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
		else if (status == HT_ERROR)
		    news->state = NEWS_ERROR;
		news->format = WWW_NNTP_LIST;
		news->sent = YES;
	    } else {
		status = HTHost_read(HTNet_host(net), net);
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
		else if (status == HT_OK)
		    news->state = NEWS_NEED_BODY;
		else if (status == HT_LOADED) {
		    news->state = (news->repcode/100 == 2) ?
			NEWS_SUCCESS : NEWS_ERROR;
		} else
		    news->state = NEWS_ERROR;
		news->sent = NO;
	    }
	    break;

	  case NEWS_NEED_GROUP:
	    if (!news->sent) {
		status = SendCommand(request, news, "GROUP", news->name);
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
		else if (status == HT_ERROR)
		    news->state = NEWS_ERROR;
		news->sent = YES;
	    } else {
		status = HTHost_read(HTNet_host(net), net);
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
		else if (status == HT_LOADED) {
		    if (news->repcode/100 == 2) {
			if (sscanf(news->reply, "%d%d%d", &news->total,
				   &news->first, &news->last) == 3) {
			    if (MaxArt && news->total>MaxArt)
				news->last = news->first-MaxArt;
			    news->current = news->first;

			    /* If no content in this group */
			    if (news->first == news->last) {
				HTRequest_addError(request, ERR_FATAL, NO,
						   HTERR_NO_CONTENT,
						   NULL, 0, "HTLoadNews");
				news->state = NEWS_NO_DATA;
				break;
			    }
			    news->state = NEWS_NEED_XOVER;
			} else
			    news->state = NEWS_ERROR;
		    } else
			news->state = NEWS_ERROR;
		} else
		    news->state = NEWS_ERROR;
		news->sent = NO;
	    }
	    break;

	  case NEWS_NEED_XOVER:
	    if (!news->sent) {
		char buf[20];
		sprintf(buf, "%d-%d", news->first, news->last);
		status = SendCommand(request, news, "XOVER", buf);
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
		else if (status == HT_ERROR)
		    news->state = NEWS_ERROR;
		news->format = WWW_NNTP_OVER;
		news->sent = YES;
	    } else {
		status = HTHost_read(HTNet_host(net), net);
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
		else if (status == HT_OK)
		    news->state = NEWS_NEED_BODY;
		else if (status == HT_LOADED) {
		    if (news->repcode/100 == 2)
			news->state = NEWS_SUCCESS;
		    else {
			news->format = WWW_NNTP_HEAD;
			news->state = NEWS_NEED_HEAD;
		    }
		} else
		    news->state = NEWS_ERROR;
		news->sent = NO;
	    }
	    break;

	  case NEWS_NEED_HEAD:
	    if (!news->sent) {
		char buf[10];
		sprintf(buf, "%d", news->current++);
		status = SendCommand(request, news, "HEAD", buf);
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
		else if (status == HT_ERROR)
		    news->state = NEWS_ERROR;
		news->sent = YES;
	    } else {
		status = HTHost_read(HTNet_host(net), net);
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
		else if (status == HT_LOADED) {
		    if (news->repcode/100 == 2) {
			if (news->current > news->last)
			    news->state = NEWS_SUCCESS;
		    } else
			news->state = NEWS_ERROR;
		} else
		    news->state = NEWS_ERROR;
		news->sent = NO;
	    }
	    break;

	  case NEWS_NEED_POST:
	  {
	      HTStream * oldinput = HTRequest_inputStream(request);
	      HTStream * newinput =
		  HTNewsPost_new(request, HTBuffer_new(oldinput, request,512));
	      HTRequest_setInputStream(request, newinput);
	      
	      /* Remember to convert to CRLF */

	  }
	  news->state = NEWS_NEED_BODY;
	  break;

          case NEWS_NEED_BODY:
            if (type == HTEvent_WRITE || type == HTEvent_BEGIN) {
		if (HTRequest_isDestination(request)) {
		    HTRequest * source = HTRequest_source(request);
		    HTNet * srcnet = HTRequest_net(source);
		    if (srcnet) {
			HTHost_register(HTNet_host(srcnet), srcnet, HTEvent_READ);
			HTHost_unregister(HTNet_host(srcnet), srcnet, HTEvent_WRITE);
		    }
		    return HT_OK;
		}

		/*
		**  Should we use the input stream directly or call the post
		**  callback function to send data down to the network?
		*/
		{
		    HTStream * input = HTRequest_inputStream(request);
		    HTPostCallback * pcbf = HTRequest_postCallback(request);
		    if (pcbf) {
			status = pcbf(request, input);
			if (status == HT_PAUSE || status == HT_LOADED)
			    type = HTEvent_READ;
		    } else {
			status = (*input->isa->flush)(input);
			type = HTEvent_READ;
		    }
		    if (status == HT_WOULD_BLOCK) return HT_OK;
		}
		status = request->PostCallback ?
                    request->PostCallback(request, request->input_stream) :
			(*request->input_stream->isa->flush)(request->input_stream);
 		if (status == HT_WOULD_BLOCK)
                    return HT_OK;
                else 	
                    type = HTEvent_READ;	  /* Trick to ensure that we do READ */
	    } else if (type == HTEvent_READ) {
                status = HTHost_read(HTNet_host(net), net);
		if (status == HT_WOULD_BLOCK)
		    return HT_OK;
                else if (status == HT_LOADED)
		    news->state = NEWS_SUCCESS;
		else
		    news->state = NEWS_ERROR;
	    } else {
		news->state = NEWS_ERROR;
	    }
	    break;
		
	  case NEWS_SUCCESS:
	    HTNewsCleanup(request, HT_LOADED);
	    return HT_OK;
	    break;

	case NEWS_NO_DATA:
	    HTNewsCleanup(request, HT_NO_DATA);
	    return HT_OK;
	    break;

	  case NEWS_ERROR:
	    HTNewsCleanup(request, HT_NOT_FOUND);
	    return HT_OK;
	    break;
	}
    } /* End of while(1) */
}