scratch – Blame information for rev 87

Subversion Repositories:
Rev:
Rev Author Line No. Line
87 office 1 <?php
2  
3 namespace GuzzleHttp\Subscriber;
4  
5 use GuzzleHttp\Event\BeforeEvent;
6 use GuzzleHttp\Event\RequestEvents;
7 use GuzzleHttp\Event\SubscriberInterface;
8 use GuzzleHttp\Message\RequestInterface;
9 use GuzzleHttp\Mimetypes;
10 use GuzzleHttp\Post\PostBodyInterface;
11 use GuzzleHttp\Stream\MetadataStreamInterface;
12 use GuzzleHttp\Stream\StreamInterface;
13  
14 /**
15 * Prepares requests with a body before sending
16 *
17 * **Request Options**
18 *
19 * - expect: Set to true to enable the "Expect: 100-Continue" header for a
20 * request that send a body. Set to false to disable "Expect: 100-Continue".
21 * Set to a number so that the size of the payload must be greater than the
22 * number in order to send the Expect header. Setting to a number will send
23 * the Expect header for all requests in which the size of the payload cannot
24 * be determined or where the body is not rewindable.
25 */
26 class Prepare implements SubscriberInterface
27 {
28 public function getEvents()
29 {
30 return ['before' => ['onBefore', RequestEvents::PREPARE_REQUEST]];
31 }
32  
33 public function onBefore(BeforeEvent $event)
34 {
35 $request = $event->getRequest();
36  
37 // Set the appropriate Content-Type for a request if one is not set and
38 // there are form fields
39 if (!($body = $request->getBody())) {
40 return;
41 }
42  
43 $this->addContentLength($request, $body);
44  
45 if ($body instanceof PostBodyInterface) {
46 // Synchronize the POST body with the request's headers
47 $body->applyRequestHeaders($request);
48 } elseif (!$request->hasHeader('Content-Type')) {
49 $this->addContentType($request, $body);
50 }
51  
52 $this->addExpectHeader($request, $body);
53 }
54  
55 private function addContentType(
56 RequestInterface $request,
57 StreamInterface $body
58 ) {
59 if (!($body instanceof MetadataStreamInterface)) {
60 return;
61 }
62  
63 if (!($uri = $body->getMetadata('uri'))) {
64 return;
65 }
66  
67 // Guess the content-type based on the stream's "uri" metadata value.
68 // The file extension is used to determine the appropriate mime-type.
69 if ($contentType = Mimetypes::getInstance()->fromFilename($uri)) {
70 $request->setHeader('Content-Type', $contentType);
71 }
72 }
73  
74 private function addContentLength(
75 RequestInterface $request,
76 StreamInterface $body
77 ) {
78 // Set the Content-Length header if it can be determined, and never
79 // send a Transfer-Encoding: chunked and Content-Length header in
80 // the same request.
81 if ($request->hasHeader('Content-Length')) {
82 // Remove transfer-encoding if content-length is set.
83 $request->removeHeader('Transfer-Encoding');
84 return;
85 }
86  
87 if ($request->hasHeader('Transfer-Encoding')) {
88 return;
89 }
90  
91 if (null !== ($size = $body->getSize())) {
92 $request->setHeader('Content-Length', $size)
93 ->removeHeader('Transfer-Encoding');
94 } elseif ('1.1' == $request->getProtocolVersion()) {
95 // Use chunked Transfer-Encoding if there is no determinable
96 // content-length header and we're using HTTP/1.1.
97 $request->setHeader('Transfer-Encoding', 'chunked')
98 ->removeHeader('Content-Length');
99 }
100 }
101  
102 private function addExpectHeader(
103 RequestInterface $request,
104 StreamInterface $body
105 ) {
106 // Determine if the Expect header should be used
107 if ($request->hasHeader('Expect')) {
108 return;
109 }
110  
111 $expect = $request->getConfig()['expect'];
112  
113 // Return if disabled or if you're not using HTTP/1.1
114 if ($expect === false || $request->getProtocolVersion() !== '1.1') {
115 return;
116 }
117  
118 // The expect header is unconditionally enabled
119 if ($expect === true) {
120 $request->setHeader('Expect', '100-Continue');
121 return;
122 }
123  
124 // By default, send the expect header when the payload is > 1mb
125 if ($expect === null) {
126 $expect = 1048576;
127 }
128  
129 // Always add if the body cannot be rewound, the size cannot be
130 // determined, or the size is greater than the cutoff threshold
131 $size = $body->getSize();
132 if ($size === null || $size >= (int) $expect || !$body->isSeekable()) {
133 $request->setHeader('Expect', '100-Continue');
134 }
135 }
136 }