POST II: Bestanden uploaden

Het is tijd om nog een stapje verder te gaan, we gaan verder met het
2e bekende POST data type, namelijk multipart/form-data. Deze is
natuurlijk bekend van de file uploads, en dat is dus ook wat we gaan
doen, bestanden uploaden.
Dit is weer net iets moeilijker, aangezien een request nu uit meerdere
delen gaat bestaan, die afgescheiden zijn door zogenaamde boundaries.
Een boundary is gewoon een willekeurig gekozen hoeveelheid tekens die
niet verder in de data voor komt. Het body gedeelte bestaat dan
uiteindelijk uit stukjes die beginnen met een regel met eerst twee
streepjes ("--") vervolgens de boundary, daarna op aparte regels de
header, gevolgd door een witregel en daarna de data zelf. Het laatste
stukje wordt afgesloten door de boundary met aan beide kanten twee
streepjes ("--"). De headers van een stukje bevatten sowieso een
Content-Disposition header die de naam van het stukje data aangeeft en
aangeeft dat het een stukje data is.
Een voorbeeld request volgt hieronder:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /example.php HTTP/1.0
Host: www.example.org
Connection: close
User-Agent: LegolasWeb Socket Browser 1.0.2
Content-Type: multipart/form-data; boundary=boundsX
Content-Length: 250

--boundsX
Content-Disposition: form-data; name="iets"

hoi
--boundsX
Content-Disposition: form-data; name="niets"

doei
--boundsX
Content-Disposition: form-data; name="test"; filename="test.txt"
Content-Type: text/plain

test
--boundsX--

Dit is niets meer dan het formulier van hierboven met een tekst
bestandje erbij. Het illustreert ook meteen goed dat je
multipart/form-data alleen moet gebruiken als het ook echt nodig is,
anders wordt je request onnodig groot.
Dit alles weer in het socket script verwerkt geeft deze creatie:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<?php

// Nodige informatie
define('SERVER', 'www.example.org');
define('PORT', 80);
define('PATH', '/example.php');

// Versie
define('VERSION', '1.0');

// End of line
define('_EOL', "\r\n");

// Data
$data = array('test' => array(null, null, 'wiej!'), 'fiets' =>
array(null, null, 'pomp'), '35@&%' => array(null, null, '?&='), 'file'
=> array('text/plain', 'test.txt', 'test'));

// Maak een socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
if (!$sock) {
       echo 'Fatal error: Couldn\'t create socket';
       exit;
}


// Maak verbinding
if (!socket_connect($sock, SERVER, PORT)) {
       echo 'Fatal error: Couldn\'t connect';
       exit;
}


// Maak een boundary
$bound = null;
for ($i = 0; $i < 15; $i++) {
       $bound .= chr(rand(33, 126));
}


// Maak het body stuk
$body = null;
foreach ($data as $var => $content) {
       $body .= '--' . $bound . _EOL;
       if ($content[0] != null) {
               $body .= 'Content-Disposition: form-data; name="' . $var . '";
filename="'
. $content[1] . '"' . _EOL;
               $body .= 'Content-Type: ' . $content[0] . _EOL;
       }

       else {
               $body .= 'Content-Disposition: form-data; name="' .
$var . '"' . _EOL;
       }

       $body .= _EOL;
       $body .= $content[2] . _EOL;
}

$body .= '--' . $bound . '--';

// Maak het request
$request = null;
$request .= 'POST ' . PATH . ' HTTP/1.0' . _EOL;
$request .= 'Host: ' . SERVER . _EOL;
$request .= 'User-Agent: LegolasWeb WebBrowserDemo ' . VERSION . _EOL;
$request .= 'Content-Type: multipart/form-data; boundary=' . $bound . _EOL;
$request .= 'Content-Length: ' . strlen($body) . _EOL;
$request .= _EOL;
$request .= $body;

// En verstuur het
if (!socket_send($sock, $request, strlen($request), 0)) {
       echo 'Fatal error: Couldn\'t send request';
       exit;
}


// Haal de response op
$output = null;
$buffer = null;
while (socket_recv($sock, $buffer, 1024, 0) != 0) {
       $output .= $buffer;
}


// Isoleer het body gedeelte en toon het
$output = explode(_EOL . _EOL, $output);
$output = $output[1];
echo $output;

?>

Hiermee gaat dan dus de wereld van het uploaden van bestanden voor je
open, maar dan vooral de wereld er achter. Je zou nu dus al kunnen
gaan werken aan een script dat automatisch back-ups voor je maakt of
iets in die richting.

« Lees de omschrijving en reacties

Inhoudsopgave

  1. Inleiding
  2. Basiskennis HTTP
  3. GET: Een pagina opvragen
  4. POST I: Een formulier verzenden
  5. POST II: Bestanden uploaden
  6. De response headers en status
  7. Proxies
  8. En nu?

PHP tutorial opties

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.