| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- /****************************************************************************
- * Copyright (c) 2004 by Michael Fischer. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- ****************************************************************************
- * History:
- *
- * 31.03.04 mifi First Version
- * 02.10.04 mifi Add function to register a user callback
- * 04.08.05 or Adopted to new new mime-handler framework
- ****************************************************************************/
- /*
- * $Log$
- * Revision 1.6 2009/02/13 14:52:05 haraldkipp
- * Include memdebug.h for heap management debugging support.
- *
- * Revision 1.5 2009/02/06 15:40:29 haraldkipp
- * Using newly available strdup() and calloc().
- * Replaced NutHeap routines by standard malloc/free.
- * Replaced pointer value 0 by NULL.
- *
- * Revision 1.4 2008/05/16 01:46:43 thiagocorrea
- * Minor spellcheck fix on the documentation.
- *
- * Revision 1.3 2006/03/16 15:25:38 haraldkipp
- * Changed human readable strings from u_char to char to stop GCC 4 from
- * nagging about signedness.
- *
- * Revision 1.2 2005/08/10 09:26:38 olereinhardt
- * Corrected documentation
- *
- * Revision 1.1 2005/08/05 11:21:02 olereinhardt
- * Added Michael Fischers ASP support. Initial checkin
- *
- */
- /*!
- * \addtogroup xgHTTPD
- */
- /*@{*/
- #include <sys/heap.h>
- #include <sys/confnet.h>
- #include <sys/version.h>
- #include <stdlib.h>
- #include <string.h>
- #include <io.h>
- #include <fcntl.h>
- #include <memdebug.h>
- #include <pro/httpd.h>
- #include <pro/asp.h>
- #include <arpa/inet.h>
- extern CONFNET confnet;
- /*==========================================================*/
- /* DEFINE: All Structures and Common Constants */
- /*==========================================================*/
- /*
- * Use the half size of the normal buffer, because we need
- * 2 buffers. To save memory, we have divide the size too.
- */
- #define MAX_BUFFER_SIZE 256
- /*
- * Do NOT use more than 250 for the len.
- * Because we use a unsigned char for the ASPFuncLen
- */
- #define MAX_ASP_FUNC_SIZE 64
- enum {
- ASP_STATE_IDLE = 0,
- ASP_STATE_START,
- ASP_STATE_COPY_FUNC
- };
- /*==========================================================*/
- /* DEFINE: Definition of all local Data */
- /*==========================================================*/
- static int (*asp_callback)(char *, FILE *) = NULL;
- /*==========================================================*/
- /* DEFINE: Definition of all local Procedures */
- /*==========================================================*/
- /************************************************************/
- /* ProcessASPFunction */
- /************************************************************/
- static void ProcessAspFunction(char *pASPFunction, FILE * stream)
- {
- if (strstr(pASPFunction, "nut_version") != NULL) {
- fprintf(stream, "%s", NutVersionString());
- return;
- }
- if (strstr(pASPFunction, "nut_mac_addr") != NULL) {
- fprintf(stream, "%02X:%02X:%02X:%02X:%02X:%02X",
- confnet.cdn_mac[0], confnet.cdn_mac[1], confnet.cdn_mac[2],
- confnet.cdn_mac[3], confnet.cdn_mac[4], confnet.cdn_mac[5]);
- return;
- }
- if (strstr(pASPFunction, "nut_ip_addr") != NULL) {
- fputs(inet_ntoa(confnet.cdn_ip_addr), stream);
- return;
- }
- if (strstr(pASPFunction, "nut_ip_mask") != NULL) {
- fputs(inet_ntoa(confnet.cdn_ip_mask), stream);
- return;
- }
- if (strstr(pASPFunction, "nut_gateway") != NULL) {
- fputs(inet_ntoa(confnet.cdn_gateway), stream);
- return;
- }
- /*
- * Check if the user has registered an ASPCallback
- */
- if (asp_callback != NULL) {
- asp_callback(pASPFunction, stream);
- }
- }
- /*==========================================================*/
- /* DEFINE: All code exported */
- /*==========================================================*/
- /************************************************************/
- /* NutHttpCheckAsp */
- /************************************************************/
- void NutHttpProcessAsp(FILE * stream, int fd, int file_len, char* http_root, REQUEST *req)
- {
- int n;
- char *pReadBuffer = NULL;
- char *pWriteBuffer = NULL;
- char *pASPFunction = NULL;
- char Data;
- int Size;
- long lFileLen;
- unsigned char bASPState = ASP_STATE_IDLE;
- int ReadCount;
- int WriteCount;
- unsigned char bASPFuncLen;
- lFileLen = _filelength(fd);
- Size = MAX_BUFFER_SIZE;
- WriteCount = 0;
- bASPFuncLen = 0;
- pASPFunction = malloc(MAX_ASP_FUNC_SIZE);
- pReadBuffer = malloc(Size);
- /*
- * For our VERY SPECIAL case, the size of the WriteBuffer must have one char more
- * as the ReadBuffer. Because we must be able to save one more char from the round before.
- */
- pWriteBuffer = malloc(Size + 1);
- if ((pReadBuffer != NULL) && (pWriteBuffer != NULL) && (pASPFunction != NULL)) {
- while (lFileLen) {
- if (lFileLen < MAX_BUFFER_SIZE) {
- Size = (int) lFileLen;
- }
- n = _read(fd, pReadBuffer, Size);
- for (ReadCount = 0; ReadCount < n; ReadCount++) {
- Data = pReadBuffer[ReadCount];
- switch (bASPState) {
- case ASP_STATE_IDLE:
- if (Data == '<') {
- bASPState = ASP_STATE_START;
- }
- pWriteBuffer[WriteCount] = Data;
- WriteCount++;
- break;
- /* ASP_STATE_IDLE */
- case ASP_STATE_START:
- if (Data == '%') {
- bASPState = ASP_STATE_COPY_FUNC;
- if (WriteCount) {
- WriteCount--;
- }
- /*
- * Write the data up to the ASPFunction
- */
- if (WriteCount) {
- fwrite(pWriteBuffer, 1, WriteCount, stream);
- WriteCount = 0;
- }
- } else {
- bASPState = ASP_STATE_IDLE;
- pWriteBuffer[WriteCount] = Data;
- WriteCount++;
- }
- break;
- /* ASP_STATE_START_1 */
- case ASP_STATE_COPY_FUNC:
- if (Data == '>') {
- bASPState = ASP_STATE_IDLE;
- pASPFunction[bASPFuncLen] = 0;
- ProcessAspFunction(pASPFunction, stream);
- bASPFuncLen = 0;
- } else {
- /*
- * Skip over the END of an ASPFunction
- */
- if (Data == '%') {
- Data = 0;
- }
- pASPFunction[bASPFuncLen] = Data;
- bASPFuncLen++;
- if (bASPFuncLen >= MAX_ASP_FUNC_SIZE) {
- /*
- * This make no sense, but protect our stack
- */
- bASPFuncLen = 0;
- }
- }
- break;
- /* ASP_STATE_COPY_FUNC */
- } /* end switch (bASPState) */
- } /* end for */
- /*
- * If data are available in the WriteBuffer,
- * send it out...
- */
- if (WriteCount) {
- /*
- * Now we must test a VERY SPECIAL case !
- * It could be possible that the last char in the buffer is a '<'.
- * Now the State is ASP_STATE_START. If the next chunk starts with a
- * '%' it is to late, because we have send out the '<'.
- * Therefore we must test if the last char is a '<', in this case send all the
- * rest and save the '<' for the next round.
- */
- if (pWriteBuffer[WriteCount - 1] == '<') {
- WriteCount--;
- fwrite(pWriteBuffer, 1, WriteCount, stream);
- /*
- * Now put the '<' in the buffer for the next round
- */
- pWriteBuffer[0] = '<';
- WriteCount = 1;
- } else {
- fwrite(pWriteBuffer, 1, WriteCount, stream);
- WriteCount = 0;
- }
- }
- lFileLen -= (long) n;
- }
- }
- if (pReadBuffer != NULL) {
- free(pReadBuffer);
- }
- if (pWriteBuffer != NULL) {
- free(pWriteBuffer);
- }
- if (pASPFunction != NULL) {
- free(pASPFunction);
- }
- }
- /************************************************************/
- /* NutRegisterAspCallback */
- /* */
- /* return 0 on success, -1 otherwise. */
- /************************************************************/
- int NutRegisterAspCallback(int (*func) (char *, FILE *))
- {
- register int result = 0;
- if (asp_callback == NULL) {
- asp_callback = func;
- } else {
- result = -1;
- }
- return (result);
- }
- /*!
- * \brief Register ASP handler for asp files.
- *
- * asp files may use the following syntax:
- *
- * <%my_function%>
- */
- void NutRegisterAsp(void)
- {
- NutSetMimeHandler(".asp", NutHttpProcessAsp);
- }
- /*@}*/
|