2010-03-08 04:55:21 -06:00
/* MIME Message Parse HTMIME.c
* * = = = = = = = = = = = = = = = = = =
* *
* * This is RFC 1341 - specific code .
* * The input stream pushed into this parser is assumed to be
* * stripped on CRs , ie lines end with LF , not CR LF .
* * ( It is easy to change this except for the body part where
* * conversion can be slow . )
* *
* * History :
* * Feb 92 Written Tim Berners - Lee , CERN
* *
*/
# include "../config.h"
# include "HTMIME.h" /* Implemented here */
# include "HTAlert.h"
# include "HTFile.h"
# include "tcp.h"
# include "../libnut/str-tools.h"
# if defined(KRB4) || defined(KRB5) /* ADC, 6/28/95 */
# define HAVE_KERBEROS
# endif
/*SWP*/
# include "HTAAUtil.h"
extern int securityType ;
# ifndef DISABLE_TRACE
extern int www2Trace ;
# endif
/* This is UGLY. */
char * redirecting_url = NULL ;
/* This is almost as ugly. */
extern int loading_length ;
extern int noLength ;
/* As is this - AF */
char * HTTP_last_modified ;
char * HTTP_expires ;
/* MIME Object
* * - - - - - - - - - - -
*/
2013-03-09 18:59:42 -06:00
typedef enum _MIME_state
2010-03-08 04:55:21 -06:00
{
BEGINNING_OF_LINE ,
CONTENT_ ,
CONTENT_T ,
CONTENT_TRANSFER_ENCODING ,
CONTENT_TYPE ,
CONTENT_ENCODING ,
CONTENT_LENGTH ,
EXPIRES ,
E ,
EX ,
L ,
LOCATION ,
LAST_MODIFIED ,
EXTENSION ,
SKIP_GET_VALUE , /* Skip space then get value */
GET_VALUE , /* Get value till white space */
JUNK_LINE , /* Ignore the rest of this folded line */
NEWLINE , /* Just found a LF .. maybe continuation */
CHECK , /* check against check_pointer */
MIME_TRANSPARENT , /* put straight through to target ASAP! */
MIME_IGNORE , /* ignore entire file */
/* TRANSPARENT and IGNORE are defined as stg else in _WINDOWS */
# ifdef HAVE_KERBEROS
WWW_AUTHENTICATE , /* for kerberos mutual authentication */
# endif
} MIME_state ;
# define VALUE_SIZE 8192 /* @@@@@@@ Arbitrary? */
2013-03-09 18:59:42 -06:00
struct _HTStream
2010-03-08 04:55:21 -06:00
{
WWW_CONST HTStreamClass * isa ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
MIME_state state ; /* current state */
MIME_state if_ok ; /* got this state if match */
MIME_state field ; /* remember which field */
MIME_state fold_state ; /* state on a fold */
WWW_CONST char * check_pointer ; /* checking input */
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
char * value_pointer ; /* storing values */
char value [ VALUE_SIZE ] ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
HTParentAnchor * anchor ; /* Given on creation */
HTStream * sink ; /* Given on creation */
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
char * boundary ; /* For multipart */
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
HTFormat encoding ; /* Content-Transfer-Encoding */
char * compression_encoding ;
int content_length ;
int header_length ; /* for io accounting -bjs */
HTFormat format ; /* Content-Type */
HTStream * target ; /* While writing out */
HTStreamClass targetClass ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
HTAtom * targetRep ; /* Converting into? */
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
char * location ;
char * expires ;
char * last_modified ;
int interrupted ;
} ;
/*_________________________________________________________________________
* *
* * A C T I O N R O U T I N E S
*/
/* Character handling
* * - - - - - - - - - - - - - - - - - -
* *
* * This is a FSM parser which is tolerant as it can be of all
* * syntax errors . It ignores field names it does not understand ,
* * and resynchronises on line beginnings .
*/
PRIVATE void HTMIME_put_character ARGS2 ( HTStream * , me , char , c )
{
# ifdef HAVE_KERBEROS
static int got_kerb = 0 ;
static HTAAScheme kscheme ;
extern int validate_kerberos_server_auth ( ) ;
# endif
if ( me - > state = = MIME_TRANSPARENT ) {
( * me - > targetClass . put_character ) ( me - > target , c ) ; /* MUST BE FAST */
return ;
} else {
me - > header_length + + ; /* bjs - update this first */
}
2013-03-09 18:59:42 -06:00
switch ( me - > state )
2010-03-08 04:55:21 -06:00
{
case MIME_IGNORE :
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [HTMIME_put_character] Got MIME_IGNORE; returning... \n " ) ;
# endif
return ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
/* case MIME_TRANSPARENT:*/
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
case NEWLINE :
2013-03-09 18:59:42 -06:00
if ( c ! = ' \n ' & & WHITE ( c ) )
2010-03-08 04:55:21 -06:00
{
/* Folded line */
me - > state = me - > fold_state ; /* pop state before newline */
break ;
}
/* else Falls through */
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
case BEGINNING_OF_LINE :
2013-03-09 18:59:42 -06:00
switch ( c )
2010-03-08 04:55:21 -06:00
{
case ' c ' :
case ' C ' :
me - > check_pointer = " ontent- " ;
me - > if_ok = CONTENT_ ;
me - > state = CHECK ;
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 18:59:42 -06:00
fprintf ( stderr ,
2010-03-08 04:55:21 -06:00
" [MIME] Got C at beginning of line; checking for 'ontent-' \n " ) ;
# endif
break ;
/* SWP -- 7/10/95 */
case ' E ' : /* Extension or Expires */
case ' e ' :
{
me - > state = E ;
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 18:59:42 -06:00
fprintf ( stderr ,
2010-03-08 04:55:21 -06:00
" [MIME] Got E at beginning of line; checking for 'X' \n " ) ;
# endif
}
break ;
case ' l ' :
case ' L ' :
me - > state = L ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] Got L at beginning of line \n " ) ;
# endif
break ;
# ifdef HAVE_KERBEROS
/* for kerberos mutual authentication */
case ' w ' :
case ' W ' :
me - > check_pointer = " ww-authenticate: " ;
me - > if_ok = WWW_AUTHENTICATE ;
me - > state = CHECK ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] Got W at beginning of line; checking for 'ww-authenticate' \n " ) ;
# endif
break ;
# endif
case ' \n ' : /* Blank line: End of Header! */
{
int compressed = COMPRESSED_NOT ;
# ifndef DISABLE_TRACE
2013-03-09 18:59:42 -06:00
if ( www2Trace )
2010-03-08 04:55:21 -06:00
fprintf ( stderr ,
" HTMIME: DOING STREAMSTACK: MIME content type is %s, converting to %s \n " ,
HTAtom_name ( me - > format ) , HTAtom_name ( me - > targetRep ) ) ;
# endif
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" Compression encoding '%s' \n " ,
( ! me - > compression_encoding | | ! * me - > compression_encoding ? " Undefined " : me - > compression_encoding ) ) ;
# endif
if ( me - > compression_encoding )
{
if ( strcmp ( me - > compression_encoding , " x-compress " ) = = 0 )
{
compressed = COMPRESSED_BIGZ ;
}
else if ( strcmp ( me - > compression_encoding , " x-gzip " ) = = 0 )
{
compressed = COMPRESSED_GNUZIP ;
}
else
{
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " HTMIME: Unknown compression_encoding '%s' \n " ,
me - > compression_encoding ) ;
# endif
}
}
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " HTMIME: compressed == %d \n " , compressed ) ;
# endif
me - > target = HTStreamStack ( me - > format , me - > targetRep , compressed ,
me - > sink , me - > anchor ) ;
2013-03-09 18:59:42 -06:00
if ( ! me - > target )
2010-03-08 04:55:21 -06:00
{
# ifndef DISABLE_TRACE
2013-03-09 18:59:42 -06:00
if ( www2Trace )
2010-03-08 04:55:21 -06:00
{
fprintf ( stderr , " MIME: Can't translate! ** \n " ) ;
fprintf ( stderr , " HTMIME: Defaulting to HTML. \n " ) ;
}
# endif
/* Default to HTML. */
me - > target = HTStreamStack ( HTAtom_for ( " text/html " ) ,
me - > targetRep ,
compressed ,
me - > sink ,
me - > anchor ) ;
}
2013-03-09 18:59:42 -06:00
if ( me - > target )
2010-03-08 04:55:21 -06:00
{
me - > targetClass = * me - > target - > isa ;
/* Check for encoding and select state from there @@ */
/* From now push straigh through */
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [MIME] Entering MIME_TRANSPARENT \n " ) ;
# endif
2013-03-09 18:59:42 -06:00
me - > state = MIME_TRANSPARENT ;
2010-03-08 04:55:21 -06:00
/* bjs note: header is now completely read */
2013-03-09 18:59:42 -06:00
}
else
2010-03-08 04:55:21 -06:00
{
/* This is HIGHLY EVIL -- the browser WILL BREAK
if it ever reaches here . Thus the default to
HTML above , which should always happen . . . */
# ifndef DISABLE_TRACE
2013-03-09 18:59:42 -06:00
if ( www2Trace )
2010-03-08 04:55:21 -06:00
fprintf ( stderr , " MIME: HIT HIGHLY EVIL!!! *** \n " ) ;
# endif
me - > state = MIME_IGNORE ; /* What else to do? */
}
}
break ;
default :
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [MIME] Got nothing at beginning of line; bleah. \n " ) ;
# endif
goto bad_field_name ;
break ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
} /* switch on character */
break ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
case CHECK : /* Check against string */
2013-03-09 18:59:42 -06:00
if ( TOLOWER ( c ) = = * ( me - > check_pointer ) + + )
2010-03-08 04:55:21 -06:00
{
2013-03-09 18:59:42 -06:00
if ( ! * me - > check_pointer )
2010-03-08 04:55:21 -06:00
me - > state = me - > if_ok ;
2013-03-09 18:59:42 -06:00
}
else
2010-03-08 04:55:21 -06:00
{ /* Error */
# ifndef DISABLE_TRACE
2013-03-09 18:59:42 -06:00
if ( www2Trace )
2010-03-08 04:55:21 -06:00
fprintf ( stderr ,
" HTMIME: Bad character `%c' found where `%s' expected \n " ,
c , me - > check_pointer - 1 ) ;
# endif
goto bad_field_name ;
}
break ;
case CONTENT_ :
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 18:59:42 -06:00
fprintf ( stderr ,
2010-03-08 04:55:21 -06:00
" [MIME] in case CONTENT_ \n " ) ;
# endif
2013-03-09 18:59:42 -06:00
switch ( c )
2010-03-08 04:55:21 -06:00
{
case ' t ' :
case ' T ' :
me - > state = CONTENT_T ;
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 18:59:42 -06:00
fprintf ( stderr ,
2010-03-08 04:55:21 -06:00
" [MIME] Was CONTENT_, found T, state now CONTENT_T \n " ) ;
# endif
break ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
case ' e ' :
case ' E ' :
me - > check_pointer = " ncoding: " ;
me - > if_ok = CONTENT_ENCODING ;
me - > state = CHECK ;
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 18:59:42 -06:00
fprintf ( stderr ,
2010-03-08 04:55:21 -06:00
" [MIME] Was CONTENT_, found E, checking for 'ncoding:' \n " ) ;
# endif
break ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
case ' l ' :
case ' L ' :
me - > check_pointer = " ength: " ;
me - > if_ok = CONTENT_LENGTH ;
me - > state = CHECK ;
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 18:59:42 -06:00
fprintf ( stderr ,
2010-03-08 04:55:21 -06:00
" [MIME] Was CONTENT_, found L, checking for 'ength:' \n " ) ;
# endif
break ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
default :
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 18:59:42 -06:00
fprintf ( stderr ,
2010-03-08 04:55:21 -06:00
" [MIME] Was CONTENT_, found nothing; bleah \n " ) ;
# endif
goto bad_field_name ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
} /* switch on character */
break ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
case CONTENT_T :
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 18:59:42 -06:00
fprintf ( stderr ,
2010-03-08 04:55:21 -06:00
" [MIME] in case CONTENT_T \n " ) ;
# endif
2013-03-09 18:59:42 -06:00
switch ( c )
2010-03-08 04:55:21 -06:00
{
case ' r ' :
case ' R ' :
me - > check_pointer = " ansfer-encoding: " ;
me - > if_ok = CONTENT_TRANSFER_ENCODING ;
me - > state = CHECK ;
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 18:59:42 -06:00
fprintf ( stderr ,
2010-03-08 04:55:21 -06:00
" [MIME] Was CONTENT_T; going to check for ansfer-encoding: \n " ) ;
# endif
break ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
case ' y ' :
case ' Y ' :
me - > check_pointer = " pe: " ;
me - > if_ok = CONTENT_TYPE ;
me - > state = CHECK ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [MIME] Was CONTENT_T; going to check for pe: \n " ) ;
# endif
break ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
default :
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] Was CONTENT_T; found nothing; bleah \n " ) ;
# endif
goto bad_field_name ;
} /* switch on character */
break ;
case L :
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] in case L \n " ) ;
# endif
switch ( c )
{
case ' a ' :
case ' A ' :
me - > check_pointer = " st-modified: " ;
me - > if_ok = LAST_MODIFIED ;
me - > state = CHECK ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] Was L; going to check for st-modified: \n " ) ;
# endif
break ;
case ' o ' :
case ' O ' :
me - > check_pointer = " cation: " ;
me - > if_ok = LOCATION ;
me - > state = CHECK ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] Was L; going to check for ocation: \n " ) ;
# endif
break ;
default :
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] Was L; found nothing; bleah \n " ) ;
# endif
goto bad_field_name ;
} /* switch on character */
break ;
case E :
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] in case E \n " ) ;
# endif
switch ( c )
{
case ' x ' :
case ' X ' :
me - > state = EX ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] Was EX; going to check for EXP or EXT: \n " ) ;
# endif
break ;
default :
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] Was E; found nothing; bleah \n " ) ;
# endif
goto bad_field_name ;
} /* switch on character */
break ;
case EX :
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] in case EX \n " ) ;
# endif
switch ( c )
{
case ' p ' :
case ' P ' :
me - > check_pointer = " ires " ;
me - > if_ok = EXPIRES ;
me - > state = CHECK ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] Was EXP; going to check for 'ires' \n " ) ;
# endif
break ;
case ' t ' :
case ' T ' :
me - > check_pointer = " ension: " ;
me - > if_ok = EXTENSION ;
me - > state = CHECK ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] Was EXT; going to check for 'ension:' \n " ) ;
# endif
break ;
default :
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME] Was EX; found nothing; bleah \n " ) ;
# endif
goto bad_field_name ;
} /* switch on character */
break ;
# ifdef HAVE_KERBEROS
case WWW_AUTHENTICATE :
# endif
case EXTENSION :
case CONTENT_TYPE :
case CONTENT_TRANSFER_ENCODING :
case CONTENT_ENCODING :
case CONTENT_LENGTH :
case LOCATION :
case EXPIRES :
case LAST_MODIFIED :
me - > field = me - > state ; /* remember it */
me - > state = SKIP_GET_VALUE ;
/* Fall through! (no break!) */
case SKIP_GET_VALUE :
2013-03-09 18:59:42 -06:00
if ( c = = ' \n ' )
2010-03-08 04:55:21 -06:00
{
me - > fold_state = me - > state ;
me - > state = NEWLINE ;
break ;
}
2013-03-09 18:59:42 -06:00
if ( WHITE ( c ) )
2010-03-08 04:55:21 -06:00
break ; /* Skip white space */
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
me - > value_pointer = me - > value ;
2013-03-09 18:59:42 -06:00
me - > state = GET_VALUE ;
2010-03-08 04:55:21 -06:00
/* Fall through to store first character */
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
case GET_VALUE :
2013-03-09 18:59:42 -06:00
if ( WHITE ( c ) )
2010-03-08 04:55:21 -06:00
{
/* End of field */
* me - > value_pointer = 0 ;
2013-03-09 18:59:42 -06:00
switch ( me - > field )
2010-03-08 04:55:21 -06:00
{
case CONTENT_TYPE :
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [MIME_put_char] Got content-type value '%s' \n " , me - > value ) ;
# endif
/* Lowercase it. */
{
char * tmp ;
// SAM
if ( ( tmp = strchr ( me - > value , ' ; ' ) ) ) * tmp = ' \0 ' ;
// SAM
for ( tmp = me - > value ; * tmp ; tmp + + )
* tmp = TOLOWER ( * tmp ) ;
}
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [MIME_put_char] Lowercased to '%s' \n " , me - > value ) ;
# endif
me - > format = HTAtom_for ( me - > value ) ;
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 17:01:23 -06:00
fprintf ( stderr , " [MIME_put_char] Got content-type value atom %p \n " ,
2010-03-08 04:55:21 -06:00
me - > format ) ;
# endif
break ;
case CONTENT_TRANSFER_ENCODING :
me - > encoding = HTAtom_for ( me - > value ) ;
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 18:59:42 -06:00
fprintf ( stderr ,
2010-03-08 04:55:21 -06:00
" [MIME_put_char] Picked up transfer_encoding '%s' \n " ,
2013-03-09 17:01:23 -06:00
( char * ) me - > encoding ) ;
2010-03-08 04:55:21 -06:00
# endif
break ;
case CONTENT_ENCODING :
me - > compression_encoding = strdup ( me - > value ) ;
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 18:59:42 -06:00
fprintf ( stderr ,
" [MIME_put_char] Picked up compression encoding '%s' \n " ,
2010-03-08 04:55:21 -06:00
me - > compression_encoding ) ;
# endif
break ;
case CONTENT_LENGTH :
me - > content_length = atoi ( me - > value ) ;
/* This is TEMPORARY. */
loading_length = me - > content_length ;
noLength = 0 ;
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 18:59:42 -06:00
fprintf ( stderr ,
" [MIME_put_char] Picked up content length '%d' \n " ,
2010-03-08 04:55:21 -06:00
me - > content_length ) ;
# endif
break ;
case EXPIRES :
if ( me - > value_pointer < me - > value + VALUE_SIZE - 1 )
{
* me - > value_pointer + + = c ;
* me - > value_pointer = 0 ;
}
else
{
goto value_too_long ;
}
if ( me - > expires )
free ( me - > expires ) ;
me - > expires = strdup ( me - > value ) ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME_put_char] Picked up expires '%s' \n " , me - > value ) ;
# endif
break ;
case LAST_MODIFIED :
if ( me - > value_pointer < me - > value + VALUE_SIZE - 1 )
{
* me - > value_pointer + + = c ;
* me - > value_pointer = 0 ;
}
else
{
goto value_too_long ;
}
if ( me - > last_modified )
free ( me - > last_modified ) ;
me - > last_modified = strdup ( me - > value ) ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME_put_char] Picked up last modified '%s' \n " , me - > value ) ;
# endif
break ;
case LOCATION :
me - > location = me - > value ;
redirecting_url = strdup ( me - > location ) ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr ,
" [MIME_put_char] Picked up location '%s' \n " , me - > location ) ;
# endif
break ;
# ifdef HAVE_KERBEROS
case WWW_AUTHENTICATE :
/*
* msg from server looks like :
* WWW - Authenticate : KerberosV4 [ strified ktext ]
* also allowed : KerberosV5 , KerbV4 - Encrypted , KerbV5 - Encrypted
*
* This code is ugly : we have to keep this got_kerb static around because
* the FSM isn ' t really designed to have fields with values that
* include whitespace . got_kerb tells us that we ' ve been in this code
* before , and that we saw the word " kerberos "
*/
# ifndef DISABLE_TRACE
if ( www2Trace ) fprintf ( stderr , " [MIME put char] picked up Auth. arg '%s' \n " ,
me - > value ) ;
# endif
if ( got_kerb ) {
validate_kerberos_server_auth ( kscheme , me - > value ) ;
got_kerb = 0 ; /* reset kerb state */
me - > state = me - > field ;
} else if ( ! my_strncasecmp ( me - > value , " kerb " , 4 ) ) {
if ( 0 ) { /* just to get things started */
}
# ifdef KRB4
else if ( ! my_strncasecmp ( me - > value , " KerberosV4 " , 10 ) ) {
kscheme = HTAA_KERBEROS_V4 ;
got_kerb = 1 ;
me - > state = SKIP_GET_VALUE ;
}
# endif
# ifdef KRB5
else if ( ! my_strncasecmp ( me - > value , " KerberosV5 " , 10 ) ) {
kscheme = HTAA_KERBEROS_V5 ;
got_kerb = 1 ;
me - > state = SKIP_GET_VALUE ;
}
# endif
else {
fprintf ( stderr , " Unrecognized field in WWW-Authenticate header \n " ) ;
me - > state = me - > field ;
}
}
break ;
# endif
case EXTENSION :
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [MIME_put_char] Got Extension value '%s' \n " , me - > value ) ;
# endif
/* Lowercase it. */
{
char * tmp ;
for ( tmp = me - > value ; * tmp ; tmp + + )
* tmp = TOLOWER ( * tmp ) ;
}
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [MIME_put_char] Lowercased to '%s' \n " , me - > value ) ;
# endif
switch ( * ( me - > value ) ) {
case ' d ' : /*Domain*/
if ( ! strcmp ( me - > value , " domain-restricted " ) ) {
securityType = HTAA_DOMAIN ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [MIME_put_char] Domain restricted extension header found. \n " ) ;
# endif
break ;
}
/*fall through*/
default : /*Unknown*/
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [MIME_put_char] Unknown extension header: '%s' \n " , me - > value ) ;
# endif
me - > state = me - > field ;
break ;
}
break ;
default : /* Should never get here */
break ;
}
}
else
{
2013-03-09 18:59:42 -06:00
if ( me - > value_pointer < me - > value + VALUE_SIZE - 1 )
2010-03-08 04:55:21 -06:00
{
* me - > value_pointer + + = c ;
break ;
}
else
{
goto value_too_long ;
}
}
/* Fall through */
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
case JUNK_LINE :
2013-03-09 18:59:42 -06:00
if ( c = = ' \n ' )
2010-03-08 04:55:21 -06:00
{
me - > state = NEWLINE ;
me - > fold_state = me - > state ;
}
break ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
} /* switch on state*/
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
return ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
value_too_long :
# ifndef DISABLE_TRACE
if ( www2Trace ) fprintf ( stderr ,
" HTMIME: *** Syntax error. (string too long) \n " ) ;
# endif
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
bad_field_name : /* Ignore it */
me - > state = JUNK_LINE ;
return ;
}
/* String handling
* * - - - - - - - - - - - - - - -
* *
* * Strings must be smaller than this buffer size .
*/
PRIVATE void HTMIME_put_string ARGS2 ( HTStream * , me , WWW_CONST char * , s )
{
WWW_CONST char * p ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [HTMIME_put_string] Putting '%s' \n " , s ) ;
# endif
if ( me - > state = = MIME_TRANSPARENT ) /* Optimisation */
{
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [HTMIME_put_string] Doing transparent put_string \n " ) ;
# endif
( * me - > targetClass . put_string ) ( me - > target , s ) ;
}
else if ( me - > state ! = MIME_IGNORE )
{
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [HTMIME_put_string] Doing char-by-char put_character \n " ) ;
# endif
2013-03-09 18:59:42 -06:00
for ( p = s ; * p ; p + + )
2010-03-08 04:55:21 -06:00
HTMIME_put_character ( me , * p ) ;
}
else
{
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [HTMIME_put_string] DOING NOTHING! \n " ) ;
# endif
}
return ;
}
/* Buffer write. Buffers can (and should!) be big.
* * - - - - - - - - - - - -
*/
PRIVATE void HTMIME_write ARGS3 ( HTStream * , me , WWW_CONST char * , s , int , l )
{
WWW_CONST char * p ;
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [HTMIME_write] Putting %d bytes \n " , l ) ;
# endif
if ( me - > state = = MIME_TRANSPARENT ) /* Optimisation */
{
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [HTMIME_write] Doing transparent put_block \n " ) ;
# endif
( * me - > targetClass . put_block ) ( me - > target , s , l ) ;
}
else if ( me - > state ! = MIME_IGNORE )
{
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [HTMIME_write] Doing char-by-char put_character \n " ) ;
# endif
2013-03-09 18:59:42 -06:00
for ( p = s ; p < s + l ; p + + )
2010-03-08 04:55:21 -06:00
HTMIME_put_character ( me , * p ) ;
}
else
{
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [HTMIME_write] DOING NOTHING! \n " ) ;
# endif
}
return ;
}
/* Free an HTML object
* * - - - - - - - - - - - - - - - - - - -
* *
*/
PRIVATE void HTMIME_free ARGS1 ( HTStream * , me )
{
if ( ! me - > target )
{
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [HTMIME_free] Caught case where we didn't get a target. \n " ) ;
# endif
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 17:01:23 -06:00
fprintf ( stderr , " me %p, me->target %p \n " , me , me - > target ) ;
2010-03-08 04:55:21 -06:00
# endif
me - > format = HTAtom_for ( " text/html " ) ;
me - > target = HTStreamStack ( me - > format , me - > targetRep , 0 ,
me - > sink , me - > anchor ) ;
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 17:01:23 -06:00
fprintf ( stderr , " me->target->isa %p \n " , me - > target - > isa ) ;
2010-03-08 04:55:21 -06:00
# endif
# ifndef DISABLE_TRACE
if ( www2Trace )
2013-03-09 17:01:23 -06:00
fprintf ( stderr , " me->target->isa->name %s \n " , me - > target - > isa - > name ) ;
2010-03-08 04:55:21 -06:00
# endif
me - > targetClass = * me - > target - > isa ;
( * me - > targetClass . put_string ) ( me - > target , " <H1>ERROR IN HTTP/1.0 RESPONSE</H1> The remote server returned a HTTP/1.0 response that Mosaic's MIME parser could not understand. Please contact the server maintainer.<P> Sorry for the inconvenience,<P> <ADDRESS>The Management</ADDRESS> " ) ;
securityType = HTAA_UNKNOWN ;
2013-03-09 18:59:42 -06:00
}
if ( me - > target )
2010-03-08 04:55:21 -06:00
( * me - > targetClass . free ) ( me - > target ) ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
if ( me - > expires )
{
char * p ;
if ( HTTP_expires )
free ( HTTP_expires ) ;
HTTP_expires = me - > expires ;
for ( p = HTTP_expires + strlen ( HTTP_expires ) - 1 ;
p > HTTP_expires & & isspace ( * p ) ; p - - )
{
* p = ' \0 ' ;
}
}
if ( me - > last_modified )
{
char * p ;
if ( HTTP_last_modified )
free ( HTTP_last_modified ) ;
HTTP_last_modified = me - > last_modified ;
for ( p = HTTP_last_modified + strlen ( HTTP_last_modified ) - 1 ;
p > HTTP_last_modified & & isspace ( * p ) ; p - - )
{
* p = ' \0 ' ;
}
}
free ( me ) ;
return ;
}
/* End writing
*/
PRIVATE void HTMIME_end_document ARGS1 ( HTStream * , me )
{
2013-03-09 18:59:42 -06:00
if ( me - > target )
2010-03-08 04:55:21 -06:00
( * me - > targetClass . end_document ) ( me - > target ) ;
}
PRIVATE void HTMIME_handle_interrupt ARGS1 ( HTStream * , me )
{
me - > interrupted = 1 ;
/* Propagate interrupt message down. */
if ( me - > target )
( * me - > targetClass . handle_interrupt ) ( me - > target ) ;
return ;
}
/* Structured Object Class
* * - - - - - - - - - - - - - - - - - - - - - - -
*/
PUBLIC WWW_CONST HTStreamClass HTMIME =
2013-03-09 18:59:42 -06:00
{
2010-03-08 04:55:21 -06:00
" MIMEParser " ,
HTMIME_free ,
HTMIME_end_document ,
HTMIME_put_character , HTMIME_put_string ,
HTMIME_write ,
HTMIME_handle_interrupt
2013-03-09 18:59:42 -06:00
} ;
2010-03-08 04:55:21 -06:00
/* Subclass-specific Methods
* * - - - - - - - - - - - - - - - - - - - - - - - - -
*/
PUBLIC HTStream * HTMIMEConvert ARGS5 (
HTPresentation * , pres ,
HTParentAnchor * , anchor ,
HTStream * , sink ,
HTFormat , format_in ,
int , compressed )
{
HTStream * me ;
2013-03-09 18:59:42 -06:00
2010-03-08 04:55:21 -06:00
me = malloc ( sizeof ( * me ) ) ;
2013-03-09 18:59:42 -06:00
me - > isa = & HTMIME ;
2010-03-08 04:55:21 -06:00
# ifndef DISABLE_TRACE
if ( www2Trace )
fprintf ( stderr , " [HTMIMEConvert] HELLO! \n " ) ;
# endif
me - > sink = sink ;
me - > anchor = anchor ;
me - > target = NULL ;
me - > state = BEGINNING_OF_LINE ;
me - > format = WWW_PLAINTEXT ;
me - > targetRep = pres - > rep_out ;
me - > boundary = 0 ; /* Not set yet */
me - > location = 0 ;
me - > interrupted = 0 ;
me - > encoding = 0 ;
me - > compression_encoding = 0 ;
me - > content_length = - 1 ;
me - > header_length = 0 ; /* bjs - to allow differentiation between
content and header for read length */
me - > expires = 0 ;
me - > last_modified = 0 ;
return me ;
}
/* bjs - a kludge for HTFormat.c */
int HTMIME_get_header_length ( HTStream * me )
{
2013-03-09 18:59:42 -06:00
if ( me - > isa ! = & HTMIME ) return 0 ; /* in case we screw up */
2010-03-08 04:55:21 -06:00
return me - > header_length ;
}