00001
00002
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #define __HTTP2_C
00066
00067 #include "TCPIP.h"
00068
00069
00070 #include "web.h"
00071 #include "stringtable.h"
00072 #include "HTTPPrint.h"
00073
00074 #if defined(STACK_USE_HTTP2_SERVER)
00075
00076
00077
00078
00079
00080 static ROM BYTE HTTP_CRLF[] = "\r\n";
00081 #define HTTP_CRLF_LEN 2 // Length of above string
00082
00083
00084
00085
00086
00087
00088 static ROM char *httpFileExtensions[HTTP_UNKNOWN+1] =
00089 {
00090 "txt",
00091 "htm",
00092 "html",
00093 "cgi",
00094 "xml",
00095 "css",
00096 "gif",
00097 "png",
00098 "jpg",
00099 "cla",
00100 "wav",
00101 "\0\0\0"
00102 };
00103
00104
00105 static ROM char *httpContentTypes[HTTP_UNKNOWN+1] =
00106 {
00107 "text/plain",
00108 "text/html",
00109 "text/html",
00110 "text/html",
00111 "text/xml",
00112 "text/css",
00113 "image/gif",
00114 "image/png",
00115 "image/jpeg",
00116 "application/java-vm",
00117 "audio/x-wave",
00118 ""
00119 };
00120
00121
00122
00123
00124
00125
00126
00127 static ROM char *HTTPResponseHeaders[] =
00128 {
00129 "HTTP/1.1 200 OK\r\nConnection: close\r\n",
00130 "HTTP/1.1 200 OK\r\nConnection: close\r\n",
00131 "HTTP/1.1 401 Unauthorized\r\nWWW-Authenticate: Basic realm=\"Protected\"\r\nConnection: close\r\n\r\n401 Unauthorized: Password required\r\n",
00132 #if defined(HTTP_MPFS_UPLOAD)
00133 "HTTP/1.1 404 Not found\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n404: File not found<br>Use <a href=\"/" HTTP_MPFS_UPLOAD "\">MPFS Upload</a> to program web pages\r\n",
00134 #else
00135 "HTTP/1.1 404 Not found\r\nConnection: close\r\n\r\n404: File not found\r\n",
00136 #endif
00137 "HTTP/1.1 414 Request-URI Too Long\r\nConnection: close\r\n\r\n414 Request-URI Too Long: Buffer overflow detected\r\n",
00138 "HTTP/1.1 500 Internal Server Error\r\nConnection: close\r\n\r\n500 Internal Server Error: Expected data not present\r\n",
00139 "HTTP/1.1 501 Not Implemented\r\nConnection: close\r\n\r\n501 Not Implemented: Only GET and POST supported\r\n",
00140 #if defined(HTTP_MPFS_UPLOAD)
00141 "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n<html><body style=\"margin:100px\"><form method=post action=\"/" HTTP_MPFS_UPLOAD "\" enctype=\"multipart/form-data\"><b>MPFS Image Upload</b><p><input type=file name=i size=40> <input type=submit value=\"Upload\"></form></body></html>",
00142 "",
00143 "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n<html><body style=\"margin:100px\"><b>MPFS Update Successful</b><p><a href=\"/\">Site main page</a></body></html>",
00144 "HTTP/1.1 500 Internal Server Error\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n<html><body style=\"margin:100px\"><b>MPFS Image Corrupt or Wrong Version</b><p><a href=\"/" HTTP_MPFS_UPLOAD "\">Try again?</a></body></html>",
00145 #endif
00146 "HTTP/1.1 302 Found\r\nConnection: close\r\nLocation: ",
00147 "HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n403 Forbidden: SSL Required - use HTTPS\r\n"
00148 };
00149
00150
00151
00152
00153
00154 #define HTTP_NUM_HEADERS 3
00155
00156
00157 static ROM char *HTTPRequestHeaders[HTTP_NUM_HEADERS] =
00158 {
00159 "Cookie:",
00160 "Authorization:",
00161 "Content-Length:"
00162 };
00163
00164
00165 #define HTTP_MAX_HEADER_LEN (15u)
00166
00167
00168
00169
00170
00171 #pragma udata HTTP_CONNECTION_STATES
00172 HTTP_CONN curHTTP;
00173 HTTP_STUB httpStubs[MAX_HTTP_CONNECTIONS];
00174 BYTE curHTTPID;
00175 #pragma udata
00176
00177
00178
00179
00180
00181 static void HTTPHeaderParseLookup(BYTE i);
00182 #if defined(HTTP_USE_COOKIES)
00183 static void HTTPHeaderParseCookie(void);
00184 #endif
00185 #if defined(HTTP_USE_AUTHENTICATION)
00186 static void HTTPHeaderParseAuthorization(void);
00187 #endif
00188 #if defined(HTTP_USE_POST)
00189 static void HTTPHeaderParseContentLength(void);
00190 static HTTP_READ_STATUS HTTPReadTo(BYTE delim, BYTE* buf, WORD len);
00191 #endif
00192
00193 static void HTTPProcess(void);
00194 static BOOL HTTPSendFile(void);
00195 static void HTTPLoadConn(BYTE hHTTP);
00196
00197 #if defined(HTTP_MPFS_UPLOAD)
00198 static HTTP_IO_RESULT HTTPMPFSUpload(void);
00199 #endif
00200
00201 #define mMIN(a, b) ((a<b)?a:b)
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 void HTTPInit(void)
00228 {
00229 WORD oldPtr;
00230
00231
00232 curHTTP.file = MPFS_INVALID_HANDLE;
00233 curHTTP.offsets = MPFS_INVALID_HANDLE;
00234
00235 for(curHTTPID = 0; curHTTPID < MAX_HTTP_CONNECTIONS; curHTTPID++)
00236 {
00237 smHTTP = SM_HTTP_IDLE;
00238 sktHTTP = TCPOpen(0, TCP_OPEN_SERVER, HTTP_PORT, TCP_PURPOSE_HTTP_SERVER);
00239 #if defined(STACK_USE_SSL_SERVER)
00240 TCPAddSSLListener(sktHTTP, HTTPS_PORT);
00241 #endif
00242
00243
00244 oldPtr = MACSetWritePtr(BASE_HTTPB_ADDR + curHTTPID*sizeof(HTTP_CONN));
00245 MACPutArray((BYTE*)&curHTTP, sizeof(HTTP_CONN));
00246 MACSetWritePtr(oldPtr);
00247 }
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 void HTTPServer(void)
00278 {
00279 BYTE conn;
00280
00281 for(conn = 0; conn < MAX_HTTP_CONNECTIONS; conn++)
00282 {
00283 if(httpStubs[conn].socket == INVALID_SOCKET)
00284 continue;
00285
00286
00287
00288
00289
00290 if(TCPWasReset(httpStubs[conn].socket))
00291 {
00292 HTTPLoadConn(conn);
00293 smHTTP = SM_HTTP_IDLE;
00294
00295
00296 if(curHTTP.file != MPFS_INVALID_HANDLE)
00297 {
00298 MPFSClose(curHTTP.file);
00299 curHTTP.file = MPFS_INVALID_HANDLE;
00300 }
00301 if(curHTTP.offsets != MPFS_INVALID_HANDLE)
00302 {
00303 MPFSClose(curHTTP.offsets);
00304 curHTTP.offsets = MPFS_INVALID_HANDLE;
00305 }
00306
00307
00308
00309 TCPAdjustFIFOSize(sktHTTP, 1, 0, TCP_ADJUST_PRESERVE_RX);
00310 }
00311
00312
00313 if(httpStubs[conn].sm != SM_HTTP_IDLE || TCPIsGetReady(httpStubs[conn].socket))
00314 {
00315 HTTPLoadConn(conn);
00316 HTTPProcess();
00317 }
00318 }
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 static void HTTPLoadConn(BYTE hHTTP)
00343 {
00344 WORD oldPtr;
00345
00346
00347 if(hHTTP == curHTTPID)
00348 return;
00349
00350
00351 oldPtr = MACSetWritePtr(BASE_HTTPB_ADDR + curHTTPID*sizeof(HTTP_CONN));
00352 MACPutArray((BYTE*)&curHTTP, sizeof(HTTP_CONN));
00353 MACSetWritePtr(oldPtr);
00354
00355
00356 oldPtr = MACSetReadPtr(BASE_HTTPB_ADDR + hHTTP*sizeof(HTTP_CONN));
00357 MACGetArray((BYTE*)&curHTTP, sizeof(HTTP_CONN));
00358 MACSetReadPtr(oldPtr);
00359
00360
00361 curHTTPID = hHTTP;
00362
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 static void HTTPProcess(void)
00382 {
00383 WORD lenA, lenB;
00384 BYTE c, i;
00385 BOOL isDone;
00386 BYTE *ext;
00387 BYTE buffer[HTTP_MAX_HEADER_LEN+1];
00388
00389 do
00390 {
00391 isDone = TRUE;
00392
00393 switch(smHTTP)
00394 {
00395
00396 case SM_HTTP_IDLE:
00397
00398
00399 lenA = TCPIsGetReady(sktHTTP);
00400
00401
00402 if(lenA)
00403 {
00404 curHTTP.ptrData = curHTTP.data;
00405 smHTTP = SM_HTTP_PARSE_REQUEST;
00406 curHTTP.isAuthorized = 0xff;
00407 curHTTP.hasArgs = FALSE;
00408 curHTTP.callbackID = TickGet() + HTTP_TIMEOUT*TICK_SECOND;
00409 curHTTP.callbackPos = 0xffffffff;
00410 curHTTP.byteCount = 0;
00411 #if defined(HTTP_USE_POST)
00412 curHTTP.smPost = 0x00;
00413 #endif
00414
00415
00416
00417 TCPAdjustFIFOSize(sktHTTP, 1, 0, TCP_ADJUST_PRESERVE_RX | TCP_ADJUST_GIVE_REST_TO_RX);
00418 }
00419 else
00420
00421
00422 break;
00423
00424 case SM_HTTP_PARSE_REQUEST:
00425
00426
00427 if(TCPFind(sktHTTP, '\n', 0, FALSE) == 0xffff)
00428 {
00429 if(TCPGetRxFIFOFree(sktHTTP) == 0)
00430 {
00431 curHTTP.httpStatus = HTTP_OVERFLOW;
00432 smHTTP = SM_HTTP_SERVE_HEADERS;
00433 isDone = FALSE;
00434 }
00435 if((LONG)(TickGet() - curHTTP.callbackID) > (LONG)0)
00436 {
00437 TCPDisconnect(sktHTTP);
00438 smHTTP = SM_HTTP_DISCONNECT;
00439 isDone = FALSE;
00440 }
00441 break;
00442 }
00443
00444
00445 curHTTP.callbackID = TickGet() + HTTP_TIMEOUT*TICK_SECOND;
00446
00447
00448 lenA = TCPFind(sktHTTP, ' ', 0, FALSE);
00449 if(lenA > 5)
00450 lenA = 5;
00451 TCPGetArray(sktHTTP, curHTTP.data, lenA+1);
00452
00453 if ( memcmppgm2ram(curHTTP.data, (ROM void*)"GET", 3) == 0)
00454 curHTTP.httpStatus = HTTP_GET;
00455 #if defined(HTTP_USE_POST)
00456 else if ( memcmppgm2ram(curHTTP.data, (ROM void*)"POST", 4) == 0)
00457 curHTTP.httpStatus = HTTP_POST;
00458 #endif
00459 else
00460 {
00461 curHTTP.httpStatus = HTTP_NOT_IMPLEMENTED;
00462 smHTTP = SM_HTTP_SERVE_HEADERS;
00463 isDone = FALSE;
00464 break;
00465 }
00466
00467
00468 lenA = TCPFind(sktHTTP, ' ', 0, FALSE);
00469 lenB = TCPFindEx(sktHTTP, '?', 0, lenA, FALSE);
00470 lenA = mMIN(lenA, lenB);
00471
00472
00473 if(lenA > HTTP_MAX_DATA_LEN - HTTP_DEFAULT_LEN - 1)
00474 {
00475 curHTTP.httpStatus = HTTP_OVERFLOW;
00476 smHTTP = SM_HTTP_SERVE_HEADERS;
00477 isDone = FALSE;
00478 break;
00479 }
00480
00481
00482 lenB = TCPGetArray(sktHTTP, curHTTP.data, lenA);
00483 curHTTP.data[lenB] = '\0';
00484 HTTPURLDecode(curHTTP.data);
00485
00486
00487 #if defined(HTTP_MPFS_UPLOAD)
00488 if(memcmppgm2ram(&curHTTP.data[1], HTTP_MPFS_UPLOAD, strlenpgm(HTTP_MPFS_UPLOAD)) == 0)
00489 {
00490 #if defined(HTTP_USE_AUTHENTICATION)
00491 curHTTP.isAuthorized = HTTPNeedsAuth(&curHTTP.data[1]);
00492 #endif
00493 if(curHTTP.httpStatus == HTTP_GET)
00494 curHTTP.httpStatus = HTTP_MPFS_FORM;
00495 else
00496 curHTTP.httpStatus = HTTP_MPFS_UP;
00497
00498 smHTTP = SM_HTTP_PARSE_HEADERS;
00499 isDone = FALSE;
00500 break;
00501 }
00502 #endif
00503
00504
00505
00506 if(curHTTP.data[lenB-1] != '/')
00507 curHTTP.file = MPFSOpen(&curHTTP.data[1]);
00508
00509
00510 if(curHTTP.file == MPFS_INVALID_HANDLE)
00511 {
00512
00513 if(curHTTP.data[lenB-1] != '/')
00514 curHTTP.data[lenB++] = '/';
00515
00516
00517 #if defined(STACK_USE_SSL_SERVER)
00518 if(TCPIsSSL(sktHTTP))
00519 {
00520 strcpypgm2ram((void*)&curHTTP.data[lenB], HTTPS_DEFAULT_FILE);
00521 lenB += strlenpgm(HTTPS_DEFAULT_FILE);
00522 }
00523 else
00524 #endif
00525 {
00526 strcpypgm2ram((void*)&curHTTP.data[lenB], HTTP_DEFAULT_FILE);
00527 lenB += strlenpgm(HTTP_DEFAULT_FILE);
00528 }
00529
00530
00531 curHTTP.file = MPFSOpen(&curHTTP.data[1]);
00532 }
00533
00534
00535 for(ext = curHTTP.data + lenB-1; ext != curHTTP.data; ext--)
00536 if(*ext == '.')
00537 break;
00538
00539
00540 ext++;
00541 for(curHTTP.fileType = HTTP_TXT; curHTTP.fileType < HTTP_UNKNOWN; curHTTP.fileType++)
00542 if(!stricmppgm2ram(ext, (ROM void*)httpFileExtensions[curHTTP.fileType]))
00543 break;
00544
00545
00546 #if defined(HTTP_USE_AUTHENTICATION)
00547 curHTTP.isAuthorized = HTTPNeedsAuth(&curHTTP.data[1]);
00548 #endif
00549
00550
00551 if(curHTTP.file != MPFS_INVALID_HANDLE &&
00552 (MPFSGetFlags(curHTTP.file) & MPFS2_FLAG_HASINDEX) )
00553 {
00554 curHTTP.offsets = MPFSOpenID(MPFSGetID(curHTTP.file) + 1);
00555 }
00556
00557
00558 lenA = TCPFind(sktHTTP, ' ', 0, FALSE);
00559 if(lenA != 0)
00560 {
00561 curHTTP.hasArgs = TRUE;
00562
00563
00564 TCPGet(sktHTTP, &c);
00565
00566
00567 lenA--;
00568 if(lenA >= HTTP_MAX_DATA_LEN - 2)
00569 {
00570 curHTTP.httpStatus = HTTP_OVERFLOW;
00571 smHTTP = SM_HTTP_SERVE_HEADERS;
00572 isDone = FALSE;
00573 break;
00574 }
00575
00576
00577 curHTTP.ptrData += TCPGetArray(sktHTTP, curHTTP.data, lenA);
00578 *(curHTTP.ptrData++) = '&';
00579
00580 }
00581
00582
00583 lenA = TCPFind(sktHTTP, '\n', 0, FALSE);
00584 TCPGetArray(sktHTTP, NULL, lenA + 1);
00585
00586
00587 smHTTP = SM_HTTP_PARSE_HEADERS;
00588
00589
00590
00591 case SM_HTTP_PARSE_HEADERS:
00592
00593
00594 while(1)
00595 {
00596
00597 lenA = TCPFind(sktHTTP, '\n', 0, FALSE);
00598 if(lenA == 0xffff)
00599 {
00600 if(TCPGetRxFIFOFree(sktHTTP) == 0)
00601 {
00602 curHTTP.httpStatus = HTTP_OVERFLOW;
00603 smHTTP = SM_HTTP_SERVE_HEADERS;
00604 isDone = FALSE;
00605 }
00606 if((LONG)(TickGet() - curHTTP.callbackID) > (LONG)0)
00607 {
00608 TCPDisconnect(sktHTTP);
00609 smHTTP = SM_HTTP_DISCONNECT;
00610 isDone = FALSE;
00611 }
00612 break;
00613 }
00614
00615
00616 curHTTP.callbackID = TickGet() + HTTP_TIMEOUT*TICK_SECOND;
00617
00618
00619 if(lenA == 1)
00620 {
00621 TCPGetArray(sktHTTP, NULL, 2);
00622 smHTTP = SM_HTTP_AUTHENTICATE;
00623 isDone = FALSE;
00624 break;
00625 }
00626
00627
00628 lenB = TCPFindEx(sktHTTP, ':', 0, lenA, FALSE) + 2;
00629 isDone = FALSE;
00630
00631
00632 if(lenB > sizeof(buffer))
00633 {
00634 TCPGetArray(sktHTTP, NULL, lenA+1);
00635 continue;
00636 }
00637
00638
00639 TCPGetArray(sktHTTP, buffer, lenB);
00640 buffer[lenB-1] = '\0';
00641 lenA -= lenB;
00642
00643
00644 for(i = 0; i < HTTP_NUM_HEADERS; i++)
00645 {
00646 if(strcmppgm2ram((char*)buffer, (ROM char *)HTTPRequestHeaders[i]) == 0)
00647 {
00648 HTTPHeaderParseLookup(i);
00649 isDone = TRUE;
00650 break;
00651 }
00652 }
00653
00654
00655 if(isDone)
00656 {
00657 lenA = TCPFind(sktHTTP, '\n', 0, FALSE);
00658 }
00659 TCPGetArray(sktHTTP, NULL, lenA+1);
00660 }
00661
00662 break;
00663
00664 case SM_HTTP_AUTHENTICATE:
00665
00666 #if defined(HTTP_USE_AUTHENTICATION)
00667
00668 if(curHTTP.isAuthorized < 0x80)
00669 {
00670 curHTTP.httpStatus = HTTP_UNAUTHORIZED;
00671 smHTTP = SM_HTTP_SERVE_HEADERS;
00672 isDone = FALSE;
00673
00674 #if defined(HTTP_NO_AUTH_WITHOUT_SSL)
00675 if(!TCPIsSSL(sktHTTP))
00676 curHTTP.httpStatus = HTTP_SSL_REQUIRED;
00677 #endif
00678
00679 break;
00680 }
00681 #endif
00682
00683
00684 *curHTTP.ptrData = '\0';
00685 curHTTP.ptrData = HTTPURLDecode(curHTTP.data);
00686
00687
00688 #if defined(HTTP_MPFS_UPLOAD)
00689 if(curHTTP.httpStatus == HTTP_MPFS_FORM)
00690 {
00691 smHTTP = SM_HTTP_SERVE_HEADERS;
00692 isDone = FALSE;
00693 break;
00694 }
00695 #endif
00696
00697
00698 smHTTP = SM_HTTP_PROCESS_GET;
00699 if(!curHTTP.hasArgs)
00700 smHTTP = SM_HTTP_PROCESS_POST;
00701 isDone = FALSE;
00702 curHTTP.hasArgs = FALSE;
00703 break;
00704
00705 case SM_HTTP_PROCESS_GET:
00706
00707
00708 if(HTTPExecuteGet() == HTTP_IO_WAITING)
00709 {
00710 break;
00711 }
00712
00713
00714 smHTTP = SM_HTTP_PROCESS_POST;
00715
00716 case SM_HTTP_PROCESS_POST:
00717
00718 #if defined(HTTP_USE_POST)
00719
00720
00721 if(TCPIsGetReady(sktHTTP) == curHTTP.callbackPos)
00722 {
00723 if((LONG)(TickGet() - curHTTP.callbackID) > (LONG)0)
00724 {
00725 TCPDisconnect(sktHTTP);
00726 smHTTP = SM_HTTP_DISCONNECT;
00727 isDone = FALSE;
00728 break;
00729 }
00730 }
00731
00732 if(curHTTP.httpStatus == HTTP_POST
00733 #if defined(HTTP_MPFS_UPLOAD)
00734 || (curHTTP.httpStatus >= HTTP_MPFS_UP && curHTTP.httpStatus <= HTTP_MPFS_ERROR)
00735 #endif
00736 )
00737 {
00738
00739 #if defined(HTTP_MPFS_UPLOAD)
00740 if(curHTTP.httpStatus >= HTTP_MPFS_UP && curHTTP.httpStatus <= HTTP_MPFS_ERROR)
00741 {
00742 c = HTTPMPFSUpload();
00743 if(c == HTTP_IO_DONE)
00744 {
00745 smHTTP = SM_HTTP_SERVE_HEADERS;
00746 isDone = FALSE;
00747 break;
00748 }
00749 }
00750 else
00751 #endif
00752 c = HTTPExecutePost();
00753
00754
00755 if(c == HTTP_IO_WAITING)
00756 {
00757 curHTTP.callbackPos = TCPIsGetReady(sktHTTP) - 1;
00758 break;
00759 }
00760 else if(c == HTTP_IO_NEED_DATA)
00761 {
00762 curHTTP.callbackPos = TCPIsGetReady(sktHTTP);
00763 curHTTP.callbackID = TickGet() + HTTP_TIMEOUT*TICK_SECOND;
00764
00765
00766 if(curHTTP.byteCount > curHTTP.callbackPos && TCPGetRxFIFOFree(sktHTTP) != 0)
00767 break;
00768
00769
00770 curHTTP.httpStatus = HTTP_INTERNAL_SERVER_ERROR;
00771 smHTTP = SM_HTTP_SERVE_HEADERS;
00772 isDone = FALSE;
00773 break;
00774 }
00775 }
00776 #endif
00777
00778
00779 smHTTP = SM_HTTP_PROCESS_REQUEST;
00780
00781
00782 case SM_HTTP_PROCESS_REQUEST:
00783
00784
00785 if(curHTTP.file == MPFS_INVALID_HANDLE)
00786 {
00787 curHTTP.httpStatus = HTTP_NOT_FOUND;
00788 smHTTP = SM_HTTP_SERVE_HEADERS;
00789 isDone = FALSE;
00790 break;
00791 }
00792
00793
00794 curHTTP.byteCount = 0;
00795 if(curHTTP.offsets == MPFS_INVALID_HANDLE)
00796 {
00797 curHTTP.nextCallback = 0xffffffff;
00798 }
00799 else
00800 {
00801 MPFSGetLong(curHTTP.offsets, &(curHTTP.nextCallback));
00802 }
00803
00804
00805 smHTTP = SM_HTTP_SERVE_HEADERS;
00806
00807 case SM_HTTP_SERVE_HEADERS:
00808
00809
00810
00811
00812 TCPAdjustFIFOSize(sktHTTP, 1, 0, TCP_ADJUST_GIVE_REST_TO_TX);
00813
00814
00815 TCPPutROMString(sktHTTP, (ROM BYTE*)HTTPResponseHeaders[curHTTP.httpStatus]);
00816
00817
00818 if(curHTTP.httpStatus == HTTP_REDIRECT)
00819 {
00820 TCPPutString(sktHTTP, curHTTP.data);
00821 TCPPutROMString(sktHTTP, (ROM BYTE*)"\r\n\r\n304 Redirect: ");
00822 TCPPutString(sktHTTP, curHTTP.data);
00823 TCPPutROMString(sktHTTP, (ROM BYTE*)HTTP_CRLF);
00824 }
00825
00826
00827 if(curHTTP.httpStatus != HTTP_GET && curHTTP.httpStatus != HTTP_POST)
00828 {
00829 smHTTP = SM_HTTP_DISCONNECT;
00830 break;
00831 }
00832
00833
00834 if(curHTTP.fileType != HTTP_UNKNOWN)
00835 {
00836 TCPPutROMString(sktHTTP, (ROM BYTE*)"Content-Type: ");
00837 TCPPutROMString(sktHTTP, (ROM BYTE*)httpContentTypes[curHTTP.fileType]);
00838 TCPPutROMString(sktHTTP, HTTP_CRLF);
00839 }
00840
00841
00842 if(MPFSGetFlags(curHTTP.file) & MPFS2_FLAG_ISZIPPED)
00843 {
00844 TCPPutROMString(sktHTTP, (ROM BYTE*)"Content-Encoding: gzip\r\n");
00845 }
00846
00847
00848 TCPPutROMString(sktHTTP, (ROM BYTE*)"Cache-Control: ");
00849 if(curHTTP.httpStatus == HTTP_POST || curHTTP.nextCallback != 0xffffffff)
00850 {
00851 TCPPutROMString(sktHTTP, (ROM BYTE*)"no-cache");
00852 }
00853 else
00854 {
00855 TCPPutROMString(sktHTTP, (ROM BYTE*)"max-age=");
00856 TCPPutROMString(sktHTTP, (ROM BYTE*)HTTP_CACHE_LEN);
00857 }
00858 TCPPutROMString(sktHTTP, HTTP_CRLF);
00859
00860
00861 if(curHTTP.hasArgs)
00862 smHTTP = SM_HTTP_SERVE_COOKIES;
00863 else
00864 {
00865 TCPPutROMString(sktHTTP, HTTP_CRLF);
00866 smHTTP = SM_HTTP_SERVE_BODY;
00867 }
00868
00869
00870 isDone = FALSE;
00871 break;
00872
00873 case SM_HTTP_SERVE_COOKIES:
00874
00875 #if defined(HTTP_USE_COOKIES)
00876
00877
00878
00879
00880 for(curHTTP.ptrRead = curHTTP.data; curHTTP.hasArgs != 0; curHTTP.hasArgs--)
00881 {
00882
00883 TCPPutROMString(sktHTTP, (ROM BYTE*)"Set-Cookie: ");
00884
00885
00886 while((c = *(curHTTP.ptrRead++)))
00887 {
00888 if(c == ' ')
00889 TCPPut(sktHTTP, '+');
00890 else if(c < '0' || (c > '9' && c < 'A') || (c > 'Z' && c < 'a') || c > 'z')
00891 {
00892 TCPPut(sktHTTP, '%');
00893 TCPPut(sktHTTP, btohexa_high(c));
00894 TCPPut(sktHTTP, btohexa_low(c));
00895 }
00896 else
00897 TCPPut(sktHTTP, c);
00898 }
00899
00900 TCPPut(sktHTTP, '=');
00901
00902
00903 while((c = *(curHTTP.ptrRead++)))
00904 {
00905 if(c == ' ')
00906 TCPPut(sktHTTP, '+');
00907 else if(c < '0' || (c > '9' && c < 'A') || (c > 'Z' && c < 'a') || c > 'z')
00908 {
00909 TCPPut(sktHTTP, '%');
00910 TCPPut(sktHTTP, btohexa_high(c));
00911 TCPPut(sktHTTP, btohexa_low(c));
00912 }
00913 else
00914 TCPPut(sktHTTP, c);
00915 }
00916
00917
00918 TCPPutROMString(sktHTTP, HTTP_CRLF);
00919
00920 }
00921 #endif
00922
00923
00924 TCPPutROMString(sktHTTP, HTTP_CRLF);
00925 smHTTP = SM_HTTP_SERVE_BODY;
00926
00927 case SM_HTTP_SERVE_BODY:
00928
00929 isDone = FALSE;
00930
00931
00932 if(HTTPSendFile())
00933 {
00934 MPFSClose(curHTTP.file);
00935 curHTTP.file = MPFS_INVALID_HANDLE;
00936 smHTTP = SM_HTTP_DISCONNECT;
00937 isDone = TRUE;
00938 }
00939
00940
00941 if(TCPIsPutReady(sktHTTP) == 0)
00942 isDone = TRUE;
00943 break;
00944
00945 case SM_HTTP_SEND_FROM_CALLBACK:
00946
00947 isDone = TRUE;
00948
00949
00950 if(TCPIsPutReady(sktHTTP) < HTTP_MIN_CALLBACK_FREE)
00951 break;
00952
00953
00954 HTTPPrint(curHTTP.callbackID);
00955
00956 if(curHTTP.callbackPos == 0)
00957 {
00958 isDone = FALSE;
00959 smHTTP = SM_HTTP_SERVE_BODY;
00960 }
00961
00962 break;
00963
00964 case SM_HTTP_DISCONNECT:
00965
00966 if(curHTTP.file != MPFS_INVALID_HANDLE)
00967 {
00968 MPFSClose(curHTTP.file);
00969 curHTTP.file = MPFS_INVALID_HANDLE;
00970 }
00971 if(curHTTP.offsets != MPFS_INVALID_HANDLE)
00972 {
00973 MPFSClose(curHTTP.offsets);
00974 curHTTP.offsets = MPFS_INVALID_HANDLE;
00975 }
00976
00977 TCPDisconnect(sktHTTP);
00978 smHTTP = SM_HTTP_IDLE;
00979 break;
00980 }
00981 } while(!isDone);
00982
00983 }
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004 static BOOL HTTPSendFile(void)
01005 {
01006 WORD numBytes, len;
01007 BYTE c, data[64];
01008
01009
01010 len = TCPIsPutReady(sktHTTP);
01011 numBytes = mMIN(len, curHTTP.nextCallback - curHTTP.byteCount);
01012
01013
01014 curHTTP.byteCount += numBytes;
01015 while(numBytes > 0)
01016 {
01017 len = MPFSGetArray(curHTTP.file, data, mMIN(numBytes, 64));
01018 if(len == 0)
01019 return TRUE;
01020 else
01021 TCPPutArray(sktHTTP, data, len);
01022 numBytes -= len;
01023 }
01024
01025
01026 if(curHTTP.byteCount == curHTTP.nextCallback)
01027 {
01028
01029 smHTTP = SM_HTTP_SEND_FROM_CALLBACK;
01030 curHTTP.callbackPos = 0;
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045 MPFSGetLong(curHTTP.offsets, &(curHTTP.callbackID));
01046 if(!MPFSGetLong(curHTTP.offsets, &(curHTTP.nextCallback)))
01047 {
01048 curHTTP.nextCallback = 0xffffffff;
01049 MPFSClose(curHTTP.offsets);
01050 curHTTP.offsets = MPFS_INVALID_HANDLE;
01051 }
01052 }
01053
01054
01055 return FALSE;
01056 }
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 static void HTTPHeaderParseLookup(BYTE i)
01077 {
01078
01079
01080 #if defined(HTTP_USE_COOKIES)
01081 if(i == 0u)
01082 {
01083 HTTPHeaderParseCookie();
01084 return;
01085 }
01086 #endif
01087
01088 #if defined(HTTP_USE_AUTHENTICATION)
01089 if(i == 1u)
01090 {
01091 HTTPHeaderParseAuthorization();
01092 return;
01093 }
01094 #endif
01095
01096 #if defined(HTTP_USE_POST)
01097 if(i == 2u)
01098 {
01099 HTTPHeaderParseContentLength();
01100 return;
01101 }
01102 #endif
01103 }
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134 #if defined(HTTP_USE_AUTHENTICATION)
01135 static void HTTPHeaderParseAuthorization(void)
01136 {
01137 WORD len;
01138 BYTE buf[40];
01139 BYTE *ptrBuf;
01140
01141
01142 if(curHTTP.isAuthorized & 0x80)
01143 return;
01144
01145
01146 TCPGetArray(sktHTTP, NULL, 6);
01147
01148
01149 len = TCPFindROMArray(sktHTTP, HTTP_CRLF, HTTP_CRLF_LEN, 0, FALSE);
01150 len += 3;
01151 len &= 0xfc;
01152 len = mMIN(len, sizeof(buf)-4);
01153
01154
01155 for(ptrBuf = buf; len > 0; len-=4, ptrBuf+=3)
01156 {
01157 TCPGetArray(sktHTTP, ptrBuf, 4);
01158 Base64Decode(ptrBuf, 4, ptrBuf, 3);
01159 }
01160
01161
01162 *ptrBuf = '\0';
01163 for(len = 0, ptrBuf = buf; len < sizeof(buf); len++, ptrBuf++)
01164 if(*ptrBuf == ':')
01165 break;
01166 *(ptrBuf++) = '\0';
01167
01168
01169 curHTTP.isAuthorized = HTTPCheckAuth(buf, ptrBuf);
01170
01171 return;
01172 }
01173 #endif
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204 #if defined(HTTP_USE_COOKIES)
01205 static void HTTPHeaderParseCookie(void)
01206 {
01207 WORD lenA, lenB;
01208
01209
01210 lenB = TCPFindROMArray(sktHTTP, HTTP_CRLF, HTTP_CRLF_LEN, 0, FALSE);
01211 if(lenB >= curHTTP.data + HTTP_MAX_DATA_LEN - curHTTP.ptrData - 2)
01212 {
01213 curHTTP.httpStatus = HTTP_OVERFLOW;
01214 smHTTP = SM_HTTP_SERVE_HEADERS;
01215 return;
01216 }
01217
01218
01219 while(lenB != 0)
01220 {
01221
01222 lenA = TCPFind(sktHTTP, ';', 0, FALSE);
01223
01224
01225 curHTTP.ptrData += TCPGetArray(sktHTTP, curHTTP.ptrData, mMIN(lenA, lenB));
01226
01227
01228 *(curHTTP.ptrData++) = '&';
01229
01230
01231 if(lenA < lenB)
01232 {
01233 TCPGet(sktHTTP, NULL);
01234 while(TCPFind(sktHTTP, ' ', 0, FALSE) == 0)
01235 TCPGet(sktHTTP, NULL);
01236 }
01237
01238
01239 lenB = TCPFindROMArray(sktHTTP, HTTP_CRLF, HTTP_CRLF_LEN, 0, FALSE);
01240 }
01241
01242 return;
01243
01244 }
01245 #endif
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271 #if defined(HTTP_USE_POST)
01272 static void HTTPHeaderParseContentLength(void)
01273 {
01274 WORD len;
01275 BYTE buf[10];
01276
01277
01278 len = TCPFindROMArray(sktHTTP, HTTP_CRLF, HTTP_CRLF_LEN, 0, FALSE);
01279 len = TCPGetArray(sktHTTP, buf, len);
01280 buf[len] = '\0';
01281
01282 curHTTP.byteCount = atol((char*)buf);
01283
01284 return;
01285
01286 }
01287 #endif
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321 BYTE* HTTPURLDecode(BYTE* cData)
01322 {
01323 BYTE *pRead, *pWrite;
01324 WORD wLen;
01325 BYTE c;
01326 WORD_VAL hex;
01327
01328
01329 wLen = strlen((char*)cData);
01330
01331
01332 for(pRead = pWrite = cData; wLen != 0; )
01333 {
01334 c = *pRead++;
01335 wLen--;
01336
01337 if(c == '=' || c == '&')
01338 *pWrite++ = '\0';
01339 else if(c == '+')
01340 *pWrite++ = ' ';
01341 else if(c == '%')
01342 {
01343 if(wLen < 2)
01344 wLen = 0;
01345 else
01346 {
01347 hex.v[1] = *pRead++;
01348 hex.v[0] = *pRead++;
01349 wLen--;
01350 wLen--;
01351 *pWrite++ = hexatob(hex);
01352 }
01353 }
01354 else
01355 *pWrite++ = c;
01356 }
01357
01358
01359 *pWrite++ = '\0';
01360 *pWrite = '\0';
01361
01362 return pWrite;
01363 }
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391 BYTE* HTTPGetArg(BYTE* cData, BYTE* cArg)
01392 {
01393
01394 while(*cData != '\0')
01395 {
01396
01397 if(!strcmp((char*)cArg, (char*)cData))
01398 {
01399 return cData + strlen((char*)cArg) + 1;
01400 }
01401
01402
01403 cData += strlen((char*)cData) + 1;
01404 cData += strlen((char*)cData) + 1;
01405 }
01406
01407
01408 return NULL;
01409 }
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440 #if defined(__18CXX)
01441 BYTE* HTTPGetROMArg(BYTE* cData, ROM BYTE* cArg)
01442 {
01443
01444 while(*cData != '\0')
01445 {
01446
01447 if(!memcmppgm2ram(cData, (ROM void*)cArg, strlenpgm((ROM char*)cArg) + 1))
01448 {
01449 return cData + strlenpgm((ROM char*)cArg) + 1;
01450 }
01451
01452
01453 cData += strlen((char*)cData) + 1;
01454 cData += strlen((char*)cData) + 1;
01455 }
01456
01457
01458 return NULL;
01459 }
01460 #endif
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501 #if defined(HTTP_USE_POST)
01502 HTTP_READ_STATUS HTTPReadPostName(BYTE* cData, WORD wLen)
01503 {
01504 HTTP_READ_STATUS status;
01505
01506 status = HTTPReadTo('=', cData, wLen);
01507
01508
01509 if(cData && !*cData)
01510 HTTPURLDecode(cData);
01511 return status;
01512 }
01513 #endif
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556 #if defined(HTTP_USE_POST)
01557 HTTP_READ_STATUS HTTPReadPostValue(BYTE* cData, WORD wLen)
01558 {
01559 HTTP_READ_STATUS status;
01560
01561
01562 status = HTTPReadTo('&', cData, wLen);
01563
01564
01565 if(status == HTTP_READ_INCOMPLETE)
01566 {
01567
01568 if(curHTTP.byteCount == TCPIsGetReady(sktHTTP))
01569 status = HTTPReadTo('\0', cData, wLen);
01570 }
01571
01572
01573 if(cData && *cData)
01574 HTTPURLDecode(cData);
01575 return status;
01576 }
01577 #endif
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615 #if defined(HTTP_USE_POST)
01616 static HTTP_READ_STATUS HTTPReadTo(BYTE cDelim, BYTE* cData, WORD wLen)
01617 {
01618 HTTP_READ_STATUS status;
01619 WORD wPos;
01620
01621
01622 if(cDelim)
01623 wPos = TCPFind(sktHTTP, cDelim, 0, FALSE);
01624 else
01625 wPos = TCPIsGetReady(sktHTTP);
01626
01627
01628 if(wPos == 0xffff)
01629 return HTTP_READ_INCOMPLETE;
01630
01631
01632 if(wLen < 2 && cData != NULL)
01633 {
01634 curHTTP.byteCount -= TCPGetArray(sktHTTP, NULL, wPos);
01635 status = HTTP_READ_TRUNCATED;
01636 }
01637 else if(cData == NULL)
01638 {
01639 curHTTP.byteCount -= TCPGetArray(sktHTTP, NULL, wPos);
01640 status = HTTP_READ_OK;
01641 }
01642 else if(wPos > wLen - 2)
01643 {
01644 curHTTP.byteCount -= TCPGetArray(sktHTTP, cData, wLen - 2);
01645 curHTTP.byteCount -= TCPGetArray(sktHTTP, NULL, wPos - (wLen - 2));
01646 cData[wLen - 2] = '\0';
01647 status = HTTP_READ_TRUNCATED;
01648 }
01649 else
01650 {
01651 curHTTP.byteCount -= TCPGetArray(sktHTTP, cData, wPos);
01652 cData[wPos] = '\0';
01653 status = HTTP_READ_OK;
01654 }
01655
01656
01657 if(cDelim)
01658 curHTTP.byteCount -= TCPGet(sktHTTP, NULL);
01659
01660 return status;
01661 }
01662 #endif
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696 #if defined(HTTP_MPFS_UPLOAD)
01697 static HTTP_IO_RESULT HTTPMPFSUpload(void)
01698 {
01699 BYTE c[16];
01700 WORD lenA, lenB;
01701
01702 switch(curHTTP.httpStatus)
01703 {
01704
01705 case HTTP_MPFS_UP:
01706
01707 lenA = TCPFindROMArray(sktHTTP, (ROM BYTE*)"\r\n\r\n", 4, 0, FALSE);
01708
01709 if(lenA != 0xffff)
01710 {
01711 lenA = TCPGetArray(sktHTTP, NULL, lenA);
01712 curHTTP.byteCount -= lenA;
01713
01714
01715 if(TCPIsGetReady(sktHTTP) < (4 + 6) )
01716 {
01717 lenA++;
01718 return HTTP_IO_NEED_DATA;
01719 }
01720
01721
01722 lenA = TCPGetArray(sktHTTP, c, 10);
01723 curHTTP.byteCount -= lenA;
01724 if(memcmppgm2ram(c, (ROM void*)"\r\n\r\nMPFS\x02\x01", 10) == 0)
01725 {
01726 curHTTP.httpStatus = HTTP_MPFS_OK;
01727
01728
01729 curHTTP.file = MPFSFormat();
01730 MPFSPutArray(curHTTP.file, &c[4], 6);
01731 }
01732 else
01733 {
01734 curHTTP.httpStatus = HTTP_MPFS_ERROR;
01735 }
01736 }
01737 else
01738 {
01739 lenA = TCPGetArray(sktHTTP, NULL, TCPIsGetReady(sktHTTP) - 4);
01740 curHTTP.byteCount -= lenA;
01741 }
01742
01743 break;
01744
01745
01746 case HTTP_MPFS_ERROR:
01747 curHTTP.byteCount -= TCPIsGetReady(sktHTTP);
01748 TCPDiscard(sktHTTP);
01749 if(curHTTP.byteCount < 100 || curHTTP.byteCount > 0x80000000)
01750 {
01751 smHTTP = SM_HTTP_SERVE_HEADERS;
01752 return HTTP_IO_DONE;
01753 }
01754 break;
01755
01756
01757 case HTTP_MPFS_OK:
01758
01759 lenA = TCPIsGetReady(sktHTTP);
01760 if(lenA > curHTTP.byteCount)
01761 lenA = curHTTP.byteCount;
01762
01763 while(lenA > 0)
01764 {
01765 lenB = TCPGetArray(sktHTTP, c, mMIN(lenA,16));
01766 curHTTP.byteCount -= lenB;
01767 lenA -= lenB;
01768 MPFSPutArray(curHTTP.file, c, lenB);
01769 }
01770
01771
01772 if(curHTTP.byteCount == 0)
01773 {
01774 MPFSPutEnd(TRUE);
01775 smHTTP = SM_HTTP_SERVE_HEADERS;
01776 return HTTP_IO_DONE;
01777 }
01778
01779
01780 default:
01781 break;
01782 }
01783
01784
01785 return HTTP_IO_NEED_DATA;
01786
01787 }
01788 #endif
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824 void HTTPIncFile(ROM BYTE* cFile)
01825 {
01826 WORD wCount, wLen;
01827 BYTE data[64];
01828 MPFS_HANDLE fp;
01829
01830
01831 if(curHTTP.callbackPos == 0x00)
01832 {
01833 fp = MPFSOpenROM(cFile);
01834 if(fp == MPFS_INVALID_HANDLE)
01835 {
01836 return;
01837 }
01838 ((DWORD_VAL*)&curHTTP.callbackPos)->w[0] = MPFSGetID(fp);
01839 }
01840 else
01841 {
01842 fp = MPFSOpenID(((DWORD_VAL*)&curHTTP.callbackPos)->w[0]);
01843 if(fp == MPFS_INVALID_HANDLE)
01844 {
01845 return;
01846 }
01847 MPFSSeek(fp, ((DWORD_VAL*)&curHTTP.callbackPos)->w[1], MPFS_SEEK_FORWARD);
01848 }
01849
01850
01851 wCount = TCPIsPutReady(sktHTTP);
01852 while(wCount > 0)
01853 {
01854 wLen = MPFSGetArray(fp, data, mMIN(wCount, 64));
01855 if(wLen == 0)
01856 {
01857 MPFSClose(fp);
01858 curHTTP.callbackPos = 0x00;
01859 return;
01860 }
01861 else
01862 {
01863 TCPPutArray(sktHTTP, data, wLen);
01864 wCount -= wLen;
01865 }
01866 }
01867
01868
01869 ((DWORD_VAL*)&curHTTP.callbackPos)->w[1] = MPFSTell(fp);
01870 MPFSClose(fp);
01871
01872 return;
01873 }
01874
01875
01876 #endif
01877
01878
01879
01880 BOOL HTTPCheckForIdle(void)
01881 {
01882 BYTE conn;
01883
01884 for(conn = 0; conn < MAX_HTTP_CONNECTIONS; conn++)
01885 {
01886 if((httpStubs[conn].sm != SM_HTTP_IDLE) || TCPIsGetReady(httpStubs[conn].socket))
01887 {
01888 return FALSE;
01889 }
01890 }
01891
01892 return TRUE;
01893 }
01894