diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-09-09 17:20:56 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-09-09 17:20:56 +0000 |
commit | 7a65f932826220c741ffbf5698b48692a787d915 (patch) | |
tree | 825e048f8fc18b7e69cb155ad96b7254566a3ffe /nuttx/netutils | |
parent | d12e00bdd6ffbb39ab5d45d5d5a484d293108021 (diff) | |
download | nuttx-7a65f932826220c741ffbf5698b48692a787d915.tar.gz nuttx-7a65f932826220c741ffbf5698b48692a787d915.tar.bz2 nuttx-7a65f932826220c741ffbf5698b48692a787d915.zip |
Implement TCP send; remove uIP proto-sockets
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@339 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/netutils')
-rw-r--r-- | nuttx/netutils/smtp/smtp.c | 212 | ||||
-rw-r--r-- | nuttx/netutils/webserver/httpd-cgi.c | 83 | ||||
-rw-r--r-- | nuttx/netutils/webserver/httpd-cgi.h | 3 | ||||
-rw-r--r-- | nuttx/netutils/webserver/httpd-fs.c | 1 | ||||
-rw-r--r-- | nuttx/netutils/webserver/httpd.c | 271 | ||||
-rw-r--r-- | nuttx/netutils/webserver/httpd.h | 74 |
6 files changed, 335 insertions, 309 deletions
diff --git a/nuttx/netutils/smtp/smtp.c b/nuttx/netutils/smtp/smtp.c index 5d7a61aa6..be224590a 100644 --- a/nuttx/netutils/smtp/smtp.c +++ b/nuttx/netutils/smtp/smtp.c @@ -47,13 +47,14 @@ ****************************************************************************/ #include <sys/types.h> -#include <string.h> +#include <stdio.h> #include <stdlib.h> +#include <unistd.h> +#include <string.h> #include <semaphore.h> #include <sys/socket.h> #include <net/uip/uip.h> -#include <net/uip/psock.h> #include <net/uip/smtp.h> #include "smtp-strings.h" @@ -77,7 +78,6 @@ struct smtp_state uint8 state; boolean connected; sem_t sem; - struct psock psock; uip_ipaddr_t smtpserver; char *localhostname; char *to; @@ -89,146 +89,155 @@ struct smtp_state int sentlen; int textlen; int sendptr; - int result; char buffer[SMTP_INPUT_BUFFER_SIZE]; }; -static volatile struct smtp_state *gpsmtp = 0; - -static void smtp_send_message(struct smtp_state *psmtp) +static inline int smtp_send_message(int sockfd, struct smtp_state *psmtp) { - psock_readto(&psmtp->psock, ISO_nl); + if (recv(sockfd, psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, 0) < 0) + { + return ERROR; + } if (strncmp(psmtp->buffer, smtp_220, 3) != 0) { - PSOCK_CLOSE(&psmtp->psock); - psmtp->result = 2; - return; + return ERROR; } - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_helo); - PSOCK_SEND_STR(&psmtp->psock, psmtp->localhostname); - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_crnl); + snprintf(psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, "%s%s\r\n", smtp_helo, psmtp->localhostname); + if (send(sockfd, psmtp->buffer, strlen(psmtp->buffer), 0) < 0) + { + return ERROR; + } - psock_readto(&psmtp->psock, ISO_nl); + if (recv(sockfd, psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, 0) < 0) + { + return ERROR; + } if (psmtp->buffer[0] != ISO_2) { - PSOCK_CLOSE(&psmtp->psock); - psmtp->result = 3; - return; + return ERROR; } - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_mail_from); - PSOCK_SEND_STR(&psmtp->psock, psmtp->from); - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_crnl); + snprintf(psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, "%s%s\r\n", smtp_mail_from, psmtp->from); + if (send(sockfd, psmtp->buffer, strlen(psmtp->buffer), 0) < 0) + { + return ERROR; + } - psock_readto(&psmtp->psock, ISO_nl); + if (recv(sockfd, psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, 0) < 0) + { + return ERROR; + } if (psmtp->buffer[0] != ISO_2) { - PSOCK_CLOSE(&psmtp->psock); - psmtp->result = 3; - return; + return ERROR; } - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_rcpt_to); - PSOCK_SEND_STR(&psmtp->psock, psmtp->to); - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_crnl); + snprintf(psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, "%s%s\r\n", smtp_rcpt_to, psmtp->to); + if (send(sockfd, psmtp->buffer, strlen(psmtp->buffer), 0) < 0) + { + return ERROR; + } - psock_readto(&psmtp->psock, ISO_nl); + if (recv(sockfd, psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, 0) < 0) + { + return ERROR; + } if (psmtp->buffer[0] != ISO_2) { - PSOCK_CLOSE(&psmtp->psock); - psmtp->result = 5; - return; + return ERROR; } if (psmtp->cc != 0) { - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_rcpt_to); - PSOCK_SEND_STR(&psmtp->psock, psmtp->cc); - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_crnl); + snprintf(psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, "%s%s\r\n", smtp_rcpt_to, psmtp->cc); + if (send(sockfd, psmtp->buffer, strlen(psmtp->buffer), 0) < 0) + { + return ERROR; + } - psock_readto(&psmtp->psock, ISO_nl); + if (recv(sockfd, psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, 0) < 0) + { + return ERROR; + } if (psmtp->buffer[0] != ISO_2) { - PSOCK_CLOSE(&psmtp->psock); - psmtp->result = 6; - return; + return ERROR; } } - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_data); + if (send(sockfd, smtp_data, strlen(smtp_data), 0) < 0) + { + return ERROR; + } - psock_readto(&psmtp->psock, ISO_nl); + if (recv(sockfd, psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, 0) < 0) + { + return ERROR; + } if (psmtp->buffer[0] != ISO_3) { - PSOCK_CLOSE(&psmtp->psock); - psmtp->result = 7; - return; + return ERROR; } - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_to); - PSOCK_SEND_STR(&psmtp->psock, psmtp->to); - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_crnl); + snprintf(psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, "%s%s\r\n", smtp_to, psmtp->to); + if (send(sockfd, psmtp->buffer, strlen(psmtp->buffer), 0) < 0) + { + return ERROR; + } if (psmtp->cc != 0) { - PSOCK_SEND_STR(&psmtp->psock, (char *)psmtp->cc); - PSOCK_SEND_STR(&psmtp->psock, psmtp->cc); - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_crnl); + snprintf(psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, "%s%s\r\n", smtp_to, psmtp->cc); + if (send(sockfd, psmtp->buffer, strlen(psmtp->buffer), 0) < 0) + { + return ERROR; + } } - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_from); - PSOCK_SEND_STR(&psmtp->psock, psmtp->from); - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_crnl); - - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_subject); - PSOCK_SEND_STR(&psmtp->psock, psmtp->subject); - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_crnl); - - psock_send(&psmtp->psock, psmtp->msg, psmtp->msglen); - - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_crnlperiodcrnl); + snprintf(psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, "%s%s\r\n", smtp_from, psmtp->from); + if (send(sockfd, psmtp->buffer, strlen(psmtp->buffer), 0) < 0) + { + return ERROR; + } - psock_readto(&psmtp->psock, ISO_nl); - if (psmtp->buffer[0] != ISO_2) + snprintf(psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, "%s%s\r\n", smtp_subject, psmtp->subject); + if (send(sockfd, psmtp->buffer, strlen(psmtp->buffer), 0) < 0) { - PSOCK_CLOSE(&psmtp->psock); - psmtp->result = 8; - return; + return ERROR; } - PSOCK_SEND_STR(&psmtp->psock, (char *)smtp_quit); - psmtp->result = 0; -} + if (send(sockfd, psmtp->msg, psmtp->msglen, 0) < 0) + { + return ERROR; + } -/* This function is called by the UIP interrupt handling logic whenevent an - * event of interest occurs. - */ + if (send(sockfd, smtp_crnlperiodcrnl, strlen(smtp_crnlperiodcrnl), 0) < 0) + { + return ERROR; + } -void uip_interrupt_event(void) -{ -#warning OBSOLETE -- needs to be redesigned - if (gpsmtp) + if (recv(sockfd, psmtp->buffer, SMTP_INPUT_BUFFER_SIZE, 0) < 0) { - if (uip_closed()) - { - gpsmtp->connected = FALSE; - return; - } + return ERROR; + } - if (uip_aborted() || uip_timedout()) - { - gpsmtp->connected = FALSE; - } + if (psmtp->buffer[0] != ISO_2) + { + return ERROR; + } - sem_post((sem_t*)&gpsmtp->sem); + if (send(sockfd, smtp_quit, strlen(smtp_quit), 0) < 0) + { + return ERROR; } + return OK; } /* Specificy an SMTP server and hostname. @@ -264,6 +273,7 @@ int smtp_send(void *handle, char *to, char *cc, char *from, char *subject, char struct smtp_state *psmtp = (struct smtp_state *)handle; struct sockaddr_in server; int sockfd; + int ret; /* Setup */ @@ -274,7 +284,6 @@ int smtp_send(void *handle, char *to, char *cc, char *from, char *subject, char psmtp->subject = subject; psmtp->msg = msg; psmtp->msglen = msglen; - psmtp->result = OK; /* Create a socket */ @@ -284,12 +293,6 @@ int smtp_send(void *handle, char *to, char *cc, char *from, char *subject, char return ERROR; } - /* Make this instance globally visible (we will get interrupts as - * soon as we connect - */ - - gpsmtp = psmtp; - /* Connect to server. First we have to set some fields in the * 'server' structure. The system will assign me an arbitrary * local port that is not in use. @@ -301,27 +304,16 @@ int smtp_send(void *handle, char *to, char *cc, char *from, char *subject, char if (connect(sockfd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) { + close(sockfd); return ERROR; - } - - /* Initialize the psock structure inside the smtp state structure */ - - psock_init(&psmtp->psock, psmtp->buffer, SMTP_INPUT_BUFFER_SIZE); - - /* And wait for the the socket to be connected */ - - sem_wait(&psmtp->sem); - gpsmtp = 0; + } - /* Was an error reported by interrupt handler? */ + /* Send the message */ - if (psmtp->result == OK ) - { - /* No... Send the message */ - smtp_send_message(psmtp); - } + ret = smtp_send_message(sockfd, psmtp); - return psmtp->result; + close(sockfd); + return ret; } void *smtp_open(void) diff --git a/nuttx/netutils/webserver/httpd-cgi.c b/nuttx/netutils/webserver/httpd-cgi.c index 2b68040a2..9870961e6 100644 --- a/nuttx/netutils/webserver/httpd-cgi.c +++ b/nuttx/netutils/webserver/httpd-cgi.c @@ -30,15 +30,15 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <stdio.h> +#include <string.h> +#include <sys/socket.h> + #include <net/uip/uip.h> -#include <net/uip/psock.h> #include <net/uip/httpd.h> #include "httpd-cgi.h" -#include <stdio.h> -#include <string.h> - #define CONFIG_HTTPDCGI_FILESTATS 1 #undef CONFIG_HTTPDCGI_DCPSTATS #define CONFIG_HTTPDCGI_NETSTATS 1 @@ -101,7 +101,7 @@ static const char *states[] = }; #endif -static void nullfunction(struct httpd_state *s, char *ptr) +static void nullfunction(struct httpd_state *pstate, char *ptr) { } @@ -120,66 +120,57 @@ httpd_cgifunction httpd_cgi(char *name) } #ifdef CONFIG_HTTPDCGI_FILESTATS -static unsigned short generate_file_stats(void *arg) +static void file_stats(struct httpd_state *pstate, char *ptr) { - char *f = (char *)arg; - return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, "%5u", httpd_fs_count(f)); -} - -static void file_stats(struct httpd_state *s, char *ptr) -{ - psock_generator_send(&s->sout, generate_file_stats, strchr(ptr, ' ') + 1); + char buffer[16]; + char *pcount = strchr(ptr, ' ') + 1; + snprintf(buffer, 16, "%5u", httpd_fs_count(pcount)); + (void)send(pstate->sockout, buffer, strlen(buffer), 0); } #endif #if CONFIG_HTTPDCGI_TCPSTATS -static unsigned short generate_tcp_stats(void *arg) +static void tcp_stats(struct httpd_state *pstate, char *ptr) { struct uip_conn *conn; - struct httpd_state *s = (struct httpd_state *)arg; - - conn = &uip_conns[s->count]; - return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, - "<tr><td>%d</td><td>%u.%u.%u.%u:%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n", - htons(conn->lport), - htons(conn->ripaddr[0]) >> 8, - htons(conn->ripaddr[0]) & 0xff, - htons(conn->ripaddr[1]) >> 8, - htons(conn->ripaddr[1]) & 0xff, - htons(conn->rport), - states[conn->tcpstateflags & UIP_TS_MASK], - conn->nrtx, - conn->timer, - (uip_outstanding(conn))? '*':' ', - (uip_stopped(conn))? '!':' '); -} + struct httpd_state *pstate = (struct httpd_state *)arg; + char buffer[256]; -static void tcp_stats(struct httpd_state *s, char *ptr) -{ - for(s->count = 0; s->count < UIP_CONNS; ++s->count) + for(pstate->count = 0; pstate->count < UIP_CONNS; ++pstate->count) { - if((uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) + conn = &uip_conns[pstate->count]; + if((conn->tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) { - psock_generator_send(&s->sout, generate_tcp_stats, s); + snprintf(buffer, 25t, + "<tr><td>%d</td><td>%u.%u.%u.%u:%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n", + htons(conn->lport), + htons(conn->ripaddr[0]) >> 8, + htons(conn->ripaddr[0]) & 0xff, + htons(conn->ripaddr[1]) >> 8, + htons(conn->ripaddr[1]) & 0xff, + htons(conn->rport), + states[conn->tcpstateflags & UIP_TS_MASK], + conn->nrtx, + conn->timer, + (uip_outstanding(conn))? '*':' ', + (uip_stopped(conn))? '!':' '); + + (void)send(pstate->sockout, buffer, strlen(buffer), 0); } } } #endif #ifdef CONFIG_HTTPDCGI_NETSTATS -static unsigned short generate_net_stats(void *arg) -{ - struct httpd_state *s = (struct httpd_state *)arg; - return snprintf((char*)uip_appdata, UIP_APPDATA_SIZE, - "%5u\n", ((uip_stats_t *)&uip_stat)[s->count]); -} - -static void net_stats(struct httpd_state *s, char *ptr) +static void net_stats(struct httpd_state *pstate, char *ptr) { #if UIP_STATISTICS - for(s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t); ++s->count) + char buffer[16]; + + for(pstate->count = 0; pstate->count < sizeof(uip_stat) / sizeof(uip_stats_t); ++pstate->count) { - psock_generator_send(&s->sout, generate_net_stats, s); + snprintf(buffer, 16, "%5u\n", ((uip_stats_t *)&uip_stat)[pstate->count]); + send(pstate->sockout, buffer, strlen(buffer), 0); } #endif /* UIP_STATISTICS */ } diff --git a/nuttx/netutils/webserver/httpd-cgi.h b/nuttx/netutils/webserver/httpd-cgi.h index bd22feb85..7243b19f2 100644 --- a/nuttx/netutils/webserver/httpd-cgi.h +++ b/nuttx/netutils/webserver/httpd-cgi.h @@ -33,9 +33,10 @@ #ifndef __HTTPD_CGI_H__ #define __HTTPD_CGI_H__ -#include <net/uip/psock.h> #include <net/uip/httpd.h> +#include "httpd.h" + typedef void (* httpd_cgifunction)(struct httpd_state *, char *); httpd_cgifunction httpd_cgi(char *name); diff --git a/nuttx/netutils/webserver/httpd-fs.c b/nuttx/netutils/webserver/httpd-fs.c index 3b446ac43..d3fe35171 100644 --- a/nuttx/netutils/webserver/httpd-fs.c +++ b/nuttx/netutils/webserver/httpd-fs.c @@ -45,6 +45,7 @@ #include <net/uip/httpd.h> +#include "httpd.h" #include "httpd-fsdata.h" #ifndef NULL diff --git a/nuttx/netutils/webserver/httpd.c b/nuttx/netutils/webserver/httpd.c index 6cf50962f..4f18a72df 100644 --- a/nuttx/netutils/webserver/httpd.c +++ b/nuttx/netutils/webserver/httpd.c @@ -35,9 +35,12 @@ */ #include <stdlib.h> +#include <sys/socket.h> + #include <net/uip/uip.h> #include <net/uip/httpd.h> +#include "httpd.h" #include "httpd-cgi.h" #include "http-strings.h" @@ -54,244 +57,208 @@ #define ISO_slash 0x2f #define ISO_colon 0x3a -static unsigned short generate_part_of_file(void *state) -{ - struct httpd_state *s = (struct httpd_state *)state; - - if (s->file.len > uip_mss()) { - s->len = uip_mss(); - } else { - s->len = s->file.len; - } - memcpy(uip_appdata, s->file.data, s->len); - - return s->len; -} +#define SEND_STR(psock, str) psock_send(psock, str, strlen(str)) -static void send_file(struct httpd_state *s) +static inline int send_file(struct httpd_state *pstate) { - do { - psock_generator_send(&s->sout, generate_part_of_file, s); - s->file.len -= s->len; - s->file.data += s->len; - } while(s->file.len > 0); -#warning REVISIT must not return until file sent + return send(pstate->sockout, pstate->file.data, pstate->file.len, 0); } -static void send_part_of_file(struct httpd_state *s) +static inline int send_part_of_file(struct httpd_state *pstate) { - psock_send(&s->sout, s->file.data, s->len); -#warning REVISIT must not return until file sent + return send(pstate->sockout, pstate->file.data, pstate->len, 0); } -static void next_scriptstate(struct httpd_state *s) +static void next_scriptstate(struct httpd_state *pstate) { char *p; - p = strchr(s->scriptptr, ISO_nl) + 1; - s->scriptlen -= (unsigned short)(p - s->scriptptr); - s->scriptptr = p; + p = strchr(pstate->scriptptr, ISO_nl) + 1; + pstate->scriptlen -= (unsigned short)(p - pstate->scriptptr); + pstate->scriptptr = p; } -static void handle_script(struct httpd_state *s) +static void handle_script(struct httpd_state *pstate) { char *ptr; - - while(s->file.len > 0) { + + while(pstate->file.len > 0) { /* Check if we should start executing a script. */ - if (*s->file.data == ISO_percent && - *(s->file.data + 1) == ISO_bang) { - s->scriptptr = s->file.data + 3; - s->scriptlen = s->file.len - 3; - if (*(s->scriptptr - 1) == ISO_colon) { - httpd_fs_open(s->scriptptr + 1, &s->file); - send_file(s); + if (*pstate->file.data == ISO_percent && + *(pstate->file.data + 1) == ISO_bang) { + pstate->scriptptr = pstate->file.data + 3; + pstate->scriptlen = pstate->file.len - 3; + if (*(pstate->scriptptr - 1) == ISO_colon) { + httpd_fs_open(pstate->scriptptr + 1, &pstate->file); + send_file(pstate); } else { - httpd_cgi(s->scriptptr)(s, s->scriptptr); + httpd_cgi(pstate->scriptptr)(pstate, pstate->scriptptr); } - next_scriptstate(s); + next_scriptstate(pstate); /* The script is over, so we reset the pointers and continue sending the rest of the file. */ - s->file.data = s->scriptptr; - s->file.len = s->scriptlen; + pstate->file.data = pstate->scriptptr; + pstate->file.len = pstate->scriptlen; } else { /* See if we find the start of script marker in the block of HTML to be sent. */ - if (s->file.len > uip_mss()) { - s->len = uip_mss(); + if (pstate->file.len > uip_mss()) { + pstate->len = uip_mss(); } else { - s->len = s->file.len; + pstate->len = pstate->file.len; } - if (*s->file.data == ISO_percent) { - ptr = strchr(s->file.data + 1, ISO_percent); + if (*pstate->file.data == ISO_percent) { + ptr = strchr(pstate->file.data + 1, ISO_percent); } else { - ptr = strchr(s->file.data, ISO_percent); + ptr = strchr(pstate->file.data, ISO_percent); } if (ptr != NULL && - ptr != s->file.data) { - s->len = (int)(ptr - s->file.data); - if (s->len >= uip_mss()) { - s->len = uip_mss(); + ptr != pstate->file.data) { + pstate->len = (int)(ptr - pstate->file.data); + if (pstate->len >= uip_mss()) { + pstate->len = uip_mss(); } } - send_part_of_file(s); - s->file.data += s->len; - s->file.len -= s->len; + send_part_of_file(pstate); + pstate->file.data += pstate->len; + pstate->file.len -= pstate->len; } } -#warning REVISIT must not return until sent } -static void send_headers(struct httpd_state *s, const char *statushdr) +static int send_headers(struct httpd_state *pstate, const char *statushdr) { char *ptr; + int ret; - PSOCK_SEND_STR(&s->sout, statushdr); - - ptr = strrchr(s->filename, ISO_period); - if (ptr == NULL) { - PSOCK_SEND_STR(&s->sout, http_content_type_binary); - } else if (strncmp(http_html, ptr, 5) == 0 || - strncmp(http_shtml, ptr, 6) == 0) { - PSOCK_SEND_STR(&s->sout, http_content_type_html); - } else if (strncmp(http_css, ptr, 4) == 0) { - PSOCK_SEND_STR(&s->sout, http_content_type_css); - } else if (strncmp(http_png, ptr, 4) == 0) { - PSOCK_SEND_STR(&s->sout, http_content_type_png); - } else if (strncmp(http_gif, ptr, 4) == 0) { - PSOCK_SEND_STR(&s->sout, http_content_type_gif); - } else if (strncmp(http_jpg, ptr, 4) == 0) { - PSOCK_SEND_STR(&s->sout, http_content_type_jpg); - } else { - PSOCK_SEND_STR(&s->sout, http_content_type_plain); - } -#warning REVISIT must not return until sent + ret = send(pstate->sockout, statushdr, strlen(statushdr), 0); + + ptr = strrchr(pstate->filename, ISO_period); + if (ptr == NULL) + { + ret = send(pstate->sockout, http_content_type_binary, strlen(http_content_type_binary), 0); + } + else if (strncmp(http_html, ptr, 5) == 0 || strncmp(http_shtml, ptr, 6) == 0) + { + ret = send(pstate->sockout, http_content_type_html, strlen(http_content_type_html), 0); + } + else if (strncmp(http_css, ptr, 4) == 0) + { + ret = send(pstate->sockout, http_content_type_css, strlen(http_content_type_css), 0); + } + else if (strncmp(http_png, ptr, 4) == 0) + { + ret = send(pstate->sockout, http_content_type_png, strlen(http_content_type_png), 0); + } + else if (strncmp(http_gif, ptr, 4) == 0) + { + ret = send(pstate->sockout, http_content_type_gif, strlen(http_content_type_gif), 0); + } + else if (strncmp(http_jpg, ptr, 4) == 0) + { + ret = send(pstate->sockout, http_content_type_jpg, strlen(http_content_type_jpg), 0); + } + else + { + ret = send(pstate->sockout, http_content_type_plain, strlen(http_content_type_plain), 0); + } + return ret; } -static void handle_output(struct httpd_state *s) +static void handle_output(struct httpd_state *pstate) { char *ptr; - if (!httpd_fs_open(s->filename, &s->file)) + if (!httpd_fs_open(pstate->filename, &pstate->file)) { - httpd_fs_open(http_404_html, &s->file); - strcpy(s->filename, http_404_html); - send_headers(s, http_header_404); - send_file(s); + httpd_fs_open(http_404_html, &pstate->file); + strcpy(pstate->filename, http_404_html); + send_headers(pstate, http_header_404); + send_file(pstate); } else { - send_headers(s, http_header_200); - ptr = strchr(s->filename, ISO_period); + send_headers(pstate, http_header_200); + ptr = strchr(pstate->filename, ISO_period); if (ptr != NULL && strncmp(ptr, http_shtml, 6) == 0) { - handle_script(s); + handle_script(pstate); } else { - send_file(s); + send_file(pstate); } } - PSOCK_CLOSE(&s->sout); } -static void handle_input(struct httpd_state *s) +static int handle_input(struct httpd_state *pstate) { - psock_readto(&s->sin, ISO_space); + ssize_t recvlen; + + if (recv(pstate->sockin, pstate->inputbuf, HTTPD_INBUFFER_SIZE, 0) < 0) + { + return ERROR; + } - if (strncmp(s->inputbuf, http_get, 4) != 0) + if (strncmp(pstate->inputbuf, http_get, 4) != 0) { - PSOCK_CLOSE(&s->sin); - return; + return ERROR; } - psock_readto(&s->sin, ISO_space); + recvlen = recv(pstate->sockin, pstate->inputbuf, HTTPD_INBUFFER_SIZE, 0); + if (recvlen < 0) + { + return ERROR; + } - if (s->inputbuf[0] != ISO_slash) + if (pstate->inputbuf[0] != ISO_slash) { - PSOCK_CLOSE(&s->sin); - return; + return ERROR; } - if (s->inputbuf[1] == ISO_space) + if (pstate->inputbuf[1] == ISO_space) { - strncpy(s->filename, http_index_html, sizeof(s->filename)); + strncpy(pstate->filename, http_index_html, sizeof(pstate->filename)); } else { - s->inputbuf[psock_datalen(&s->sin) - 1] = 0; - strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename)); + pstate->inputbuf[recvlen - 1] = 0; + strncpy(pstate->filename, &pstate->inputbuf[0], sizeof(pstate->filename)); } - s->state = STATE_OUTPUT; + pstate->state = STATE_OUTPUT; while(1) { - psock_readto(&s->sin, ISO_nl); + recvlen = recv(pstate->sockin, pstate->inputbuf, HTTPD_INBUFFER_SIZE, 0); + if (recvlen < 0) + { + return ERROR; + } - if (strncmp(s->inputbuf, http_referer, 8) == 0) + if (strncmp(pstate->inputbuf, http_referer, 8) == 0) { - s->inputbuf[psock_datalen(&s->sin) - 2] = 0; + pstate->inputbuf[recvlen - 2] = 0; } } + + return OK; } -static void handle_connection(struct httpd_state *s) +static void handle_connection(struct httpd_state *pstate) { - handle_input(s); - if (s->state == STATE_OUTPUT) { - handle_output(s); + handle_input(pstate); + if (pstate->state == STATE_OUTPUT) { + handle_output(pstate); } } -/* This function is called by the UIP interrupt handling logic whenevent an - * event of interest occurs. - */ - -void uip_interrupt_event(void) +void httpd_listen(void) { -#warning OBSOLETE -- needs to be redesigned - /* Get the private application specific data */ - struct httpd_state *s = (struct httpd_state *)(uip_conn->private); - - /* Has application specific data been allocate yet? */ - - if (!s) - { - /* No.. allocate it now */ - s = (struct httpd_state *)malloc(sizeof(struct httpd_state)); - if (!s) - { - return; - } - - /* And assign the private instance to the connection */ - uip_conn->private = s; - } - - if (uip_closed() || uip_aborted() || uip_timedout()) { - } else if (uip_connected()) { - psock_init(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1); - psock_init(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1); - s->state = STATE_WAITING; - s->timer = 0; - handle_connection(s); - } else if (s != NULL) { - if (uip_poll()) { - ++s->timer; - if (s->timer >= 20) { - uip_abort(); - } - } else { - s->timer = 0; - } - handle_connection(s); - } else { - uip_abort(); - } +#warning "this is all very broken at the moment" } /* Initialize the web server diff --git a/nuttx/netutils/webserver/httpd.h b/nuttx/netutils/webserver/httpd.h new file mode 100644 index 000000000..b256c1dd1 --- /dev/null +++ b/nuttx/netutils/webserver/httpd.h @@ -0,0 +1,74 @@ +/* httpd.h + * + * Copyright (c) 2001-2005, Adam Dunkels. + * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#ifndef _NETUTILS_WEBSERVER_HTTPD_H +#define _NETUTILS_WEBSERVER_HTTPD_H + +#include <sys/types.h> + +#define HTTPD_FS_STATISTICS 1 +#define HTTPD_INBUFFER_SIZE 50 + +struct httpd_fs_file +{ + char *data; + int len; +}; + +struct httpd_state +{ + unsigned char timer; + int sockin; + int sockout; + char inputbuf[HTTPD_INBUFFER_SIZE]; + char filename[20]; + char state; + struct httpd_fs_file file; + int len; + char *scriptptr; + int scriptlen; + + unsigned short count; +}; + +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 +extern uint16 httpd_fs_count(char *name); +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ + +/* file must be allocated by caller and will be filled in + * by the function. + */ + +int httpd_fs_open(const char *name, struct httpd_fs_file *file); +void httpd_fs_init(void); + +#endif /* _NETUTILS_WEBSERVER_HTTPD_H */ |