📄 httpd.c
字号:
/*
* Copyright (C) 2001-2003 by egnite Software GmbH. 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 copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE
* SOFTWARE GMBH 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.
*
* For additional information see http://www.ethernut.de/
*/
/*
* $Log: httpd.c,v $
* Revision 1.3 2003/07/20 16:03:27 haraldkipp
* Saved some RAM by moving string literals to program memory.
*
* Revision 1.2 2003/07/17 12:28:21 haraldkipp
* Memory hole bugfix
*
* Revision 1.1.1.1 2003/05/09 14:41:58 haraldkipp
* Initial using 3.2.1
*
* Revision 1.14 2003/02/04 18:17:32 harald
* Version 3 released
*
* Revision 1.13 2003/01/14 17:04:20 harald
* Using FAT file system and added types
*
* Revision 1.12 2002/10/31 16:32:45 harald
* Mods by troth for Linux
*
* Revision 1.11 2002/09/15 17:08:44 harald
* Allow different character sets
*
* Revision 1.10 2002/06/26 17:29:49 harald
* First pre-release with 2.4 stack
*
*/
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <sys/heap.h>
#include <sys/version.h>
#include "dencode.h"
#include <pro/httpd.h>
/*!
* \addtogroup xgHTTPD
*/
/*@{*/
static struct {
char *ext;
char *type;
} mimeTypes[] = {
{
".txt", "text/plain"}, {
".html", "text/html"}, {
".htm", "text/html"}, {
".gif", "image/gif"}, {
".jpg", "image/jpeg"}, {
".pdf", "application/pdf"}, {
".js", "application/x-javascript"}
};
static char *http_root;
/*!
* \brief Send top lines of a standard HTML header.
*
* Sends HTTP and Server version lines.
*
* \param stream Stream of the socket connection, previously opened for
* binary read and write.
* \param req The associated client request.
* \param status Response status, error code or 200, if no error occured.
* \param title Error text, or OK, if no error occured.
*/
void NutHttpSendHeaderTop(FILE * stream, REQUEST * req, int status, char *title)
{
static prog_char fmt_P[] = "HTTP/%d.%d %d %s\r\nServer: Ethernut %s\r\n";
fprintf_P(stream, fmt_P, req->req_version / 10, req->req_version % 10,
status, title, NutVersionString());
}
/*!
* \brief Send bottom lines of a standard HTML header.
*
* Sends Content-Type, Content-Lenght and Connection lines.
*
* \param stream Stream of the socket connection, previously opened
* for binary read and write.
* \param mime_type Points to a string that specifies the content type.
* Examples are "text/html", "image/png",
* "image/gif", "video/mpeg" or "text/css".
* A null pointer is ignored.
* \param bytes Content length of the data following this
* header. Ignored, if negative.
*/
void NutHttpSendHeaderBot(FILE * stream, char *mime_type, long bytes)
{
static prog_char typ_fmt_P[] = "Content-Type: %s\r\n";
static prog_char len_fmt_P[] = "Content-Length: %ld\r\n";
static prog_char ccl_str_P[] = "Connection: close\r\n\r\n";
if (mime_type)
fprintf_P(stream, typ_fmt_P, mime_type);
if (bytes >= 0)
fprintf_P(stream, len_fmt_P, bytes);
fputs_P(ccl_str_P, stream);
}
/*!
* \brief Send a HTTP error response.
*
* A canned error file is used.
*
* \param stream Stream of the socket connection, previously opened for
* binary read and write.
* \param req Contains the HTTP request.
* \param status Error code to be returned.
*/
void NutHttpSendError(FILE * stream, REQUEST * req, int status)
{
static prog_char err_fmt_P[] = "<HTML><HEAD><TITLE>%d %s</TITLE></HEAD><BODY>%d %s</BODY></HTML>";
static prog_char auth_fmt_P[] = "WWW-Authenticate: Basic realm=\"%s\"";
char *title;
switch (status) {
case 400:
title = "Bad Request";
break;
case 401:
title = "Unauthorized";
break;
case 404:
title = "Not Found";
break;
case 500:
title = "Internal Error";
break;
case 501:
title = "Not Implemented";
break;
default:
title = "Error";
break;
}
NutHttpSendHeaderTop(stream, req, status, title);
if (status == 401) {
char *cp = 0;
char *realm = req->req_url;
if ((cp = strrchr(realm, '/')) != 0)
*cp = 0;
else
realm = ".";
fprintf_P(stream, auth_fmt_P, realm);
if (cp)
*cp = '/';
}
NutHttpSendHeaderBot(stream, "text/html", -1);
fprintf_P(stream, err_fmt_P, status, title, status, title);
}
/*!
* \brief Return the mime type description of a specified file name.
*
* The mime type returned is based on the file extension.
*
* \todo Function to register additional mime types. Currently only
* .txt, .html, .gif and .jpg are supported.
*
* \param name Name of the file.
*
* \return A pointer to a static string, containing the
* associated mime type description. If the extension
* is not registered, "text/plain; charset=iso-8859-1"
* is returned. If the filename is empty, then
* "text/hatml; charset=iso-8859-1" is returned.
*/
char *NutGetMimeType(char *name)
{
size_t i;
int fl;
if (name == 0 || (fl = strlen(name)) == 0)
return mimeTypes[1].type;
for (i = 0; i < sizeof(mimeTypes) / sizeof(*mimeTypes); i++)
if (strcasecmp
(&(name[fl - strlen(mimeTypes[i].ext)]),
mimeTypes[i].ext) == 0)
return mimeTypes[i].type;
return mimeTypes[0].type;
}
static void NutHttpProcessFileRequest(FILE * stream, REQUEST * req)
{
int fd;
int n;
char *data;
int size;
long file_len;
char *filename = NULL;
/*
* Validate authorization.
*/
if (NutHttpAuthValidate(req)) {
NutHttpSendError(stream, req, 401);
return;
}
/*
* Process CGI.
*/
if (strncasecmp(req->req_url, "cgi-bin/", 8) == 0) {
NutCgiProcessRequest(stream, req);
return;
}
/*
* Process file.
*/
if (http_root) {
filename =
NutHeapAlloc(strlen(http_root) + strlen(req->req_url) + 1);
strcpy(filename, http_root);
} else {
filename = NutHeapAlloc(strlen(req->req_url) + 6);
strcpy(filename, "UROM:");
}
strcat(filename, req->req_url);
fd = _open(filename, _O_BINARY | _O_RDONLY);
NutHeapFree(filename);
if (fd == -1) {
u_char *index;
u_short urll;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -