1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 5 6<html xmlns="http://www.w3.org/1999/xhtml"> 7 <head> 8 <meta name="generator" content="HTML Tidy, see www.w3.org" /> 9 10 <title>Apache Content Negotiation</title> 11 </head> 12 <!-- Background white, links blue (unvisited), navy (visited), red (active) --> 13 14 <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" 15 vlink="#000080" alink="#FF0000"> 16 <div align="CENTER"> 17 <img src="images/sub.gif" alt="[APACHE DOCUMENTATION]" /> 18 19 <h3>Apache HTTP Server</h3> 20 </div> 21 22 23 24 <h1 align="CENTER">Content Negotiation</h1> 25 26 <p>Apache's support for content negotiation has been updated to 27 meet the HTTP/1.1 specification. It can choose the best 28 representation of a resource based on the browser-supplied 29 preferences for media type, languages, character set and 30 encoding. It is also implements a couple of features to give 31 more intelligent handling of requests from browsers which send 32 incomplete negotiation information.</p> 33 34 <p>Content negotiation is provided by the <a 35 href="mod/mod_negotiation.html">mod_negotiation</a> module, 36 which is compiled in by default.</p> 37 <hr /> 38 39 <h2>About Content Negotiation</h2> 40 41 <p>A resource may be available in several different 42 representations. For example, it might be available in 43 different languages or different media types, or a combination. 44 One way of selecting the most appropriate choice is to give the 45 user an index page, and let them select. However it is often 46 possible for the server to choose automatically. This works 47 because browsers can send as part of each request information 48 about what representations they prefer. For example, a browser 49 could indicate that it would like to see information in French, 50 if possible, else English will do. Browsers indicate their 51 preferences by headers in the request. To request only French 52 representations, the browser would send</p> 53<pre> 54 Accept-Language: fr 55</pre> 56 57 <p>Note that this preference will only be applied when there is 58 a choice of representations and they vary by language.</p> 59 60 <p>As an example of a more complex request, this browser has 61 been configured to accept French and English, but prefer 62 French, and to accept various media types, preferring HTML over 63 plain text or other text types, and preferring GIF or JPEG over 64 other media types, but also allowing any other media type as a 65 last resort:</p> 66<pre> 67 Accept-Language: fr; q=1.0, en; q=0.5 68 Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, 69 image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1 70</pre> 71 Apache 1.2 supports 'server driven' content negotiation, as 72 defined in the HTTP/1.1 specification. It fully supports the 73 Accept, Accept-Language, Accept-Charset and Accept-Encoding 74 request headers. Apache 1.3.4 also supports 'transparent' 75 content negotiation, which is an experimental negotiation 76 protocol defined in RFC 2295 and RFC 2296. It does not offer 77 support for 'feature negotiation' as defined in these RFCs. 78 79 <p>A <strong>resource</strong> is a conceptual entity 80 identified by a URI (RFC 2396). An HTTP server like Apache 81 provides access to <strong>representations</strong> of the 82 resource(s) within its namespace, with each representation in 83 the form of a sequence of bytes with a defined media type, 84 character set, encoding, etc. Each resource may be associated 85 with zero, one, or more than one representation at any given 86 time. If multiple representations are available, the resource 87 is referred to as <strong>negotiable</strong> and each of its 88 representations is termed a <strong>variant</strong>. The ways 89 in which the variants for a negotiable resource vary are called 90 the <strong>dimensions</strong> of negotiation.</p> 91 92 <h2>Negotiation in Apache</h2> 93 94 <p>In order to negotiate a resource, the server needs to be 95 given information about each of the variants. This is done in 96 one of two ways:</p> 97 98 <ul> 99 <li>Using a type map (<em>i.e.</em>, a <code>*.var</code> 100 file) which names the files containing the variants 101 explicitly, or</li> 102 103 <li>Using a 'MultiViews' search, where the server does an 104 implicit filename pattern match and chooses from among the 105 results.</li> 106 </ul> 107 108 <h3>Using a type-map file</h3> 109 110 <p>A type map is a document which is associated with the 111 handler named <code>type-map</code> (or, for 112 backwards-compatibility with older Apache configurations, the 113 mime type <code>application/x-type-map</code>). Note that to 114 use this feature, you must have a handler set in the 115 configuration that defines a file suffix as 116 <code>type-map</code>; this is best done with a</p> 117<pre> 118 AddHandler type-map .var 119</pre> 120 in the server configuration file. See the comments in the 121 sample config file for more details. 122 123 <p>Type map files have an entry for each available variant; 124 these entries consist of contiguous HTTP-format header lines. 125 Entries for different variants are separated by blank lines. 126 Blank lines are illegal within an entry. It is conventional to 127 begin a map file with an entry for the combined entity as a 128 whole (although this is not required, and if present will be 129 ignored). An example map file is shown below. In this example, the 130 file would be named <code>foo.var</code> and would be placed in the 131 same directory with the various variants of the resource 132 <code>foo</code>.</p> 133<pre> 134 URI: foo 135 136 URI: foo.en.html 137 Content-type: text/html 138 Content-language: en 139 140 URI: foo.fr.de.html 141 Content-type: text/html;charset=iso-8859-2 142 Content-language: fr, de 143</pre> 144 If the variants have different source qualities, that may be 145 indicated by the "qs" parameter to the media type, as in this 146 picture (available as jpeg, gif, or ASCII-art): 147<pre> 148 URI: foo 149 150 URI: foo.jpeg 151 Content-type: image/jpeg; qs=0.8 152 153 URI: foo.gif 154 Content-type: image/gif; qs=0.5 155 156 URI: foo.txt 157 Content-type: text/plain; qs=0.01 158</pre> 159 160 <p>qs values can vary in the range 0.000 to 1.000. Note that 161 any variant with a qs value of 0.000 will never be chosen. 162 Variants with no 'qs' parameter value are given a qs factor of 163 1.0. The qs parameter indicates the relative 'quality' of this 164 variant compared to the other available variants, independent 165 of the client's capabilities. For example, a jpeg file is 166 usually of higher source quality than an ascii file if it is 167 attempting to represent a photograph. However, if the resource 168 being represented is an original ascii art, then an ascii 169 representation would have a higher source quality than a jpeg 170 representation. A qs value is therefore specific to a given 171 variant depending on the nature of the resource it 172 represents.</p> 173 174 <p>The full list of headers recognized is:</p> 175 176 <dl> 177 <dt><code>URI:</code></dt> 178 179 <dd>uri of the file containing the variant (of the given 180 media type, encoded with the given content encoding). These 181 are interpreted as URLs relative to the map file; they must 182 be on the same server (!), and they must refer to files to 183 which the client would be granted access if they were to be 184 requested directly.</dd> 185 186 <dt><code>Content-Type:</code></dt> 187 188 <dd>media type --- charset, level and "qs" parameters may be 189 given. These are often referred to as MIME types; typical 190 media types are <code>image/gif</code>, 191 <code>text/plain</code>, or 192 <code>text/html; level=3</code>.</dd> 193 194 <dt><code>Content-Language:</code></dt> 195 196 <dd>The languages of the variant, specified as an Internet 197 standard language tag from RFC 1766 (<em>e.g.</em>, 198 <code>en</code> for English, <code>kr</code> for Korean, 199 <em>etc.</em>).</dd> 200 201 <dt><code>Content-Encoding:</code></dt> 202 203 <dd>If the file is compressed, or otherwise encoded, rather 204 than containing the actual raw data, this says how that was 205 done. Apache only recognizes encodings that are defined by an 206 <a href="mod/mod_mime.html#addencoding">AddEncoding</a> 207 directive. This normally includes the encodings 208 <code>x-compress</code> for compress'd files, and 209 <code>x-gzip</code> for gzip'd files. The <code>x-</code> 210 prefix is ignored for encoding comparisons.</dd> 211 212 <dt><code>Content-Length:</code></dt> 213 214 <dd>The size of the file. Specifying content lengths in the 215 type-map allows the server to compare file sizes without 216 checking the actual files.</dd> 217 218 <dt><code>Description:</code></dt> 219 220 <dd>A human-readable textual description of the variant. If 221 Apache cannot find any appropriate variant to return, it will 222 return an error response which lists all available variants 223 instead. Such a variant list will include the human-readable 224 variant descriptions.</dd> 225 </dl> 226 227 <h3>Multiviews</h3> 228 229 <p><code>MultiViews</code> is a per-directory option, meaning 230 it can be set with an <code>Options</code> directive within a 231 <code><Directory></code>, <code><Location></code> 232 or <code><Files></code> section in 233 <code>access.conf</code>, or (if <code>AllowOverride</code> is 234 properly set) in <code>.htaccess</code> files. Note that 235 <code>Options All</code> does not set <code>MultiViews</code>; 236 you have to ask for it by name.</p> 237 238 <p>The effect of <code>MultiViews</code> is as follows: if the 239 server receives a request for <code>/some/dir/foo</code>, if 240 <code>/some/dir</code> has <code>MultiViews</code> enabled, and 241 <code>/some/dir/foo</code> does <em>not</em> exist, then the 242 server reads the directory looking for files named foo.*, and 243 effectively fakes up a type map which names all those files, 244 assigning them the same media types and content-encodings it 245 would have if the client had asked for one of them by name. It 246 then chooses the best match to the client's requirements.</p> 247 248 <p><code>MultiViews</code> may also apply to searches for the 249 file named by the <code>DirectoryIndex</code> directive, if the 250 server is trying to index a directory. If the configuration 251 files specify</p> 252<pre> 253 DirectoryIndex index 254</pre> 255 then the server will arbitrate between <code>index.html</code> 256 and <code>index.html3</code> if both are present. If neither 257 are present, and <code>index.cgi</code> is there, the server 258 will run it. 259 260 <p>If one of the files found when reading the directive is a 261 CGI script, it's not obvious what should happen. The code gives 262 that case special treatment --- if the request was a POST, or a 263 GET with QUERY_ARGS or PATH_INFO, the script is given an 264 extremely high quality rating, and generally invoked; otherwise 265 it is given an extremely low quality rating, which generally 266 causes one of the other views (if any) to be retrieved.</p> 267 268 <h2>The Negotiation Methods</h2> 269 After Apache has obtained a list of the variants for a given 270 resource, either from a type-map file or from the filenames in 271 the directory, it invokes one of two methods to decide on the 272 'best' variant to return, if any. It is not necessary to know 273 any of the details of how negotiation actually takes place in 274 order to use Apache's content negotiation features. However the 275 rest of this document explains the methods used for those 276 interested. 277 278 <p>There are two negotiation methods:</p> 279 280 <ol> 281 <li><strong>Server driven negotiation with the Apache 282 algorithm</strong> is used in the normal case. The Apache 283 algorithm is explained in more detail below. When this 284 algorithm is used, Apache can sometimes 'fiddle' the quality 285 factor of a particular dimension to achieve a better result. 286 The ways Apache can fiddle quality factors is explained in 287 more detail below.</li> 288 289 <li><strong>Transparent content negotiation</strong> is used 290 when the browser specifically requests this through the 291 mechanism defined in RFC 2295. This negotiation method gives 292 the browser full control over deciding on the 'best' variant, 293 the result is therefore dependent on the specific algorithms 294 used by the browser. As part of the transparent negotiation 295 process, the browser can ask Apache to run the 'remote 296 variant selection algorithm' defined in RFC 2296.</li> 297 </ol> 298 299 <h3>Dimensions of Negotiation</h3> 300 301 <table> 302 <tr valign="top"> 303 <th>Dimension</th> 304 305 <th>Notes</th> 306 </tr> 307 308 <tr valign="top"> 309 <td>Media Type</td> 310 311 <td>Browser indicates preferences with the Accept header 312 field. Each item can have an associated quality factor. 313 Variant description can also have a quality factor (the 314 "qs" parameter).</td> 315 </tr> 316 317 <tr valign="top"> 318 <td>Language</td> 319 320 <td>Browser indicates preferences with the Accept-Language 321 header field. Each item can have a quality factor. Variants 322 can be associated with none, one or more than one 323 language.</td> 324 </tr> 325 326 <tr valign="top"> 327 <td>Encoding</td> 328 329 <td>Browser indicates preference with the Accept-Encoding 330 header field. Each item can have a quality factor.</td> 331 </tr> 332 333 <tr valign="top"> 334 <td>Charset</td> 335 336 <td>Browser indicates preference with the Accept-Charset 337 header field. Each item can have a quality factor. Variants 338 can indicate a charset as a parameter of the media 339 type.</td> 340 </tr> 341 </table> 342 343 <h3>Apache Negotiation Algorithm</h3> 344 345 <p>Apache can use the following algorithm to select the 'best' 346 variant (if any) to return to the browser. This algorithm is 347 not further configurable. It operates as follows:</p> 348 349 <ol> 350 <li>First, for each dimension of the negotiation, check the 351 appropriate <em>Accept*</em> header field and assign a 352 quality to each variant. If the <em>Accept*</em> header for 353 any dimension implies that this variant is not acceptable, 354 eliminate it. If no variants remain, go to step 4.</li> 355 356 <li> 357 Select the 'best' variant by a process of elimination. Each 358 of the following tests is applied in order. Any variants 359 not selected at each test are eliminated. After each test, 360 if only one variant remains, select it as the best match 361 and proceed to step 3. If more than one variant remains, 362 move on to the next test. 363 364 <ol> 365 <li>Multiply the quality factor from the Accept header 366 with the quality-of-source factor for this variant's 367 media type, and select the variants with the highest 368 value.</li> 369 370 <li>Select the variants with the highest language quality 371 factor.</li> 372 373 <li>Select the variants with the best language match, 374 using either the order of languages in the 375 Accept-Language header (if present), or else the order of 376 languages in the <code>LanguagePriority</code> directive 377 (if present).</li> 378 379 <li>Select the variants with the highest 'level' media 380 parameter (used to give the version of text/html media 381 types).</li> 382 383 <li>Select variants with the best charset media 384 parameters, as given on the Accept-Charset header line. 385 Charset ISO-8859-1 is acceptable unless explicitly 386 excluded. Variants with a <code>text/*</code> media type 387 but not explicitly associated with a particular charset 388 are assumed to be in ISO-8859-1.</li> 389 390 <li>Select those variants which have associated charset 391 media parameters that are <em>not</em> ISO-8859-1. If 392 there are no such variants, select all variants 393 instead.</li> 394 395 <li>Select the variants with the best encoding. If there 396 are variants with an encoding that is acceptable to the 397 user-agent, select only these variants. Otherwise if 398 there is a mix of encoded and non-encoded variants, 399 select only the unencoded variants. If either all 400 variants are encoded or all variants are not encoded, 401 select all variants.</li> 402 403 <li>Select the variants with the smallest content 404 length.</li> 405 406 <li>Select the first variant of those remaining. This 407 will be either the first listed in the type-map file, or 408 when variants are read from the directory, the one whose 409 file name comes first when sorted using ASCII code 410 order.</li> 411 </ol> 412 </li> 413 414 <li>The algorithm has now selected one 'best' variant, so 415 return it as the response. The HTTP response header Vary is 416 set to indicate the dimensions of negotiation (browsers and 417 caches can use this information when caching the resource). 418 End.</li> 419 420 <li><p>To get here means no variant was selected (because none 421 are acceptable to the browser). Return a 406 status (meaning 422 "No acceptable representation") with a response body 423 consisting of an HTML document listing the available 424 variants. Also set the HTTP Vary header to indicate the 425 dimensions of variance.</p> 426 427 <p>You should be aware that the error message returned by Apache is 428 necessarily rather terse and might confuse some users (even though it 429 lists the available alternatives). If you want to avoid users seeing this 430 error page, you should organize your documents such that a document in a 431 default language (or with a default encoding etc.) is always returned if a 432 document is not available in any of the languages, encodings etc. the 433 browser asked for.</p> 434 435 <p>In particular, if you want a document in a default language to 436 be returned if a document is not available in any of the languages 437 a browser asked for, you should create a document with no language 438 attribute set. See <a href="#nolanguage">Variants with no 439 Language</a> below for details.</p></li> 440 </ol> 441 442 <h2><a id="better" name="better">Fiddling with Quality 443 Values</a></h2> 444 445 <p>Apache sometimes changes the quality values from what would 446 be expected by a strict interpretation of the Apache 447 negotiation algorithm above. This is to get a better result 448 from the algorithm for browsers which do not send full or 449 accurate information. Some of the most popular browsers send 450 Accept header information which would otherwise result in the 451 selection of the wrong variant in many cases. If a browser 452 sends full and correct information these fiddles will not be 453 applied.</p> 454 455 <h3>Media Types and Wildcards</h3> 456 457 <p>The Accept: request header indicates preferences for media 458 types. It can also include 'wildcard' media types, such as 459 "image/*" or "*/*" where the * matches any string. So a request 460 including:</p> 461<pre> 462 Accept: image/*, */* 463</pre> 464 would indicate that any type starting "image/" is acceptable, 465 as is any other type (so the first "image/*" is redundant). 466 Some browsers routinely send wildcards in addition to explicit 467 types they can handle. For example: 468<pre> 469 Accept: text/html, text/plain, image/gif, image/jpeg, */* 470</pre> 471 The intention of this is to indicate that the explicitly listed 472 types are preferred, but if a different representation is 473 available, that is ok too. However under the basic algorithm, 474 as given above, the */* wildcard has exactly equal preference 475 to all the other types, so they are not being preferred. The 476 browser should really have sent a request with a lower quality 477 (preference) value for *.*, such as: 478<pre> 479 Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01 480</pre> 481 The explicit types have no quality factor, so they default to a 482 preference of 1.0 (the highest). The wildcard */* is given a 483 low preference of 0.01, so other types will only be returned if 484 no variant matches an explicitly listed type. 485 486 <p>If the Accept: header contains <em>no</em> q factors at all, 487 Apache sets the q value of "*/*", if present, to 0.01 to 488 emulate the desired behaviour. It also sets the q value of 489 wildcards of the format "type/*" to 0.02 (so these are 490 preferred over matches against "*/*". If any media type on the 491 Accept: header contains a q factor, these special values are 492 <em>not</em> applied, so requests from browsers which send the 493 correct information to start with work as expected.</p> 494 495 <h3><a id="nolanguage" name="nolanguage">Variants with no Language</a></h3> 496 497 <p>If some of the variants for a particular resource have a 498 language attribute, and some do not, those variants with no 499 language are given a very low language quality factor of 500 0.001.</p> 501 502 <p>The reason for setting this language quality factor for variant 503 with no language to a very low value is to allow for a default 504 variant which can be supplied if none of the other variants match 505 the browser's language preferences. This allows you to avoid users 506 seeing a "406" error page if their browser is set to only accept 507 languages which you do not offer for the resource that was 508 requested.</p> 509 510 <p>For example, consider the situation with Multiviews enabled and 511 three variants:</p> 512 513 <ul> 514 <li>foo.en.html, language en</li> 515 516 <li>foo.fr.html, language fr</li> 517 518 <li>foo.html, no language</li> 519 </ul> 520 521 <p>The meaning of a variant with no language is that it is always 522 acceptable to the browser. If the request is for <code>foo</code> 523 and the Accept-Language header includes either en or fr (or both) 524 one of foo.en.html or foo.fr.html will be returned. If the browser 525 does not list either en or fr as acceptable, foo.html will be 526 returned instead. If the client requests <code>foo.html</code> 527 instead, then no negotiation will occur since the exact match 528 will be returned. To avoid this problem, it is sometimes helpful 529 to name the "no language" variant <code>foo.html.html</code> to assure 530 that Multiviews and language negotiation will come into play.</p> 531 532 <h2>Extensions to Transparent Content Negotiation</h2> 533 Apache extends the transparent content negotiation protocol 534 (RFC 2295) as follows. A new <code>{encoding ..}</code> element 535 is used in variant lists to label variants which are available 536 with a specific content-encoding only. The implementation of 537 the RVSA/1.0 algorithm (RFC 2296) is extended to recognize 538 encoded variants in the list, and to use them as candidate 539 variants whenever their encodings are acceptable according to 540 the Accept-Encoding request header. The RVSA/1.0 implementation 541 does not round computed quality factors to 5 decimal places 542 before choosing the best variant. 543 544 <h2>Note on hyperlinks and naming conventions</h2> 545 546 <p>If you are using language negotiation you can choose between 547 different naming conventions, because files can have more than 548 one extension, and the order of the extensions is normally 549 irrelevant (see <a href="mod/mod_mime.html">mod_mime</a> 550 documentation for details).</p> 551 552 <p>A typical file has a MIME-type extension (<em>e.g.</em>, 553 <samp>html</samp>), maybe an encoding extension (<em>e.g.</em>, 554 <samp>gz</samp>), and of course a language extension 555 (<em>e.g.</em>, <samp>en</samp>) when we have different 556 language variants of this file.</p> 557 558 <p>Examples:</p> 559 560 <ul> 561 <li>foo.en.html</li> 562 563 <li>foo.html.en</li> 564 565 <li>foo.en.html.gz</li> 566 </ul> 567 568 <p>Here some more examples of filenames together with valid and 569 invalid hyperlinks:</p> 570 571 <table border="1" cellpadding="8" cellspacing="0"> 572 <tr> 573 <th>Filename</th> 574 575 <th>Valid hyperlink</th> 576 577 <th>Invalid hyperlink</th> 578 </tr> 579 580 <tr> 581 <td><em>foo.html.en</em></td> 582 583 <td>foo<br /> 584 foo.html</td> 585 586 <td>-</td> 587 </tr> 588 589 <tr> 590 <td><em>foo.en.html</em></td> 591 592 <td>foo</td> 593 594 <td>foo.html</td> 595 </tr> 596 597 <tr> 598 <td><em>foo.html.en.gz</em></td> 599 600 <td>foo<br /> 601 foo.html</td> 602 603 <td>foo.gz<br /> 604 foo.html.gz</td> 605 </tr> 606 607 <tr> 608 <td><em>foo.en.html.gz</em></td> 609 610 <td>foo</td> 611 612 <td>foo.html<br /> 613 foo.html.gz<br /> 614 foo.gz</td> 615 </tr> 616 617 <tr> 618 <td><em>foo.gz.html.en</em></td> 619 620 <td>foo<br /> 621 foo.gz<br /> 622 foo.gz.html</td> 623 624 <td>foo.html</td> 625 </tr> 626 627 <tr> 628 <td><em>foo.html.gz.en</em></td> 629 630 <td>foo<br /> 631 foo.html<br /> 632 foo.html.gz</td> 633 634 <td>foo.gz</td> 635 </tr> 636 </table> 637 638 <p>Looking at the table above you will notice that it is always 639 possible to use the name without any extensions in a hyperlink 640 (<em>e.g.</em>, <samp>foo</samp>). The advantage is that you 641 can hide the actual type of a document rsp. file and can change 642 it later, <em>e.g.</em>, from <samp>html</samp> to 643 <samp>shtml</samp> or <samp>cgi</samp> without changing any 644 hyperlink references.</p> 645 646 <p>If you want to continue to use a MIME-type in your 647 hyperlinks (<em>e.g.</em> <samp>foo.html</samp>) the language 648 extension (including an encoding extension if there is one) 649 must be on the right hand side of the MIME-type extension 650 (<em>e.g.</em>, <samp>foo.html.en</samp>).</p> 651 652 <h2>Note on Caching</h2> 653 654 <p>When a cache stores a representation, it associates it with 655 the request URL. The next time that URL is requested, the cache 656 can use the stored representation. But, if the resource is 657 negotiable at the server, this might result in only the first 658 requested variant being cached and subsequent cache hits might 659 return the wrong response. To prevent this, Apache normally 660 marks all responses that are returned after content negotiation 661 as non-cacheable by HTTP/1.0 clients. Apache also supports the 662 HTTP/1.1 protocol features to allow caching of negotiated 663 responses.</p> 664 665 <p>For requests which come from a HTTP/1.0 compliant client 666 (either a browser or a cache), the directive 667 <tt>CacheNegotiatedDocs</tt> can be used to allow caching of 668 responses which were subject to negotiation. This directive can 669 be given in the server config or virtual host, and takes no 670 arguments. It has no effect on requests from HTTP/1.1 clients. 671 <hr /> 672 673 <h3 align="CENTER">Apache HTTP Server</h3> 674 <a href="./"><img src="images/index.gif" alt="Index" /></a> 675 676 </p> 677 </body> 678</html> 679 680 681