Nut/OS  4.10.3
API Reference
httpopt.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008 by egnite GmbH. All rights reserved.
00003  * Copyright (C) 2001-2007 by egnite Software GmbH. All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. Neither the name of the copyright holders nor the names of
00015  *    contributors may be used to endorse or promote products derived
00016  *    from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00019  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00021  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00022  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00023  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00024  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00025  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00026  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00027  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00028  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00029  * SUCH DAMAGE.
00030  *
00031  * For additional information see http://www.ethernut.de/
00032  */
00033 
00058 #include <cfg/arch.h>
00059 
00060 #include <string.h>
00061 #include <io.h>
00062 #include <fcntl.h>
00063 #include <ctype.h>
00064 #include <stdlib.h>
00065 #include <memdebug.h>
00066 
00067 #include <sys/heap.h>
00068 #include <sys/version.h>
00069 
00070 #include "dencode.h"
00071 
00072 #include <pro/httpd.h>
00073 
00078 
00079 extern MIMETYPES mimeTypes[];
00080 extern char *http_root;
00081 
00093 uint8_t NutSetMimeHandler(char *extension, void (*handler)(FILE *stream, int fd, int file_len, char *http_root, REQUEST *req))
00094 {
00095     size_t i;
00096 
00097     if (extension == NULL)
00098         return 1;
00099     for (i = 0; mimeTypes[i].mtyp_ext; i++)
00100         if (strcasecmp(extension, mimeTypes[i].mtyp_ext) == 0) {
00101             mimeTypes[i].mtyp_handler = handler;
00102             return 0;
00103         }
00104     return 1;
00105 }
00106 
00117 char *NutHttpURLEncode(char *str)
00118 {
00119     static char *hexdigits = "0123456789ABCDEF";
00120     register char *ptr1, *ptr2;
00121     char *encstring;
00122     int numEncs = 0;
00123 
00124     if (!str)
00125         return NULL;
00126 
00127     /* Calculate how many characters we need to encode */
00128     for (ptr1 = str; *ptr1; ptr1++) {
00129         if (!isalnum((unsigned char)*ptr1) || *ptr1 == '%' || *ptr1 == '&'|| *ptr1 == '+' ||
00130                 *ptr1 == ',' || *ptr1 == ':' || *ptr1 == ';'|| *ptr1 == '='|| *ptr1 == '?'|| *ptr1 == '@')
00131             numEncs++;
00132     }
00133     /* Now we can calculate the encoded string length */
00134     encstring = (char *) malloc(strlen(str) + 2 * numEncs + 1);
00135     if (encstring) {
00136         /* Encode the string. ptr1 refers to the original string,
00137          * and ptr2 refers to the new string. */
00138         ptr2 = encstring;
00139         for (ptr1 = str; *ptr1; ptr1++) {
00140                     if (isalnum((unsigned char)*ptr1) || *ptr1 == '%' || *ptr1 == '&'|| *ptr1 == '+' ||
00141                     *ptr1 == ',' || *ptr1 == ':' || *ptr1 == ';'|| *ptr1 == '='|| *ptr1 == '?'|| *ptr1 == '@')
00142                 *ptr2++ = *ptr1;
00143             else {
00144                 *ptr2++ = '%';
00145                 *ptr2++ = hexdigits[(*ptr1 >> 4)];
00146                 *ptr2++ = hexdigits[*ptr1 & 0x0F];
00147             }
00148         }
00149         *ptr2++ = 0;
00150     }
00151     return encstring;
00152 }
00153 
00166 void NutHttpProcessPostQuery(FILE *stream, REQUEST * req)
00167 {
00168     int got;
00169     register int i;
00170     register char *ptr;
00171 
00172     if (req->req_query != NULL)
00173         return;
00174 
00175     if (!stream)
00176         return;
00177 
00178     if (req->req_method == METHOD_POST) {
00179         req->req_query = malloc(req->req_length+1);
00180         if (req->req_query == NULL) {
00181             /* Out of memory */
00182             req->req_numqptrs = 0;
00183             return;
00184         }
00185         memset(req->req_query, 0, req->req_length+1);
00186         i = 0;
00187         while (i < req->req_length) {
00188             got = fread(&req->req_query[i], 1, req->req_length-i, stream);
00189             if (got <= 0) {
00190                 free(req->req_query);
00191                 req->req_numqptrs = 0;
00192                 req->req_query = NULL;
00193                 return;
00194             }
00195             i += got;
00196         }
00197     } else return;
00198 
00199     req->req_numqptrs = 1;
00200     for (ptr = req->req_query; *ptr; ptr++)
00201         if (*ptr == '&')
00202             req->req_numqptrs++;
00203 
00204     req->req_qptrs = (char **) malloc(sizeof(char *) * (req->req_numqptrs * 2));
00205     if (!req->req_qptrs) {
00206         /* Out of memory */
00207         free(req->req_query);
00208         req->req_numqptrs = 0;
00209         req->req_query = NULL;
00210         return;
00211     }
00212     req->req_qptrs[0] = req->req_query;
00213     req->req_qptrs[1] = 0;
00214     for (ptr = req->req_query, i = 2; *ptr; ptr++) {
00215         if (*ptr == '&') {
00216             req->req_qptrs[i] = ptr + 1;
00217             req->req_qptrs[i + 1] = NULL;
00218             *ptr = 0;
00219             i += 2;
00220         }
00221     }
00222 
00223     for (i = 0; i < req->req_numqptrs; i++) {
00224         for (ptr = req->req_qptrs[i * 2]; *ptr; ptr++) {
00225             if (*ptr == '=') {
00226                 req->req_qptrs[i * 2 + 1] = ptr + 1;
00227                 *ptr = 0;
00228                 NutHttpURLDecode(req->req_qptrs[i * 2 + 1]);
00229                 break;
00230             }
00231         }
00232         NutHttpURLDecode(req->req_qptrs[i * 2]);
00233     }
00234 }
00235 
00244 char *NutHttpGetParameter(REQUEST * req, char *name)
00245 {
00246     int i;
00247     for (i = 0; i < req->req_numqptrs; i++)
00248         if (strcmp(req->req_qptrs[i * 2], name) == 0)
00249             return req->req_qptrs[i * 2 + 1];
00250     return NULL;
00251 }
00252 
00277 int NutHttpGetParameterCount(REQUEST * req)
00278 {
00279     return req->req_numqptrs;
00280 }
00281 
00291 char *NutHttpGetParameterName(REQUEST * req, int index)
00292 {
00293     if (index < 0 || index >= NutHttpGetParameterCount(req))
00294         return NULL;
00295     return req->req_qptrs[index * 2];
00296 }
00297 
00307 char *NutHttpGetParameterValue(REQUEST * req, int index)
00308 {
00309     if (index < 0 || index >= NutHttpGetParameterCount(req))
00310         return NULL;
00311     return req->req_qptrs[index * 2 + 1];
00312 }
00313 
00314