📄 httpd.c
字号:
/******************************************************************
* httpd.c: HyperText Transfer Protocol
*
* Copyright (c) 2001 Atmel Corporation.
* All Rights Reserved.
*
* You are autorized to use, copy and distribute this software only at
* a single site (the term "site" meaning a single company location).
* This copyright notice must be included in any copy, modification
* or portion of this software merged into another program.
*
* This software is licenced solely for use with Atmel AVR micro
* controller family. The software may not be modified to execute on
* any other microcontroller architectures
*
* This software is provided "as is"; Without warranties either express
* or implied, including any warranty regarding merchantability,
* fitness for a particular purpose or noninfringement.
*
* In no event shall Atmel or its suppliers be liable for any special,
* indirect,incidential or concequential damages resulting from the
* use or inability to use this software.
*
* Revision history:
*
* January 17, 2001: Version 1.0 Created by JB
* July 13, 2001 Version 1.2 JB
* - Changed to IAR compiler V2.25
* - Renamed flash file functions to avoid conflict with
* standard file I/O names
* - Bug fixes in HTTP
* - Speed optimization in TCP
*
*
*******************************************************************/
#include "comp_a90.h"
#include "main.h"
#include "ffile.h"
#include "tcp.h"
#include "httpd.h"
#include "script.h"
#include <pgmspace.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
/*staus lines*/
flash char HTTP_STATUSLINE_OK[] ="HTTP/1.0 200 OK\r\n";
flash char HTTP_STATUSLINE_BADREQUEST[] ="HTTP/1.0 400 Bad Request\r\n";
flash char HTTP_STATUSLINE_FORBIDDEN[] ="HTTP/1.0 403 Forbidden\r\n";
flash char HTTP_STATUSLINE_NOTFOUND[] ="HTTP/1.0 404 Not Found\r\n";
flash char HTTP_STATUSLINE_SERVERERROR[] ="HTTP/1.0 500 Internal Server Error\r\n";
flash char HTTP_STATUSLINE_NOTIMPLEMENTED[] ="HTTP/1.0 501 Not Implemented\r\n";
flash char HTTP_STATUSLINE_UNAVAILABLE[] ="HTTP/1.0 503 Service Unavailable\r\n";
/*http headers*/
//flash char HTTP_HEADER_SERVER[] ="Server: Atmel AVR EWS\r\n\0Content-Type: ";
flash char HTTP_HEADER_SERVER[] ="Server: Atmel AVR EWS\r\n";
flash char HTTP_HEADER_CONTENT_LENGTH[] ="Content-Length: "; //must add length and \r\n for each transmition
flash char HTTP_HEADER_CONTENT_TYPE[] ="Content-Type: "; //must add type and \r\n for each transmition
/*MIME-types*/
flash char HTTP_MIME_HTML[] ="text/html\r\n";
flash char HTTP_MIME_PLAIN[] ="text/plain\r\n";
flash char HTTP_MIME_JPEG[] ="image/jpeg\r\n";
flash char HTTP_MIME_GIF[] ="image/gif\r\n";
flash char HTTP_MIME_PNG[] ="image/png\r\n";
flash char HTTP_CRLF_CRLF[] ="\r\n\r\n";
/*html tags*/ //123456 7 8901234 5 67890123
flash char HTTP_HTML_TAG_1[] ="<HTML>\r\n<HEAD>\r\n<TITLE>";
//12345678 9 01234567 8 9012345 6 7
flash char HTTP_HTML_TAG_2[] ="</TITLE>\r\n</HEAD>\r\n<BODY>\r\n";
//1234567 8 90123456 7 8
flash char HTTP_HTML_TAG_3[] ="</BODY>\r\n</HTML>\r\n";
#define HTTP_HTML_TAG_LENGTH 68 //total length of HTTP_HTML_TAG_1-3, used to calculate content length
/*html titles*/
flash char HTTP_HTML_BADREQUEST_TITLE[] ="400 Bad Request";
flash char HTTP_HTML_FORBIDDEN_TITLE[] ="403 Forbidden";
flash char HTTP_HTML_NOTFOUND_TITLE[] ="404 Not Found";
flash char HTTP_HTML_SERVERERROR_TITLE[] ="500 Internal Server Error";
flash char HTTP_HTML_NOTIMPLEMENTED_TITLE[] ="501 Not Implemented";
flash char HTTP_HTML_UNAVAILABLE_TITLE[] ="503 Service Unavailable";
/*html bodies*/
flash char HTTP_HTML_BADREQUEST_BODY[] ="<H1>400 HTTP version not supported</H>";
flash char HTTP_HTML_FORBIDDEN_BODY[] ="<H1>403 Forbidden</H>";
flash char HTTP_HTML_NOTFOUND_BODY[] ="<H1>404 File Not Found</H>";
flash char HTTP_HTML_SERVERERROR_BODY[] ="<H1>500 Internal server error, buffer overflow.</H>";
flash char HTTP_HTML_NOTIMPLEMENTED_BODY[] ="<H1>501 Method not implemented</H>";
flash char HTTP_HTML_UNAVAILABLE_BODY[] ="<H1>503 File Not Available, try again later</H>";
typedef struct _HTTPFILE //pointer to requested http-file
{
unsigned int hisPort;
unsigned int hisIP0;
unsigned int hisIP1;
FFILE *file;
}
HTTPFILE;
HTTPFILE httpFiles[TCP_MAX_SOCKETS]; //requested files queue
/*initialize http daemon*/
void httpdInit( void )
{
unsigned char n;
for(n=0;n<TCP_MAX_SOCKETS;n++) //initialize filelist to NULL
{
httpFiles[n].hisPort=0;
httpFiles[n].hisIP0=0;
httpFiles[n].hisIP1=0;
httpFiles[n].file=NULL;
}
}
/*http daemon*/
void httpd ( void )
{
SOCKET *sock; //pointer to socket
if (!(TCPlistenPort(80,0)) ) //listen to port 80
{
TCPpopen(80,0);
return;
}
sock = TCPfindSockets(80); //find a socket with portnumber 80
while ( sock )
{
httpPoll(sock); //poll the socket
httpSend(sock); //send requested filedata on the socket
sock=sock->next; //change to next socket
}
}
/*sends portions of the files in the files requested queue*/
void httpSend(SOCKET * socket)
{
char httpBuffer[HTTP_SEND_BUFFER]; //for buffering between flash reads and tcp sends
unsigned int httpRead; //number of bytes read from flash
unsigned char socketNr;
socketNr=socket->socketNr; //socketnumber is assigned to socketNr
if(httpFiles[socketNr].file!=NULL) //check if there is a file
{
if ( (socket->hisPort != httpFiles[socketNr].hisPort)
|| (socket->hisIP0 != httpFiles[socketNr].hisIP0)
|| (socket->hisIP1 != httpFiles[socketNr].hisIP1)
|| (socket->state==CLOSED) ) //check if port or ip is wrong or socket is closed
{
ffclose(httpFiles[socketNr].file); //close the file
httpFiles[socketNr].file=NULL; //remove file pointer
}
else if (socket->state==HALF_CLOSED) //check if socket is half closed
{
TCPclose(socket); //close socket
ffclose(httpFiles[socketNr].file); //close file
httpFiles[socketNr].file=NULL; //remove file pointer
}
else if(!ffeof(httpFiles[socketNr].file)) //check if end of file is not yet reached
{
if(TCPbufferSpace(socket)<HTTP_SEND_BUFFER)//check the buffer size available in tcp
{
httpRead=ffread(httpFiles[socketNr].file,httpBuffer,TCPbufferSpace(socket));
} //read rest of file from flash
else
{
httpRead=ffread(httpFiles[socketNr].file,httpBuffer,HTTP_SEND_BUFFER);
} //read a portion of the file from flash
if(httpRead>0)
{
TCPsend(socket,httpRead,httpBuffer); //if something has been read, send it
}
}
else //eof reached
{
strcpy_P(httpBuffer,&HTTP_CRLF_CRLF[2]);
TCPsend(socket,2,httpBuffer); //add CRLF
TCPclose(socket); //close socket
ffclose(httpFiles[socketNr].file); //close file
httpFiles[socketNr].file=NULL; //remove file pointer
}
}
}
/*poll socket for incoming request*/
void httpPoll(SOCKET * socket)
{
char httpBuffer[HTTP_BUFFER]; //buffer for incoming request
char * httpUriVersion;
char * httpMethod;
char * httpUri;
char * httpVer;
char * str;
char filename[8], fileext[3];
unsigned char httpUriVerLength;
unsigned char eol; //end of line flag
unsigned char http09ver=0;
unsigned int bytesRead;
unsigned int contentLength=0;
FFILE * httpFile;
if (TCPsize(socket) && httpFiles[socket->socketNr].file==NULL)
{
bytesRead=TCPreadln(socket, HTTP_BUFFER, httpBuffer,1); //read incoming request
/*check if all of the request-line has been read*/
if ( (httpBuffer[bytesRead-1]!='\r' && httpBuffer[bytesRead-1]!='\n')
&& (httpBuffer[bytesRead-2]!='\r' && httpBuffer[bytesRead-2]!='\n') )
{
return;
}
httpMethod=strtok(httpBuffer," ");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -