Overview

Namespaces

  • Contrib
    • Bundle
      • CoverallsBundle
        • Console
        • Entity
      • CoverallsV1Bundle
        • Api
        • Collector
        • Command
        • Config
        • Entity
          • Git
    • Component
      • File
      • Log
      • System
        • Git
  • Guzzle
    • Batch
      • Exception
    • Cache
    • Common
      • Exception
    • Http
      • Curl
      • Exception
      • Message
      • QueryAggregator
    • Inflection
    • Iterator
    • Log
    • Parser
      • Cookie
      • Message
      • UriTemplate
      • Url
    • Plugin
      • Async
      • Backoff
      • Cache
      • Cookie
        • CookieJar
        • Exception
      • CurlAuth
      • ErrorResponse
        • Exception
      • History
      • Log
      • Md5
      • Mock
      • Oauth
    • Service
      • Builder
      • Command
        • Factory
        • LocationVisitor
          • Request
          • Response
      • Description
      • Exception
      • Resource
    • Stream
  • PHP
  • Psr
    • Log
  • Symfony
    • Component
      • Config
        • Definition
          • Builder
          • Exception
        • Exception
        • Loader
        • Resource
        • Util
      • Console
        • Command
        • Formatter
        • Helper
        • Input
        • Output
        • Tester
      • EventDispatcher
        • Debug
      • Finder
        • Adapter
        • Comparator
        • Exception
        • Expression
        • Iterator
        • Shell
      • Stopwatch
      • Yaml
        • Exception

Classes

  • AbstractMessage
  • EntityEnclosingRequest
  • Header
  • HeaderComparison
  • PostFile
  • Request
  • RequestFactory
  • Response

Interfaces

  • EntityEnclosingRequestInterface
  • MessageInterface
  • PostFileInterface
  • RequestFactoryInterface
  • RequestInterface
  • Overview
  • Namespace
  • Class
  • Tree
  • Todo
  1: <?php
  2: 
  3: namespace Guzzle\Http\Message;
  4: 
  5: use Guzzle\Http\EntityBody;
  6: use Guzzle\Http\EntityBodyInterface;
  7: use Guzzle\Http\QueryString;
  8: use Guzzle\Http\RedirectPlugin;
  9: use Guzzle\Http\Exception\RequestException;
 10: use Guzzle\Http\Mimetypes;
 11: 
 12: /**
 13:  * HTTP request that sends an entity-body in the request message (POST, PUT, PATCH, DELETE)
 14:  */
 15: class EntityEnclosingRequest extends Request implements EntityEnclosingRequestInterface
 16: {
 17:     /**
 18:      * @var int When the size of the body is greater than 1MB, then send Expect: 100-Continue
 19:      */
 20:     protected $expectCutoff = 1048576;
 21: 
 22:     /**
 23:      * @var EntityBodyInterface $body Body of the request
 24:      */
 25:     protected $body;
 26: 
 27:     /**
 28:      * @var QueryString POST fields to use in the EntityBody
 29:      */
 30:     protected $postFields;
 31: 
 32:     /**
 33:      * @var array POST files to send with the request
 34:      */
 35:     protected $postFiles = array();
 36: 
 37:     /**
 38:      * {@inheritdoc}
 39:      */
 40:     public function __construct($method, $url, $headers = array())
 41:     {
 42:         $this->postFields = new QueryString();
 43:         parent::__construct($method, $url, $headers);
 44:     }
 45: 
 46:     /**
 47:      * Get the HTTP request as a string
 48:      *
 49:      * @return string
 50:      */
 51:     public function __toString()
 52:     {
 53:         // Only attempt to include the POST data if it's only fields
 54:         if (count($this->postFields) && empty($this->postFiles)) {
 55:             return parent::__toString() . (string) $this->postFields;
 56:         }
 57: 
 58:         return parent::__toString() . $this->body;
 59:     }
 60: 
 61:     /**
 62:      * {@inheritdoc}
 63:      */
 64:     public function setState($state, array $context = array())
 65:     {
 66:         parent::setState($state, $context);
 67:         if ($state == self::STATE_TRANSFER && !$this->body && !count($this->postFields) && !count($this->postFiles)) {
 68:             $this->setHeader('Content-Length', 0)->removeHeader('Transfer-Encoding');
 69:         }
 70: 
 71:         return $this;
 72:     }
 73: 
 74:     /**
 75:      * {@inheritdoc}
 76:      */
 77:     public function setBody($body, $contentType = null, $tryChunkedTransfer = false)
 78:     {
 79:         $this->body = EntityBody::factory($body);
 80: 
 81:         // Auto detect the Content-Type from the path of the request if possible
 82:         if ($contentType === null && !$this->hasHeader('Content-Type')) {
 83:             $contentType = $this->body->getContentType() ?: Mimetypes::getInstance()->fromFilename($this->getPath());
 84:         }
 85: 
 86:         if ($contentType) {
 87:             $this->setHeader('Content-Type', (string) $contentType);
 88:         }
 89: 
 90:         // Always add the Expect 100-Continue header if the body cannot be rewound. This helps with redirects.
 91:         if (!$this->body->isSeekable() && $this->expectCutoff !== false) {
 92:             $this->setHeader('Expect', '100-Continue');
 93:         }
 94: 
 95:         if ($tryChunkedTransfer) {
 96:             $this->removeHeader('Content-Length');
 97:             $this->setHeader('Transfer-Encoding', 'chunked');
 98:         } else {
 99:             // Set the Content-Length header if it can be determined
100:             $size = $this->body->getContentLength();
101:             if ($size !== null && $size !== false) {
102:                 $this->setHeader('Content-Length', $size);
103:                 if ($size > $this->expectCutoff) {
104:                     $this->setHeader('Expect', '100-Continue');
105:                 }
106:             } elseif (!$this->hasHeader('Content-Length')) {
107:                 if ('1.1' == $this->protocolVersion) {
108:                     $this->setHeader('Transfer-Encoding', 'chunked');
109:                 } else {
110:                     throw new RequestException(
111:                         'Cannot determine Content-Length and cannot use chunked Transfer-Encoding when using HTTP/1.0'
112:                     );
113:                 }
114:             }
115:         }
116: 
117:         return $this;
118:     }
119: 
120:     /**
121:      * {@inheritdoc}
122:      */
123:     public function getBody()
124:     {
125:         return $this->body;
126:     }
127: 
128:     /**
129:      * Set the size that the entity body of the request must exceed before adding the Expect: 100-Continue header.
130:      *
131:      * @param int|bool $size Cutoff in bytes. Set to false to never send the expect header (even with non-seekable data)
132:      *
133:      * @return self
134:      */
135:     public function setExpectHeaderCutoff($size)
136:     {
137:         $this->expectCutoff = $size;
138:         if ($size === false || !$this->body) {
139:             $this->removeHeader('Expect');
140:         } elseif ($this->body && $this->body->getSize() && $this->body->getSize() > $size) {
141:             $this->setHeader('Expect', '100-Continue');
142:         }
143: 
144:         return $this;
145:     }
146: 
147:     /**
148:      * {@inheritdoc}
149:      */
150:     public function configureRedirects($strict = false, $maxRedirects = 5)
151:     {
152:         $this->getParams()->set(RedirectPlugin::STRICT_REDIRECTS, $strict);
153:         if ($maxRedirects == 0) {
154:             $this->getParams()->set(RedirectPlugin::DISABLE, true);
155:         } else {
156:             $this->getParams()->set(RedirectPlugin::MAX_REDIRECTS, $maxRedirects);
157:         }
158: 
159:         return $this;
160:     }
161: 
162:     /**
163:      * {@inheritdoc}
164:      */
165:     public function getPostField($field)
166:     {
167:         return $this->postFields->get($field);
168:     }
169: 
170:     /**
171:      * {@inheritdoc}
172:      */
173:     public function getPostFields()
174:     {
175:         return $this->postFields;
176:     }
177: 
178:     /**
179:      * {@inheritdoc}
180:      */
181:     public function setPostField($key, $value)
182:     {
183:         $this->postFields->set($key, $value);
184:         $this->processPostFields();
185: 
186:         return $this;
187:     }
188: 
189:     /**
190:      * {@inheritdoc}
191:      */
192:     public function addPostFields($fields)
193:     {
194:         $this->postFields->merge($fields);
195:         $this->processPostFields();
196: 
197:         return $this;
198:     }
199: 
200:     /**
201:      * {@inheritdoc}
202:      */
203:     public function removePostField($field)
204:     {
205:         $this->postFields->remove($field);
206:         $this->processPostFields();
207: 
208:         return $this;
209:     }
210: 
211:     /**
212:      * {@inheritdoc}
213:      */
214:     public function getPostFiles()
215:     {
216:         return $this->postFiles;
217:     }
218: 
219:     /**
220:      * {@inheritdoc}
221:      */
222:     public function getPostFile($fieldName)
223:     {
224:         return isset($this->postFiles[$fieldName]) ? $this->postFiles[$fieldName] : null;
225:     }
226: 
227:     /**
228:      * {@inheritdoc}
229:      */
230:     public function removePostFile($fieldName)
231:     {
232:         unset($this->postFiles[$fieldName]);
233:         $this->processPostFields();
234: 
235:         return $this;
236:     }
237: 
238:     /**
239:      * {@inheritdoc}
240:      */
241:     public function addPostFile($field, $filename = null, $contentType = null)
242:     {
243:         $data = null;
244: 
245:         if ($field instanceof PostFileInterface) {
246:             $data = $field;
247:         } elseif (is_array($filename)) {
248:             // Allow multiple values to be set in a single key
249:             foreach ($filename as $file) {
250:                 $this->addPostFile($field, $file, $contentType);
251:             }
252:             return $this;
253:         } elseif (!is_string($filename)) {
254:             throw new RequestException('The path to a file must be a string');
255:         } elseif (!empty($filename)) {
256:             // Adding an empty file will cause cURL to error out
257:             $data = new PostFile($field, $filename, $contentType);
258:         }
259: 
260:         if ($data) {
261:             if (!isset($this->postFiles[$data->getFieldName()])) {
262:                 $this->postFiles[$data->getFieldName()] = array($data);
263:             } else {
264:                 $this->postFiles[$data->getFieldName()][] = $data;
265:             }
266:             $this->processPostFields();
267:         }
268: 
269:         return $this;
270:     }
271: 
272:     /**
273:      * {@inheritdoc}
274:      */
275:     public function addPostFiles(array $files)
276:     {
277:         foreach ($files as $key => $file) {
278:             if ($file instanceof PostFileInterface) {
279:                 $this->addPostFile($file, null, null, false);
280:             } elseif (is_string($file)) {
281:                 // Convert non-associative array keys into 'file'
282:                 if (is_numeric($key)) {
283:                     $key = 'file';
284:                 }
285:                 $this->addPostFile($key, $file, null, false);
286:             } else {
287:                 throw new RequestException('File must be a string or instance of PostFileInterface');
288:             }
289:         }
290: 
291:         return $this;
292:     }
293: 
294:     /**
295:      * Determine what type of request should be sent based on post fields
296:      */
297:     protected function processPostFields()
298:     {
299:         if (empty($this->postFiles)) {
300:             $this->removeHeader('Expect')->setHeader('Content-Type', self::URL_ENCODED);
301:         } else {
302:             $this->setHeader('Content-Type', self::MULTIPART);
303:             if ($this->expectCutoff !== false) {
304:                 $this->setHeader('Expect', '100-Continue');
305:             }
306:         }
307:     }
308: }
309: 
php-coveralls API documentation generated by ApiGen 2.8.0