Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of webserverBlinky by
Diff: main.cpp
- Revision:
- 67:a63e3486bcda
- Parent:
- 66:f005b9fdf4d1
- Child:
- 68:0b74763ae67f
diff -r f005b9fdf4d1 -r a63e3486bcda main.cpp --- a/main.cpp Mon Jun 05 15:34:53 2017 +0000 +++ b/main.cpp Mon Jun 05 16:45:03 2017 +0000 @@ -513,6 +513,55 @@ } } +int httpResponse( char * dataStart) +{ + int n=0; // number of bytes we have printed so far + if(strncmp(dataStart, "GET / HTTP/1.1", 14) == 0 ) { + n=n+sprintf(n+dataStart,"HTTP/1.1 200 OK\r\nServer: PPP-Blinky\r\n"); // http header + n=n+sprintf(n+dataStart,"Content-Length: "); // http header + int contentLengthStart = n; // remember where Content-Length is in buffer + n=n+sprintf(n+dataStart,"?????\r\n"); // leave five spaces for content length - will be updated later + n=n+sprintf(n+dataStart,"Content-Type: text/html; charset=us-ascii\r\n\r\n"); // http header must end with empty line (\r\n) + int nHeader=n; // byte size of the HTTP header. Note - seems like this must be 1+(multiple of four) + + // this is where we insert our web page into the buffer + n=n+sprintf(n+dataStart,"%s\r\n", ourWebPage); + + int contentLength = n-nHeader; // contentLength is the count of every character after the header +#define CONTENTLENGTHSIZE 5 + char contentLengthString[CONTENTLENGTHSIZE+1]; // temporary buffer to create Content-Length string + snprintf(contentLengthString,CONTENTLENGTHSIZE+1,"%*d",CONTENTLENGTHSIZE,contentLength); // print Content-Length with leading spaces and fixed width equal to csize + memcpy(dataStart+contentLengthStart, contentLengthString, CONTENTLENGTHSIZE); // copy Content-Length to it's place in the send buffer + + if (v0) { + debug("HTTP GET BufferSize %d*32=%d Header %d Content-Length %d Total %d Available %d\n",dataLen/32,dataLen,nHeader,contentLength,n,dataLen-n); + } + } else { // all remaining requests get 404 Not Found response + n=n+sprintf(n+dataStart,"HTTP/1.1 404 Not Found\r\nServer: PPP-Blinky\r\n"); // http header + n=n+sprintf(n+dataStart,"Content-Length: "); // http header + int contentLengthStart = n; // remember where Content-Length is in buffer + n=n+sprintf(n+dataStart,"?????\r\n"); // leave five spaces for content length - will be updated later + n=n+sprintf(n+dataStart,"Content-Type: text/html; charset=us-ascii\r\n\r\n"); // http header must end with empty line (\r\n) + int nHeader=n; // byte total of all headers. Note - seems like this must be 1+(multiple of four) + + n=n+sprintf(n+dataStart,"<!DOCTYPE html><html><head></head>"); // html start + n=n+sprintf(n+dataStart,"<body><h1>File Not Found</h1></body>"); + n=n+sprintf(n+dataStart,"</html>\r\n"); // html end + + int contentLength = n-nHeader; // Content-Length is the count of every character after the header + int cSize = 5; // maximum number of digits we allow for Content-Length + char contentLengthString[cSize+1]; // temporary buffer to create Content-Length string + snprintf(contentLengthString,cSize+1,"%*d",cSize,contentLength); // print Content-Length with leading spaces and fixed width = csize + memcpy(dataStart+contentLengthStart, contentLengthString, cSize); // copy Content-Length to the send buffer + + if (v0) { + debug("HTTP GET BufSize %d*32=%d Header %d Content-Length %d Total %d Available %d\n",dataLen/32,dataLen,nHeader,contentLength,n,dataLen-n); + } + } + return n; // total byte size of our response +} + + void tcpHandler() { char * ipPkt = ppp.pkt.buf+4; // ip packet start @@ -548,7 +597,7 @@ int flagsTCP = ((flagbitstcp[0]&1)<<8)|flagbitstcp[1]; char * dataStart = ppp.pkt.buf + 4 + headerSizeIP + headerSizeTCP; // start of data block after TCP header - int incomingLen = tcpSize - headerSizeTCP; // size of data block after TCP header + int tcpDataSize = tcpSize - headerSizeTCP; // size of data block after TCP header #define TCP_FLAG_ACK (1<<4) #define TCP_FLAG_SYN (1<<1) @@ -566,9 +615,8 @@ ppp.seq = ack; // always adopt their sequence number calculation in place of doing our own calculation - // if ( ((flagsTCP & ~TCP_FLAG_ACK) == 0) && ((flagsTCP & TCP_FLAG_ACK) != 0) ) { if ( flagsTCP == TCP_FLAG_ACK ) { - if (incomingLen == 0) { // ignore - just an empty ack packet + if (tcpDataSize == 0) { // ignore - just an empty ack packet return; } } else if ( (flagsTCP & TCP_FLAG_SYN) != 0 ) { // got SYN flag @@ -580,66 +628,12 @@ flagsOut = TCP_FLAG_ACK | TCP_FLAG_FIN; // for every push we answer once AND close the link fastResponse = 1; // we can respond fast to a push // It's a push, so let's check the incoming data for an HTTP GET request - if ( strncmp(dataStart, "GET / HTTP/1.1", 14) == 0) { - dataLen = 1024; // this buffer has to hold the web page and the content below, so keep total size under 1024 or increase this - memset(dataStart,'x', dataLen ); // initialize the data block - - int n=0; // number of bytes we have printed so far - n=n+sprintf(n+dataStart,"HTTP/1.1 200 OK\r\nServer: PPP-Blinky\r\n"); // http header - n=n+sprintf(n+dataStart,"Content-Length: "); // http header - int contentLengthStart = n; // remember where Content-Length is in buffer - n=n+sprintf(n+dataStart,"?????\r\n"); // leave five spaces for content length - will be updated later - n=n+sprintf(n+dataStart,"Content-Type: text/html; charset=us-ascii\r\n\r\n"); // http header must end with empty line (\r\n) - int nHeader=n; // byte size of the HTTP header. Note - seems like this must be 1+(multiple of four) - - // this is where we insert our web page into the buffer - n=n+sprintf(n+dataStart,"%s\r\n", ourWebPage); - - int contentLength = n-nHeader; // contentLength is the count of every character after the header - int cSize = 5; // maximum number of digits we allow for Content-Length - char contentLengthString[cSize+1]; // temporary buffer to create Content-Length string - snprintf(contentLengthString,cSize+1,"%*d",cSize,contentLength); // print Content-Length with leading spaces and fixed width equal to csize - memcpy(dataStart+contentLengthStart, contentLengthString, cSize); // copy Content-Length to it's place in the send buffer - - if (v0) { - debug("HTTP GET BufferSize %d*32=%d Header %d Content-Length %d Total %d Available %d\n",dataLen/32,dataLen,nHeader,contentLength,n,dataLen-n); - } - dataLen=n; // update the buffer size - } else if ( strncmp(dataStart, "GET /", 4) == 0) { // all other HTTP GET requests get 404 Not Found response - dataLen = 32*32; // maximum size for File not found webpage - memset(dataStart,'x', dataLen ); // initialize the data block - - int n=0; // number of bytes we have printed so far - n=n+sprintf(n+dataStart,"HTTP/1.1 404 Not Found\r\nServer: PPP-Blinky\r\n"); // http header - n=n+sprintf(n+dataStart,"Content-Length: "); // http header - int contentLengthStart = n; // remember where Content-Length is in buffer - n=n+sprintf(n+dataStart,"?????\r\n"); // leave five spaces for content length - will be updated later - n=n+sprintf(n+dataStart,"Content-Type: text/html; charset=us-ascii\r\n\r\n"); // http header must end with empty line (\r\n) - int nHeader=n; // byte total of all headers. Note - seems like this must be 1+(multiple of four) - - n=n+sprintf(n+dataStart,"<!DOCTYPE html><html><head></head>"); // html start - n=n+sprintf(n+dataStart,"<body><h1>File Not Found</h1></body>"); - n=n+sprintf(n+dataStart,"</html>\r\n"); // html end - - int contentLength = n-nHeader; // Content-Length is the count of every character after the header - int cSize = 5; // maximum number of digits we allow for Content-Length - char contentLengthString[cSize+1]; // temporary buffer to create Content-Length string - snprintf(contentLengthString,cSize+1,"%*d",cSize,contentLength); // print Content-Length with leading spaces and fixed width = csize - memcpy(dataStart+contentLengthStart, contentLengthString, cSize); // copy Content-Length to the send buffer - - if (v0) { - debug("HTTP GET BufSize %d*32=%d Header %d Content-Length %d Total %d Available %d\n",dataLen/32,dataLen,nHeader,contentLength,n,dataLen-n); - } - dataLen=n; // update the buffer size - } else { - dataLen=0; // we did not find a valid HTTP request, so just ACK with zero data + if ( strncmp(dataStart, "GET ", 4) == 0) { // do we see an http GET command + dataLen = httpResponse(dataStart); // send an http response } - } else { - dataLen=0; // it's not any TCP Flag Combo that needs special handling } // All the TCP flag handling is now done - // Now we have to recalculate all the header sizes, swap IP address/port source and destination, and do the IP and TCP checksums char tempHold[12]; // it's 12 long because we later reuse it when building the TCP pseudo-header @@ -651,18 +645,18 @@ memcpy(srctcp, dsttcp,2); memcpy(dsttcp, tempHold,2); // swap ip port source/dest - ack = seq + incomingLen; // acknowledge the number of bytes that they sent by adding it to "our" sequence number + ack = seq + tcpDataSize; // acknowledge the number of data bytes that they sent by adding it to "our" sequence number seq = ppp.seq; // set up the sequence number we have to respond with acktcp[0]=ack>>24; acktcp[1]=ack>>16; acktcp[2]=ack>>8; - acktcp[3]=ack>>0; // save ack + acktcp[3]=ack>>0; // save ack 32-bit integer seqtcp[0]=seq>>24; seqtcp[1]=seq>>16; seqtcp[2]=seq>>8; - seqtcp[3]=seq>>0; // save seq + seqtcp[3]=seq>>0; // save seq 32-bit integer flagbitstcp[1] = flagsOut; // set up the new flags @@ -682,7 +676,7 @@ // this header contains the most important parts of the IP header, i.e. source and destination address, protocol number and data length. char * pseudoHeader = s-12; // mark the start of the TCP pseudo-header - memcpy(tempHold, pseudoHeader, 12); // preserve the 12 bytes in the IP header where the TCP pseudo-Header must be built + memcpy(tempHold, pseudoHeader, 12); // preserve the 12 bytes of the IP header where the TCP pseudo-Header will be built memcpy( pseudoHeader+0, srcAdr, 8); // IP source and destination addresses from IP header memset( pseudoHeader+8, 0, 1); // reserved, set to zero memset( pseudoHeader+9, protocolIP, 1); // protocol from IP header