• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

I_RecHttp.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   HTTP configuration support.
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 #ifndef _I_REC_HTTP_H
00025 #define _I_REC_HTTP_H
00026 
00027 #include <ts/ink_inet.h>
00028 #include <ts/ink_resolver.h>
00029 #include <ts/apidefs.h>
00030 #include <ts/Vec.h>
00031 #include <ts/apidefs.h>
00032 
00033 /// Load default inbound IP addresses from the configuration file.
00034 void RecHttpLoadIp(
00035   char const* name,    ///< Name of value in configuration file.
00036   IpAddr& ip4, ///< [out] IPv4 address.
00037   IpAddr& ip6  ///< [out] Ipv6 address.
00038 );
00039 
00040 /** A set of session protocols.
00041     This depends on using @c SessionProtocolNameRegistry to get the indices.
00042 */
00043 class SessionProtocolSet {
00044   typedef SessionProtocolSet self; ///< Self reference type.
00045   /// Storage for the set - a bit vector.
00046   uint32_t m_bits;
00047 public:
00048   // The right way.
00049   //  static int const MAX = sizeof(m_bits) * CHAR_BIT;
00050   // The RHEL5/gcc 4.1.2 way
00051   static int const MAX = sizeof(uint32_t) * 8;
00052   /// Default constructor.
00053   /// Constructs and empty set.
00054   SessionProtocolSet() : m_bits(0) { }
00055 
00056   uint32_t indexToMask(int idx) const {
00057     return 0 <= idx && idx < static_cast<int>(MAX)
00058       ? static_cast<uint32_t>(1) << idx
00059       : 0
00060       ;
00061   }
00062 
00063   /// Mark the protocol at @a idx as present.
00064   void markIn(int idx) { m_bits |= this->indexToMask(idx); }
00065   /// Mark all the protocols in @a that as present in @a this.
00066   void markIn(self const& that) { m_bits |= that.m_bits; }
00067   /// Mark the protocol at a idx as not present.
00068   void markOut(int idx) { m_bits &= ~this->indexToMask(idx); }
00069   /// Mark the protocols in @a that as not in @a this.
00070   void markOut(self const& that) { m_bits &= ~(that.m_bits); }
00071   /// Test if a protocol is in the set.
00072   bool contains(int idx) const { return 0 != (m_bits & this->indexToMask(idx)); }
00073   /// Test if all the protocols in @a that are in @a this protocol set.
00074   bool contains(self const& that) const { return that.m_bits == (that.m_bits & m_bits); }
00075   /// Mark all possible protocols.
00076   void markAllIn() { m_bits = ~static_cast<uint32_t>(0); }
00077   /// Clear all protocols.
00078   void markAllOut() { m_bits = 0; }
00079 
00080   /// Check for intersection.
00081   bool intersects(self const& that) { return 0 != (m_bits & that.m_bits); }
00082 
00083   /// Check for empty set.
00084   bool isEmpty() const { return m_bits == 0; }
00085 
00086   /// Equality (identical sets).
00087   bool operator == (self const& that) const { return m_bits == that.m_bits; }
00088 };
00089 
00090 // Predefined sets of protocols, useful for configuration.
00091 extern SessionProtocolSet HTTP_PROTOCOL_SET;
00092 extern SessionProtocolSet HTTP2_PROTOCOL_SET;
00093 extern SessionProtocolSet SPDY_PROTOCOL_SET;
00094 extern SessionProtocolSet DEFAULT_NON_TLS_SESSION_PROTOCOL_SET;
00095 extern SessionProtocolSet DEFAULT_TLS_SESSION_PROTOCOL_SET;
00096 
00097 /** Registered session protocol names.
00098 
00099     We do this to avoid lots of string compares. By normalizing the
00100     string names we can just compare their indices in this table.
00101 
00102     @internal To simplify the implementation we limit the maximum
00103     number of strings to 32. That will be sufficient for the forseeable
00104     future. We can come back to this if it ever becomes a problem.
00105 
00106     @internal Because we have so few strings we just use a linear search.
00107     If the size gets much larger we should consider doing something more
00108     clever.
00109 */
00110 class SessionProtocolNameRegistry {
00111  public:
00112   static int const MAX  = SessionProtocolSet::MAX; ///< Maximum # of registered names.
00113   static int const INVALID = -1; ///< Normalized invalid index value.
00114 
00115   /// Default constructor.
00116   /// Creates empty registry with no names.
00117   SessionProtocolNameRegistry();
00118 
00119   /// Destructor.
00120   /// Cleans up strings.
00121   ~SessionProtocolNameRegistry();
00122 
00123   /** Get the index for @a name, registering it if needed.
00124       The name is copied internally.
00125       @return The index for the registered @a name.
00126   */
00127   int toIndex(char const* name);
00128 
00129   /** Get the index for @a name, registering it if needed.
00130       The caller @b guarantees @a name is persistent and immutable.
00131       @return The index for the registered @a name.
00132   */
00133   int toIndexConst(char const* name);
00134 
00135   /** Convert a @a name to an index.
00136       @return The index for @a name or @c INVALID if it is not registered.
00137   */
00138   int indexFor(char const* name) const;
00139 
00140   /** Convert an @a index to the corresponding name.
00141       @return A pointer to the name or @c NULL if the index isn't registered.
00142   */
00143   char const* nameFor(int index) const;
00144 
00145   /// Mark protocols as present in @a sp_set based on the names in @a value.
00146   /// The names can be separated by ;/|,: and space.
00147   /// @internal This is separated out to make it easy to access from the plugin API
00148   /// implementation.
00149   void markIn(char const* value, SessionProtocolSet& sp_set);
00150 
00151  protected:
00152   unsigned int m_n; ///< Index of first unused slot.
00153   char const* m_names[MAX]; ///< Pointers to registered names.
00154   uint8_t m_flags[MAX]; ///< Flags for each name.
00155 
00156   static uint8_t const F_ALLOCATED = 0x1; ///< Flag for allocated by this instance.
00157 };
00158 
00159 extern SessionProtocolNameRegistry globalSessionProtocolNameRegistry;
00160 
00161 /** Description of an proxy port.
00162 
00163     This consolidates the options needed for proxy ports, both data
00164     and parsing. It provides a static global set of ports for
00165     convenience although it can be used with an externally provided
00166     set.
00167 
00168     Options are described by a colon separated list of keywords
00169     without spaces. The options are applied in left to right order. If
00170     options do not conflict the order is irrelevant.
00171 
00172     IPv6 addresses must be enclosed by brackets. Unfortunate but colon is
00173     so overloaded there's no other option.
00174  */
00175 struct HttpProxyPort {
00176 private:
00177   typedef HttpProxyPort self; ///< Self reference type.
00178 public:
00179   /// Explicitly supported collection of proxy ports.
00180   typedef Vec<self> Group;
00181 
00182   /// Type of transport on the connection.
00183   enum TransportType {
00184     TRANSPORT_DEFAULT = 0, ///< Default (normal HTTP).
00185     TRANSPORT_COMPRESSED, ///< Compressed HTTP.
00186     TRANSPORT_BLIND_TUNNEL, ///< Blind tunnel (no processing).
00187     TRANSPORT_SSL, ///< SSL connection.
00188     TRANSPORT_PLUGIN /// < Protocol plugin connection
00189   };
00190 
00191   int m_fd; ///< Pre-opened file descriptor if present.
00192   TransportType m_type; ///< Type of connection.
00193   in_port_t m_port; ///< Port on which to listen.
00194   uint8_t m_family; ///< IP address family.
00195   /// True if inbound connects (from client) are transparent.
00196   bool m_inbound_transparent_p;
00197   /// True if outbound connections (to origin servers) are transparent.
00198   bool m_outbound_transparent_p;
00199   // True if transparent pass-through is enabled on this port.
00200   bool m_transparent_passthrough;
00201   /// Local address for inbound connections (listen address).
00202   IpAddr m_inbound_ip;
00203   /// Local address for outbound connections (to origin server).
00204   IpAddr m_outbound_ip4;
00205   /// Local address for outbound connections (to origin server).
00206   IpAddr m_outbound_ip6;
00207   /// Ordered preference for DNS resolution family ( @c FamilyPrefence )
00208   /// A value of @c PREFER_NONE indicates that entry and subsequent ones
00209   /// are invalid.
00210   HostResPreferenceOrder m_host_res_preference;
00211   /// Static preference list that is the default value.
00212   static HostResPreferenceOrder const DEFAULT_HOST_RES_PREFERENCE;
00213   /// Enabled session transports for this port.
00214   SessionProtocolSet m_session_protocol_preference;
00215 
00216   /// Default constructor.
00217   HttpProxyPort();
00218 
00219   /** Select the local outbound address object.
00220 
00221       @return The IP address for @a family
00222   */
00223   IpAddr& outboundIp(
00224     uint16_t family ///< IP address family.
00225   );
00226 
00227   /// Check for SSL port.
00228   bool isSSL() const;
00229 
00230   /// Check for SSL port.
00231   bool isPlugin() const;
00232 
00233   /// Process options text.
00234   /// @a opts should not contain any whitespace, only the option string.
00235   /// This object's internal state is updated as specified by @a opts.
00236   /// @return @c true if a port option was successfully processed, @c false otherwise.
00237   bool processOptions(
00238     char const* opts ///< String containing the options.
00239   );
00240 
00241   /** Global instance.
00242 
00243       This is provided because most of the work with this data is used as a singleton
00244       and it's handy to encapsulate it here.
00245   */
00246   static Vec<self>& global();
00247 
00248   /// Check for SSL ports.
00249   /// @return @c true if any port in @a ports is an SSL port.
00250   static bool hasSSL(
00251                      Group const& ports ///< Ports to check.
00252                      );
00253 
00254   /// Check for SSL ports.
00255   /// @return @c true if any global port is an SSL port.
00256   static bool hasSSL();
00257 
00258   /** Load all relevant configuration data.
00259 
00260       This is hardwired to look up the appropriate values in the
00261       configuration files. It clears @a ports and then loads all found
00262       values in to it.
00263 
00264       @return @c true if at least one valid port description was
00265       found, @c false if none.
00266   */
00267   static bool loadConfig(
00268     Vec<self>& ports ///< Destination for found port data.
00269   );
00270 
00271   /** Load all relevant configuration data into the global ports.
00272 
00273       @return @c true if at least one valid port description was
00274       found, @c false if none.
00275   */
00276   static bool loadConfig();
00277 
00278   /** Load ports from a value string.
00279 
00280       Load ports from single string with port descriptors. Ports
00281       found are added to @a ports. @a value may safely be @c NULL or empty.
00282 
00283       @note This is used primarily internally but is available if needed.
00284       @return @c true if a valid port was found, @c false if none.
00285   */
00286   static bool loadValue(
00287     Vec<self>& ports, ///< Destination for found port data.
00288     char const* value ///< Source port data.
00289   );
00290 
00291   /** Load ports from a value string into the global ports.
00292 
00293       Load ports from single string of port descriptors into the
00294       global set of ports. @a value may safely be @c NULL or empty.
00295 
00296       @return @c true if a valid port was found, @c false if none.
00297   */
00298   static bool loadValue(
00299     char const* value ///< Source port data.
00300   );
00301 
00302   /// Load default value if @a ports is empty.
00303   /// @return @c true if the default was needed / loaded.
00304   static bool loadDefaultIfEmpty(
00305     Vec<self>& ports ///< Load target.
00306   );
00307 
00308   /// Load default value into the global set if it is empty.
00309   /// @return @c true if the default was needed / loaded.
00310   static bool loadDefaultIfEmpty();
00311 
00312   /** Find an HTTP port in @a ports.
00313       If @a family is specified then only ports for that family
00314       are checked.
00315       @return The port if found, @c NULL if not.
00316   */
00317   static self* findHttp(
00318                         Group const& ports, ///< Group to search.
00319                         uint16_t family = AF_UNSPEC  ///< Desired address family.
00320                         );
00321 
00322   /** Find an HTTP port in the global ports.
00323       If @a family is specified then only ports for that family
00324       are checked.
00325       @return The port if found, @c NULL if not.
00326   */
00327   static self* findHttp(uint16_t family = AF_UNSPEC);
00328 
00329   /** Create text description to be used for inter-process access.
00330       Prints the file descriptor and then any options.
00331 
00332       @return The number of characters used for the description.
00333   */
00334   int print(
00335     char* out, ///< Output string.
00336     size_t n ///< Maximum output length.
00337   );
00338 
00339   static char const* const PORTS_CONFIG_NAME; ///< New unified port descriptor.
00340 
00341   /// Default value if no other values can be found.
00342   static char const* const DEFAULT_VALUE;
00343 
00344   // Keywords (lower case versions, but compares should be case insensitive)
00345   static char const* const OPT_FD_PREFIX; ///< Prefix for file descriptor value.
00346   static char const* const OPT_OUTBOUND_IP_PREFIX; ///< Prefix for inbound IP address.
00347   static char const* const OPT_INBOUND_IP_PREFIX; ///< Prefix for outbound IP address.
00348   static char const* const OPT_IPV6; ///< IPv6.
00349   static char const* const OPT_IPV4; ///< IPv4
00350   static char const* const OPT_TRANSPARENT_INBOUND; ///< Inbound transparent.
00351   static char const* const OPT_TRANSPARENT_OUTBOUND; ///< Outbound transparent.
00352   static char const* const OPT_TRANSPARENT_FULL; ///< Full transparency.
00353   static char const* const OPT_TRANSPARENT_PASSTHROUGH; ///< Pass-through non-HTTP.
00354   static char const* const OPT_SSL; ///< SSL (experimental)
00355   static char const* const OPT_PLUGIN; ///< Protocol Plugin handle (experimental)
00356   static char const* const OPT_BLIND_TUNNEL; ///< Blind tunnel.
00357   static char const* const OPT_COMPRESSED; ///< Compressed.
00358   static char const* const OPT_HOST_RES_PREFIX; ///< Set DNS family preference.
00359   static char const* const OPT_PROTO_PREFIX; ///< Transport layer protocols.
00360 
00361   static Vec<self>& m_global; ///< Global ("default") data.
00362 
00363 protected:
00364   /// Process @a value for DNS resolution family preferences.
00365   void processFamilyPreference(char const* value);
00366   /// Process @a value for session protocol preferences.
00367   void processSessionProtocolPreference(char const* value);
00368 
00369   /** Check a prefix option and find the value.
00370       @return The address of the start of the value, or @c NULL if the prefix doesn't match.
00371   */
00372 
00373   char const* checkPrefix( char const* src ///< Input text
00374                          , char const* prefix ///< Keyword prefix
00375                          , size_t prefix_len ///< Length of keyword prefix.
00376                          );
00377 };
00378 
00379 inline bool HttpProxyPort::isSSL() const { return TRANSPORT_SSL == m_type; }
00380 inline bool HttpProxyPort::isPlugin() const { return TRANSPORT_PLUGIN == m_type; }
00381 
00382 inline IpAddr&
00383 HttpProxyPort::outboundIp(uint16_t family) {
00384   static IpAddr invalid; // dummy to make compiler happy about return.
00385   if (AF_INET == family) return m_outbound_ip4;
00386   else if (AF_INET6 == family) return m_outbound_ip6;
00387   ink_release_assert(!"Invalid family for outbound address on proxy port.");
00388   return invalid; // never happens but compiler insists.
00389 }
00390 
00391 inline bool
00392 HttpProxyPort::loadValue(char const* value) {
00393   return self::loadValue(m_global, value);
00394 }
00395 inline bool
00396 HttpProxyPort::loadConfig() {
00397   return self::loadConfig(m_global);
00398 }
00399 inline bool
00400 HttpProxyPort::loadDefaultIfEmpty() {
00401   return self::loadDefaultIfEmpty(m_global);
00402 }
00403 inline Vec<HttpProxyPort>&
00404 HttpProxyPort::global() {
00405   return m_global;
00406 }
00407 inline bool
00408 HttpProxyPort::hasSSL() {
00409   return self::hasSSL(m_global);
00410 }
00411 inline HttpProxyPort* HttpProxyPort::findHttp(uint16_t family) {
00412   return self::findHttp(m_global, family);
00413 }
00414 
00415 /** Session Protocol initialization.
00416     This must be called before any proxy port parsing is done.
00417 */
00418 extern void ts_session_protocol_well_known_name_indices_init();
00419 
00420 #endif // I_REC_HTTP_H

Generated by  doxygen 1.7.1