windows - PHP - Filnavne i HTTP-overskrifter: Problem med hvide rum

Indlæg af Hanne Mølgaard Plasc

Problem



Arbejde med CakePHP og Java Web Start Jeg genererer den nødvendige .jnlp-fil i en controller, hvor jeg bl.a. sætter filnavnet som et overskriftsfelt. Det virker fint, så længe jeg ikke forsøger at bruge specielle tegn i filnavnet. Jeg vil dog gerne aktivere alle tegn, der er mulige på hovedoperativsystemerne som et filnavn. Så det jeg prøver at gøre er at fjerne alle de ugyldige tegn ved at erstatte dem med tomme strenge. Men der ser ud til at være et problem med hvide rum som skal tillades i filnavne.


Det er koden:


$panel\_id = 1
$panelname = 'w h i t e s p a c e s';
$filename = sprintf('"Project\_\%d\_\%s.jnlp"', $panel\_id, $panelname);
$invalid\_chars = array('<', '>', '?', '"', ':', '|', '\', '/', '*', '&');
$filename = str\_replace($invalid\_filenamechars, '', $filename);
$this->header('Content-Disposition: attachment; filename=' . $filename);


Når jeg gør det, er det resulterende filnavn i overskriften 'Project\_1\_w h i t e s p a c e', mens Windows 7 vil gemme filen som 'Project\_1\_w'. Så det ser ud til, at mit OS ikke accepterer unescaped whitespaces i filnavne? Jeg ville være tilfreds med den forklaring, hvis det ikke var for følgende: Jeg forlod linjerne 4 og 5, så koden ser ud


$panel\_id = 1
$panelname = 'w h i t e s p a c e s';
$filename = sprintf('"Project\_\%d\_\%s.jnlp"', $panel\_id, $panelname);
$this->header('Content-Disposition: attachment; filename=' . $filename);


Og nu er Windows villig til at gemme filen med alle sine hvide pladser, men jeg kan stadig ikke forstå hvorfor. Hvis jeg ser på filnavnet i overskrifterne ved hjælp af wireshark, er begge de samme. Og hvis sprintf-linjen erstattes med $filename = 'w h i t e s p a c e' eller endda $filename = $panelname, skærer den filnavnet som i det første kodestykke. Men jeg kan erstatte sprintf med dottet-string-concat syntaksen, og det virker.


Kan nogen fortælle mig, hvad jeg har udsigt til?

Bedste reference


Forskellen er de dobbelte citater. Med den første kode vil du ende med:


Content-Disposition: attachment; filename=Project\_1\_w h i t e s p a c e s.jnlp


med den anden kode vil du ende med:


Content-Disposition: attachment; filename="Project\_1\_w h i t e s p a c e s.jnlp"


Hvad du sandsynligvis vil have, er noget som:


$panel\_id = 1;
$panelname = 'w h i t e s p a c e s';
$filename = sprintf('"Project\_\%d\_\%s.jnlp"', $panel\_id, $panelname);
$invalid\_chars = array('<', '>', '?', '"', ':', '|', '\', '/', '*', '&');
$filename = str\_replace($invalid\_filenamechars, '', $filename);
$this->header('Content-Disposition: attachment; filename="'.$filename.'"');


Dette strimler eventuelle dobbelte citater inden for $ filnavn, men sørger derefter for, at $ filnavn altid er omgivet af dobbelt citater.

Andre referencer 1


RFC2616, som er HTTP/1.1 spec, siger dette: [12]



  Field-Disposition response-header-feltet er blevet foreslået som en
  betyder for oprindelsesserveren at foreslå et standardfilnavn, hvis brugeren
  anmoder om, at indholdet er gemt i en fil. Denne brug er afledt
  fra definitionen af ​​Content-Disposition i RFC 1806.


    content-disposition = "Content-Disposition" ":"
                          disposition-type *( ";" disposition-parm )
    disposition-type = "attachment" | disp-extension-token
    disposition-parm = filename-parm | disp-extension-parm
    filename-parm = "filename" "=" quoted-string
    disp-extension-token = token
    disp-extension-parm = token "=" ( token | quoted-string )

  
  Et eksempel er
          Indhold-disposition: vedhæftet fil filename='fname.ext'



Således sender du dette:


header('Content-Disposition: attachment; filename="' . $filename . '"');


svarer til den anden formular (quoted-string) og skal gøre hvad du forventer det til. Pas på kun at sende SPACE (ASCII dec 32/hex 20) som hvid plads, ikke nogle af de andre fancy hvide rum .