From 0202b7aa646399c0aa2fcbe95ce3444774f5df93 Mon Sep 17 00:00:00 2001 From: Remy Sharp Date: Sat, 23 Mar 2024 11:01:39 +0000 Subject: [PATCH] feat: error when the content-length header is missing --- README.md | 7 ++++--- http | Bin 5968 -> 5977 bytes http-debug.dot | Bin 6280 -> 6289 bytes src/headers.asm | 12 +++++++++++- src/main.asm | 8 +++++++- src/messages.asm | 1 + src/version.inc.asm | 2 +- src/wifi.asm | 32 ++++++++++++++++++++++++-------- 8 files changed, 48 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index e1dbc8f..2ba4486 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ A utility for application developers to talk to web servers to exchange blocks o .http post -b 22 -l 1024 -h 192.168.1.100 -p 8080 -u /send ; Download and save Manic Miner http://zxdb.remysharp.com/get/18840 -.http -h zxdb.remysharp.com -u /18840 -f manic.tap +.http -h zxdb.remysharp.com -u /get/18840 -f manic.tap -; Load http://data.remysharp.com/1 directly into bank 26 and flash border red (2) -.http get -b 26 -h data.remysharp.com -u /1 -v 2 +; Load http://data.remysharp.com/18 (the text "hello world") into bank 20 and flash border red (2) +.http get -b 20 -h data.remysharp.com -u /18 -v 2 ``` Options: @@ -109,6 +109,7 @@ I've written a number of [example servers](https://github.com/remy/next-http/tre - `K` Could not read the http content length header correctly - `L` Out of memory to buffer file download: try with `-r` to disable rolling banks - `M` Not enough memory to download: try with `-r` to disable rolling banks +- `N` content-length missing: .http requires the `content-length` header from the server to work properly ## Testing diff --git a/http b/http index 66fc78a7b721583571c3671f95dcafe8f23036fd..5e87c54f41c1302a210048290ffbcbc4e5995554 100644 GIT binary patch delta 2385 zcma)7eM}t372iGJzQ_?ThpWM^>C7&eox5Z2SnlAuCRaX=7(y;M0Tf%Q97VRS3*jdL+x9q9OA9{?8EH5!p(2xa)+u! zt@E4eMv=HNzpXmvAfJU6iqu*$_ll#4bl2DKY7{hSlbM$Va!9%K9vp2louU0|F$N_u zL%lBxesPm7KRT{n4pN8cYYFmk5L9YyQnT7wBLtJo+DdgOD3YT3Xa`xwmmH$dE-~+R z^n^5~%NyD9gpcYqpQwI<^>g1xpaC6Y$)cZF^mmMsln<5HGUXXdxzD157VTwJ*wsjc z2%l$DHOE2^D*m1!8^6WSJ}LHqQd4ak)DEk4h|gNH*mP_ zz`lWRAAS*jcmJV7`v*Q@Hw6CBx*`**?#l-8VUVK&*^HmHj0-ks&po|v`jn$Tp8gBJt{QRxqdcy% zlb8I!-rCm@^0*1`N2931SLII+T9{2YNRKaC zG_{P;`I;s}Tck~`jPdFsMtgl#P6p_tQP1@DdECI(WRMfsd|bAHJ51<;ON>Eyjj`?U zG8y&j26}CMzb|GIGUl>qca3-*qv0Cy21aN8mnZtjSLG!yrT*jw$(Q|z_gC3iDmF2Y zAus!59P+?0%~3wR3n+4eoM+w71lX?9-+pE5-^yvmpdW~{WB{0y8cu)i?Y1J4## zr>TSQIxbY#3Qsa^7yK<_Pr~Hu%z9(Z>W24pV~p-BZGm@=p<;6`>D z-Ki0mF#5_?R_43@s#2DCX`vOp9Z$s{%Vf#Ty3b2syTstVbVhjCFjnq8vQPx$*=c=9 zpL7O>&Em>j*)Xo=8=BC=29i}5txW!#q)X|Kfk{Ir;W%y17gFjD z{QoJ9O_Q@poR&%{)Cz+_j;*Y?pM43&>>M2`lJsS@W$3(fu>MTF6ZpJviibiBj&;B< zx6u={(NBRcx@Bng(%VGE4w(E0<8k-_V;)H8<)mM}brC)AJ*ITSKm3Ps?cjF6*9&pS zC?l8Z#LHNtQ+Dz~-6EZ7S?wyOEhY8gkS$}xIQ1&dv~}m&uVGqg2^})JA@Je(k(@f> zIDZ&+Op_C-9?zEK6>R5va&IlNLCJ;F^fdwY`D$Prl)S7*r>saetmINM8!F5z@FtDM zX=cBz8}S5KqH}}grp;UkCE^&naF3mHf$RLzhs3S$-~pq@@|2d{W+WdAHoKw^a&6O1 zw25hB^liB!dod&IR7hC4h;}MtX6Up8?!`ib2E#~L7?e_s1j9(AU|E9y`NTk37vCS` zr`de!qmQ1ttT3^kiMN!rH9etc_^0ZMl6$qUIrnP6L8~zM{5NPN0)MoT%e`f+YRk;3 z-J-OghUl_gTS+x;i1W8oM>f(n3BWzli}sJa`CsLvzn z(NEJBmc&P^2#86<}IY+K?$tP39c}CH+8(CBKb>Yeng)<59deK z+lqKcStZYfZf-gC{&_e%wHl^Z-N6Eztm#HGfp^(*sxjOIDhr4O&6<3jaeY2xpzlQZ z5_&Dsw<3HoJ23Qv2rsP*dzp|$2O~VPQ;~j|Gv$&O+(mmLyv=fYfrYcMJrhrF%=7;S D?Te)Q delta 2326 zcma)7T}&L;6`omsc3ConVI6nu*!bQVU}yGcScY9#4|v1Rl9*x&v7w2axKX5}QmWRG zn<`)#SgS96s;g%6kcT!>mBuSouCPV>kVZ;@Wo^dzy2c4?J4=;Y3*7wI7ELrNdDF=Y}0kAQ|oHvy$NdV1|9Z_q^u>{M=mR?1P;?rI>B2oWQ=NlFMcD|{2(j2za;=fP!a*%N_%i9bRfkI;y)8Xv^K>jHehPAkPS z$E(Bzr5G6fwNM7Z@j>5$k{P#L(F&Gv36=V8NsCGlM4oD$qiW~)hps2ipuY+o0JGf+ z%FY$yNraXK)cYN?FmgwI^w4LOHdgOy zv>4f=Uu#Yw4l~CgKXU*ax3uVIl@xLb8T=8gLDA1i{T5ygCCeRK9k=9}9S%=LHSGlS zs@)1R`gM#cp~gC51rg z83xw3{GbQNVvvx_+@{U5%RE|cj$5e?>=6DUuVxZ5R`U4U zjp79bA88aXD){98^2D>gdJlOqnRN?^!+xCe)jMb^4l$4;hy5{*q?DK&$h3A=NpJY* z_CvDU>XWxYcDsd}R55`5K^cc~c3M>4k5-E8B4tD9TyZrE4!#RY@pRqj4Au6d-%z#> zCElXeizTZY-7%(MV`(SaFs4$AR@I`#En4nHsuMoXXYkEN@sfgTn&>It@Yh$j)To@3X`P&}VWji=^6@gKFy=RZmK^{AARAF>>% zd|IV-I z+z-A6V|fK;ha`R7*>W(}oU}ga*8>j@4tQ8@f?ClE_~kCRKnMI2U@;)?vJOBqf!K#W zN>Cn0A5g|20=;=wvD=VCvsC9s?>x};qf=BjjNUFry$Ot*4vO=N4x@DbRPY82uDrge zq+}Oq3C9?1QOWfTn7xJqXDo*~V(@G@J7H=QOFu&K41_1gxgG8WrIHykPu~z1l5cX~ zkim`46uFu#hl=AzI7xlyXr;b1;)B8(%m#8Id6nBb`f-pI?h&BBC;+Ybl9EEKxw9&I z&+MTUo--zYCvVAL$?>X6-0Bsqs#8{IRub;SLSqK|#b1b|QV5^`A*lc%CBIoS$bN6; zjhcQo+2!z!HnSNzbw=RH(iT-Jj#AN3=j<7XxT8PO&a38YBc0}JqXwjHu!YAUb)G%m z#+av#+xjB4>ITqJ2uaD6`uSvAZJfQ3JXY&1Cn{M@o~#XH8)Pg%Iz!QiY{b#AfcSB< zLH-cJYjox&@7DV2yGpJWvX?)y^U0vLKbXhI{gc{v z@Pzgp1|MC@2|tFXbYF6r_clnPaE0%Ygb(0J6#m3_H3;Wd4vsoFv2=)r>AK+4Ldk< I@R0)hAJg8Eq5uE@ diff --git a/http-debug.dot b/http-debug.dot index 708559aafbdf416604371e8c9f1410556a8fdb94..7f3537de942c65f37b25af6f39eb960512284916 100644 GIT binary patch delta 2361 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 Lo0*&W!aDyiJZ^Y) diff --git a/src/headers.asm b/src/headers.asm index 48a902e..57a8fb3 100644 --- a/src/headers.asm +++ b/src/headers.asm @@ -57,7 +57,7 @@ tmpBuffer: ; Modifies: AF, HL, DE contentLengthSub: or a ; reset carry for sbc - ld hl, (contentLength) ; do the LSW first + ld hl, (contentLength) ; do the LSW first sbc hl, de ld (contentLength), hl ret nc @@ -93,6 +93,10 @@ findContentLength call Uart.read ; load A with the next character dec de + ;; if there's an immediate CR, then we're on a blank, and we need to bail + cp CR + jp z, .contentLengthNotFound + ;; convert character to uppercase cp 'a' ; if A < 'a' then skip case shift jr c, .noCaseShiftC @@ -234,11 +238,17 @@ findContentLength call Uart.read : dec de ; LR jp .processHeader +.contentLengthNotFound + ; set carry to indicate failure + scf + jr .exit + .slurpToEndOfAllHeaders call Uart.read : dec de : cp CR : jr nz, .slurpToEndOfAllHeaders call Uart.read : dec de ; LR call Uart.read : dec de : cp CR : jr nz, .slurpToEndOfAllHeaders call Uart.read : dec de ; LR + and a ; clear carry .exit pop ix ret diff --git a/src/main.asm b/src/main.asm index 9ad82d8..7b121cc 100644 --- a/src/main.asm +++ b/src/main.asm @@ -328,6 +328,7 @@ Get call Wifi.tcpSendString LoadPackets call Wifi.getPacket + jr c, .contentLenghtMissing ;; reduce the content length left to read ld de, (Wifi.bufferLength) @@ -382,10 +383,15 @@ LoadPackets jr LoadPackets +.contentLenghtMissing: + ld hl, Err.contentLengthMissing + jp Error + .contentLenghtError: ld hl, Err.contentLength jp Error + PreExitCheck ld a, (State.fileMode) cp NOT_WRITING_TO_FILE @@ -472,7 +478,7 @@ diagBinPcLo EQU ((100*diagBinSz)%8192)*10/8192 ;; delete any autoexec.bas SHELLEXEC "(hdfmonkey rm /Applications/cspect/app/cspect-next-2gb.img /nextzxos/autoexec.bas > /dev/null) || exit 0" SHELLEXEC "hdfmonkey put /Applications/cspect/app/cspect-next-2gb.img http-debug.dot /devel/http-debug.dot" - SHELLEXEC "mono /Applications/cspect/app/cspect.exe -r -w5 -basickeys -zxnext -nextrom -exit -brk -tv -mmc=/Applications/cspect/app/cspect-next-2gb.img -map=./http.map -sd2=/Applications/cspect/app/empty-32mb.img" ; -com='/dev/tty.wchusbserial1430:11520' + SHELLEXEC "mono /Applications/cspect/app/cspect.exe -r -w5 -basickeys -zxnext -nextrom -exit -brk -mmc=/Applications/cspect/app/cspect-next-2gb.img -map=./http.map" ENDIF : ENDIF DISPLAY "TEST BUILD" ENDIF diff --git a/src/messages.asm b/src/messages.asm index 0b82716..9cc1016 100644 --- a/src/messages.asm +++ b/src/messages.asm @@ -21,6 +21,7 @@ fileOpen DC "J Can't open file for writing" contentLength DC "K Content length error" outOfMemory DC "L Out of memory: try '-r'" notEnoughMemory DC "M Not enough memory: try '-r'" +contentLengthMissing DC "N content-length missing" ENDMODULE MODULE Msg diff --git a/src/version.inc.asm b/src/version.inc.asm index 799c885..fd3d8d7 100644 --- a/src/version.inc.asm +++ b/src/version.inc.asm @@ -1,5 +1,5 @@ IFNDEF TESTING - DEFINE VERSION "1.0.3" + DEFINE VERSION "1.0.4" ELSE DEFINE VERSION "TEST" ENDIF diff --git a/src/wifi.asm b/src/wifi.asm index 01d49ff..e27d3ab 100644 --- a/src/wifi.asm +++ b/src/wifi.asm @@ -28,7 +28,7 @@ init: EspCmdOkErr "AT+CIPMUX=0" ; Single connection mode jr c, .initError - and a + and a ; reset the carry flag ret .initError call RetartESP @@ -49,7 +49,7 @@ RetartESP: EspCmd "AT+RST" jr .checkWifiConnect .alreadyTried - scf + scf ; set the carry: fail ret .checkWifiConnect: call Uart.read @@ -60,10 +60,9 @@ RetartESP: call Uart.read : cp ' ' : jr nz, .checkWifiConnect call Uart.read : cp 'G' : jr nz, .checkWifiConnect ; searching for "WIFI CONNECTED" call flushToLF - and a - ret - + and a ; clear the carry + ret closeTCP EspCmdOkErr "AT+CIPCLOSE" ret @@ -102,7 +101,8 @@ checkOkErr: call Uart.read : cp 'K' : jr nz, checkOkErr call Uart.read : cp 13 : jr nz, checkOkErr call flushToLF - and a + + and a ; clear the carry ret .errStart call Uart.read : cp 'R' : jr nz, checkOkErr @@ -124,6 +124,8 @@ checkOkErr: flushToLF call Uart.read cp 10 : jr nz, flushToLF + + and a ; clear the carry ret ; HL = buff @@ -350,6 +352,7 @@ getPacket: call Uart.read : cp 13 : jr nz, getPacket ld a, 1 ld (closed), a + and a ; clear the cary ret .cspectHack ;; I don't know why, but cspect gives us OK\n\r after the http request @@ -357,6 +360,7 @@ getPacket: call Uart.read : cp 10 : jr nz, getPacket ld a, 1 ld (closed), a + and a ; clear the cary ret .ipdBegun call Uart.read : cp 'I' : jr nz, getPacket @@ -384,20 +388,30 @@ getPacket: ;; we're searching for "content-length:" call Headers.findContentLength + ;; if there's a carry flag, then it failed and we bail + ;; out leaving the carry in place + jr nc, .processHeaderNoError + pop hl + ret + +.processHeaderNoError ld a, 0 ld (firstRead), a .headerProcessed pop hl - ld b, d ; load DE (back) into BC + ld b, d ; load DE (back) into BC ld c, e - ld (bufferLength), bc ; save the length for saving to file + ld (bufferLength), bc ; save the length for saving to file ;; check if the header was all we got in the IPD request ld a, b or c jr nz, .headerProcessedContinue ld (bufferPointer), hl + + ;; then we need to clear the carry flag, as there's no error + and a ret .headerProcessedContinue @@ -476,6 +490,7 @@ getPacket: or c jr nz, .readp ld (bufferPointer), hl + and a ; clear the cary ret .outOfMemory @@ -498,6 +513,7 @@ getPacket: ld a, b or c jr nz, .skipSavingBuffer + and a ; clear the cary ret .slurp