/** * Add a Header * * @param mixed $header * Header name. Possible values are: * * <ul> * * <li>An integer as HTTP Response State Header</li> * * <li> * * A well-formed Header Field. * * It'll be used "as is", an instance of * Next\HTTP\Headers\Fields\Field * </li> * * <li> * * A Header Field Name. * * We'll try to match a valid one or send it as "Generic" * </li> * * <li> * * An associative array of Header Fields to be added * recursively, where each value can be a well-formed * Header Field or a Header Field Name * </li> * * </ul> * * @param string|optional $value * Header Field Value * * @return Next\HTTP\Headers\AbstractHeaders * AbstractHeaders Object (Fluent Interface) * * @throws Next\HTTP\Headers\Fields\FieldsException * Invalid or mal-formed Header Value */ public function addHeader($header, $value = NULL) { if (is_null($header)) { return $this; } // Well-formed Header Field. Don't need to be known if ($header instanceof Field) { if ($this->accept($header)) { $this->headers->add($header); } return $this; } // Recursion... if (is_array($header)) { foreach ($header as $n => $v) { // Usually non-associative arrays have Headers in their values if ($v instanceof Field) { $this->addHeader($v, $n); } else { $this->addHeader($n, $v); } } } else { // Preparing Header Name for Classname Mapping $header = strtolower(str_replace('HTTP_', '', $header)); $header = ucfirst(preg_replace('/(-|_)(\\w)/e', "strtoupper( '\\2' )", $header)); // Checking if its a known Header Field if (array_key_exists($header, $this->known)) { // Building full Classname... $class = sprintf('%s\\%s', self::FIELDS_NS, $this->known[$header]); // ... checking if it exists... if (class_exists($class)) { try { // ...and trying to add it $object = new $class($value); if ($this->accept($object)) { $this->headers->add($object); } } catch (FieldsException $e) { /** * @internal * We'll rethrow the same Exception caught if a true error occur * so our Exception Handler can do the rest */ if ($e->getCode() !== FieldsException::ALL_INVALID) { throw FieldsException::invalidHeaderValue($e->getMessage(), $e->getCode()); } } } } else { /** * @internal * If it is a unknown header, let's add it as Generic Header * * Generic Header don't need to be accepted */ $this->addHeader(new Generic(sprintf('%s: %s', $header, $value))); } } return $this; }
/** * Add a Coookie * * Cookie definition: <em>cookiename[=cookievalue]</em> * * @param string|array $cookie * Cookie to add * * @param string|optional $value * Cookie value, in case a non RFC definition is being used * * @return Next\HTTP\Cookies * Cookies Object (Fluent Interface) * * @throws Next\HTTP\Headers\Fields\FieldsException * Invalid or mal-formed Cookie Value */ public function addCookie($cookie, $value = NULL) { // Well-formed Cookie. Will be added "as is" if ($cookie instanceof Cookie) { $this->cookies->add($cookie); return $this; } // Recursion... if (is_array($cookie)) { foreach ($cookie as $n => $v) { $this->addCookie($n, $v); } } else { /** * @internal * In case Next\HTTP\Cookies::addCookie() was invoked like: * * $cookies -> addCookie( 'cookiename', 'cookievalue' ) * * Instead of: * * $cookies -> addCookie( 'cookiename=cookievalue' ) * * Let's build the full Cookie representation before add it */ if (!is_null($value) && strpos($value, '=') === FALSE) { $cookie = sprintf('%s=%s', $cookie, $value); } try { $this->cookies->add(new Cookie($cookie)); } catch (FieldsException $e) { /** * @internal * We'll rethrow the same Exception caught if a true error occur * so our Exception Handler can do the rest */ if ($e->getCode() !== FieldsException::ALL_INVALID) { throw FieldsException::invalidHeaderValue($e->getMessage(), $e->getCode()); } } } return $this; }
/** * Set Header Value * * - Prepare it by cleaning and/or apply pre-verification routines * * - Check it, using specific validators which follows one or more RFC specification(s) * * - Adjust it by apply a post-validation callback over it * * @param string $value * Header Value * * @throws Next\HTTP\Headers\Fields\FieldsException * All possible values assigned to the Header are invalid */ private function setValue($value) { // Removing Header's Name from value, if present $value = preg_replace(sprintf('/%s:?/', $this->options->name), '', $value); /** * @internal * Will the header need whitespaces? * * Most of Header's Fields does not need any whitespace, but some, like Date, does. * So, before remove them, we have to check if they are required, or not */ if ($this->options->preserveWhitespace === FALSE) { $value = preg_replace('/\\s{2,}/', ' ', $value); } $value = trim($value); // Removing all remaining boundary whitespaces // Executing Routines BEFORE Validation $value = $this->preCheck($value); //-------------------------- $valid = array(); // The Header accepts multiple values? /** * @internal * Test if this seperation is REALLY necessary and, * if not, use just one foreach, outside the IF */ if ($this->options->acceptMultiples !== FALSE && strpos($value, $this->options->multiplesSeparator) !== FALSE) { // Splitting and cleaning it $value = array_map('trim', array_filter(explode($this->options->multiplesSeparator, $value))); // Counting, in order to make sure we have something to work if (count($value) != 0) { foreach ($value as $v) { if ($this->getValidator()->validate(trim($v)) !== FALSE) { // Adding value, AFTER applied POST Validations Routines $valid[] = $this->postCheck($v); } } } } else { // If the Header does not accepts multiple values, let's validate just once if ($this->getValidator()->validate($value) !== FALSE) { // Adding value, AFTER applied POST Validations Routines $valid[] = $this->postCheck($value); } } // Do we have at least one valid value? if (count($valid) == 0) { throw FieldsException::invalidHeaderValue($this->options->name); } // Building Header $this->value = implode(sprintf('%s ', $this->options->multiplesSeparator), $valid); }