Is the F() print macro meant to generate an eth packet per character?

cossoft:
Sorry, is

"Connection: close\n\n"));  // including the additional empty line!

correct? I think that's two additional lines as it's messing up my transfers. Isn't a return automatically appended by println? It works for me with just one slash en.

HTTP request headers should be terminated by an empty line. standard requires them for GET request too. and HTTP requires \r\n not only \n.

use your original code only put BuffredPrint over client. Install StreamLib from Library Manager

if (c == '\n' && currentLineIsBlank) {
     char buff[64];
     BufferedPrint bp(client, buff, sizeof(buff));
     bp.println(F("HTTP/1.1 200 OK"));
     bp.println(F("Content-Type: application/octet-stream"));
     bp.println(F("Content-Length: 512"));
     bp.println(F("Connection: close")); 
     bp.println();
     bp.write(data);
     bp.flush();

you can even use printf with BufferedPrint

    bp.printf(F("Content-Length: %d\r\n"), dataLength);

read about StreamLib purpose
.