00001
00002
00003
00004
00005
00006 #include <string.h>
00007 #include "ghttp.h"
00008 #include "gstringext.h"
00009 #include "garg.h"
00010
00011
00012 gURI::sSchemeUse gURI::schemeTbl[]={
00013 { gURI::e_ftp, "ftp", 1738 },
00014 { gURI::e_http, "http", 2616 },
00015 { gURI::e_file, "file", 0 },
00016 { gURI::e_invalid, NULL, -1 }
00017
00018 };
00019
00020 gVersion::gVersion (short major, short minor)
00021 : vMajor( major ),
00022 vMinor( minor )
00023 {
00024 }
00025
00026 bool gVersion::SetVersion (gString& s)
00027 {
00028
00029 gParam param( s, "." );
00030 unsigned n = param.N();
00031 if ( n<1 ) return false;
00032 vMinor = -1;
00033 if ( n<2 ) {
00034 return thisSetMajorOrMinor( s.Str(), vMajor )==0;
00035 }
00036 vMajor = -1;
00037
00038 return
00039 thisSetMajorOrMinor( param.Str(1), vMajor )==0 &&
00040 thisSetMajorOrMinor( param.Str(2), vMinor )==0;
00041 }
00042
00043 bool gVersion::operator> (gVersion& version)
00044 {
00045 if ( vMajor > version.vMajor ) return true;
00046 if ( vMajor < version.vMajor ) return false;
00047 return vMinor > version.vMinor;
00048 }
00049
00050 bool gVersion::operator< (gVersion& version)
00051 {
00052 if ( vMajor < version.vMajor ) return true;
00053 if ( vMajor > version.vMajor ) return false;
00054 return vMinor < version.vMinor;
00055 }
00056
00057 int gVersion::thisSetMajorOrMinor (char* s, short& ver)
00058 {
00059
00060 t_uint32 m=0;
00061 int error = gStrControl::Self().ConvertToUInt32( s, m );
00062 if ( error!=0 ) return error;
00063 if ( m>(t_uint32)MAX_INT16_I ) return -1;
00064 ver = (short)m;
00065 return 0;
00066 }
00067
00068 gBigBuffer::gBigBuffer (t_uint32 bufSize)
00069 : baseBuf( nil ),
00070 isDynamic( bufSize==0 ),
00071 usedSize( 0 ),
00072 nNodes( 0 ), maxNodes( 10 ),
00073 bNode( nil ),
00074 fTemp( nil ),
00075 hasOverbuffer( false ),
00076 baseSizeBuf( 0 )
00077 {
00078 if ( isDynamic ) bufSize = 0x1000;
00079
00080
00081
00082
00083 thisAllocateBuf( bufSize );
00084 }
00085
00086 gBigBuffer::~gBigBuffer ()
00087 {
00088 delete baseBuf;
00089 if ( bNode!=nil ) {
00090 for (unsigned idxNode=0; idxNode<maxNodes; idxNode++) delete bNode[ idxNode ];
00091 delete[] bNode;
00092 }
00093
00094 delete fTemp;
00095 }
00096
00097 gBigBuffer::eBufferKind gBigBuffer::GetBufferKind ()
00098 {
00099 if ( hasOverbuffer ) return e_InFile;
00100 return GetNumberNodes()==0 ? e_NormalRAM : e_NodesRAM;
00101 }
00102
00103 gUCharBuffer* gBigBuffer::GetNode (unsigned idxNode)
00104 {
00105 ASSERTION(idxNode<nNodes,"idxNode<nNodes");
00106 gUCharBuffer* sBuf = bNode[ idxNode ];
00107 ASSERTION(sBuf!=nil,"sBuf!=nil");
00108 return sBuf;
00109 }
00110
00111 gFileTemp& gBigBuffer::GetFile ()
00112 {
00113 ASSERTION(fTemp!=nil,"fTemp!=nil");
00114 return *fTemp;
00115 }
00116
00117 bool gBigBuffer::NewFile ()
00118 {
00119
00120 delete fTemp;
00121 fTemp = new gFileTemp( "htc" );
00122 ASSERTION(fTemp!=nil,"fTemp!=nil");
00123 return true;
00124 }
00125
00126 bool gBigBuffer::WriteBuf (int fHandle, gUCharBuffer& sBuf, unsigned nBytes)
00127 {
00128
00129 hasOverbuffer = true;
00130 return thisWrite( fHandle, sBuf, nBytes )==0;
00131 }
00132
00133 bool gBigBuffer::Flush (unsigned nBytes)
00134 {
00135 bool doNeedNode = usedSize>0;
00136 unsigned idxNode;
00137
00138 ASSERTION(baseBuf!=nil,"Flush(1)");
00139 if ( nBytes==0 ) return true;
00140 if ( doNeedNode==false ) return true;
00141
00142 if ( nNodes>=maxNodes ) {
00143 return thisOverbuffer( nBytes )==0;
00144 }
00145 idxNode = nNodes++;
00146 ASSERTION(bNode[idxNode]==nil,"bNode[idxNode]==nil");
00147 bNode[ idxNode ] = new gUCharBuffer( nBytes+1 );
00148 gUCharBuffer* sBuf = bNode[ idxNode ];
00149 ASSERTION(sBuf!=nil,"Flush(2)");
00150 memcpy( sBuf->uBuf, baseBuf->uBuf, (size_t)(sBuf->size = nBytes) );
00151
00152 delete baseBuf;
00153 baseBuf = new gUCharBuffer( baseSizeBuf+1 );
00154 ASSERTION(baseBuf!=nil,"Flush(3)");
00155 return true;
00156 }
00157
00158 bool gBigBuffer::thisAllocateBuf (t_uint32 bufSize)
00159 {
00160 if ( bufSize==0 ) return true;
00161
00162
00163
00164
00165 ASSERTION(bufSize<MAX_HTTP_CHUNK_SIZE,"thisAllocateBuf(1)");
00166 baseSizeBuf = bufSize;
00167 baseBuf = new gUCharBuffer( bufSize+1 );
00168 bNode = new gUCharBuffer*[ maxNodes ];
00169 ASSERTION(bNode!=nil,"thisAllocateBuf(2)");
00170 for (unsigned idxNode=0; idxNode<maxNodes; idxNode++) bNode[ idxNode ] = nil;
00171 return baseBuf!=nil;
00172 }
00173
00174 int gBigBuffer::thisOverbuffer (unsigned nBytes)
00175 {
00176 unsigned idxNode;
00177
00178 hasOverbuffer = true;
00179 if ( fTemp==nil ) {
00180 fTemp = new gFileTemp( "htp" );
00181 ASSERTION(fTemp!=nil,"fTemp!=nil");
00182
00183 for (idxNode=0; idxNode<nNodes; idxNode++) {
00184 ASSERTION(bNode[idxNode]!=nil,"bNode[idxNode]!=nil");
00185 if ( thisWrite( fTemp->fHandle, *bNode[idxNode], nBytes )!=0 ) return 2;
00186 }
00187 }
00188
00189 return thisWrite( fTemp->fHandle, *baseBuf, nBytes )!=0 ? 2 : 0;
00190 }
00191
00192 int gBigBuffer::thisWrite (int fHandle, gUCharBuffer& sBuf, unsigned nBytes)
00193 {
00194
00195 if ( gFileControl::Self().Write( fHandle, sBuf.uBuf, nBytes ) ) return 0;
00196 return gFileControl::Self().lastOpError;
00197 }
00198
00199 gURI::gURI ()
00200 : lastOpError( 0 ),
00201 pathType( e_NoType ),
00202 scheme( gURI::e_invalid ),
00203 isOkScheme( true )
00204 {
00205 }
00206
00207 gURI::gURI (eScheme aScheme)
00208 : lastOpError( 0 ),
00209 pathType( e_NoType ),
00210 scheme( aScheme ),
00211 isOkScheme( true )
00212 {
00213 }
00214
00215 gURI::~gURI ()
00216 {
00217 }
00218
00219 bool gURI::IsOk ()
00220 {
00221 return IsOkScheme()==true && pathType!=e_NoType;
00222 }
00223
00224 char* gURI::Str ()
00225 {
00226 return gString::Str();
00227 }
00228
00229 bool gURI::SetString (char* s)
00230 {
00231
00232 sDomain.SetEmpty();
00233 sPath.SetEmpty();
00234 sOriginal.SetEmpty();
00235 if ( s==nil ) return false;
00236
00237 sOriginal.Set( s );
00238 gString sTemp( s );
00239 lastOpError = thisParseString( sTemp.Str(), scheme );
00240 DBGPRINT("DBG: gURI::SetString(%s), lastOpError=%d, scheme=%d\n",s,lastOpError,scheme);
00241 return lastOpError==0;
00242 }
00243
00244 bool gURI::IsValidDomain ()
00245 {
00246 bool isOkDomain = sDomain.Find('/')==0;
00247 if ( sDomain.Find(' ') ) return false;
00248
00249 return isOkDomain;
00250 }
00251
00252 int gURI::thisParseString (char* s, eScheme aScheme)
00253 {
00254 int error = 0;
00255 unsigned pos;
00256 bool hasSpecScheme;
00257
00258 ASSERTION(s!=nil,"s!=nil");
00259 pathType = e_NoType;
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 isOkScheme = false;
00275 pos = gStrControl::Self().Find( s, ':' );
00276 if ( (hasSpecScheme = pos>0)==true ) {
00277
00278 s[ pos-1 ] = 0;
00279 eScheme inputScheme( thisGetSchemeFromString( s, error ) );
00280 s += pos;
00281 if ( error==0 ) {
00282
00283
00284 if ( aScheme!=e_invalid && inputScheme!=aScheme ) {
00285 error = 4;
00286 }
00287 }
00288 DBGPRINT("DBG: inputScheme=%d, requested scheme=%d, error=%d\n",inputScheme,aScheme,error);
00289 }
00290
00291 if ( error!=0 ) return error;
00292 isOkScheme = true;
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 pos = s[0]=='/';
00303 if ( pos==1 ) {
00304 pos += s[1]=='/';
00305 s += pos;
00306 pathType = pos>=2 ? e_Absolute : e_RelativeQualified;
00307 }
00308 else {
00309 pathType = e_Relative;
00310 }
00311 return thisSetDomainPath( s, hasSpecScheme, aScheme );
00312 }
00313
00314 int gURI::thisSetDomainPath (char* s, bool hasSpecScheme, eScheme aScheme)
00315 {
00316 gString aStr( s );
00317 unsigned pos;
00318 pos = aStr.Find( '/' );
00319 if ( pos<=1 ) {
00320
00321
00322
00323
00324
00325
00326 if ( hasSpecScheme==false ) {
00327
00328 return thisSetPath( s );
00329 }
00330 sDomain.Set( s );
00331 return thisSetPath( nil );
00332 }
00333
00334
00335
00336 pos--;
00337 sDomain.CopyFromTo( aStr, 1, pos );
00338 return thisSetPath( s+pos );
00339 }
00340
00341 int gURI::thisSetPath (char* s)
00342 {
00343
00344
00345 ;
00346 if ( s==nil ) {
00347 Set( sDomain.Str() );
00348 return 0;
00349 }
00350 if ( s[0]==0 ) {
00351 Set( sDomain.Str() );
00352
00353 return 1;
00354 }
00355
00356
00357
00358 if ( s[0]!='/' ) {
00359 gString aPath( pathType==e_Absolute ? '/' : '\0' );
00360 aPath.Add( s );
00361 Set( aPath.Str() );
00362 sPath.Set( Str() );
00363 return 0;
00364 }
00365 Set( sDomain.Str() );
00366 Add( s );
00367 sPath.Set( s );
00368 return 0;
00369 }
00370
00371 gURI::eScheme gURI::thisGetSchemeFromString (char* s, int& error)
00372 {
00373 int i;
00374 char c, lowChar;
00375 bool isValid;
00376 bool isEscape;
00377 eScheme aScheme;
00378
00379 error = (int)e_invalid;
00380
00381 ASSERTION(s!=nil,"s!=nil");
00382 for (i=0; (c = s[i])!='\0'; ) {
00383
00384 lowChar = ( c>='A' && c<='Z' ) ? c+'a'-'A' : c;
00385 s[ i++ ] = lowChar;
00386 isEscape = lowChar=='%';
00387 isValid =
00388 (lowChar>='a' && lowChar<='z') ||
00389 (lowChar>='0' && lowChar<='9') ||
00390 lowChar=='$' || lowChar=='-' || lowChar=='_' ||
00391 lowChar=='@' || lowChar=='.' || lowChar=='&' ||
00392 lowChar=='!' || lowChar=='*' || lowChar=='"' ||
00393 lowChar=='\'' || lowChar=='(' || lowChar==')' ||
00394 lowChar==',' || isEscape==true;
00395 if ( isValid==false ) return e_invalid;
00396 if ( isEscape ) {
00397 c = s[ i++ ];
00398 isValid = (c>='0' && c<='9') || (c>='a' && c<='f');
00399 if ( isValid==false ) return e_invalid;
00400 c = s[ i++ ];
00401 isValid = (c>='0' && c<='9') || (c>='a' && c<='f');
00402 if ( isValid==false ) return e_invalid;
00403 }
00404 }
00405
00406
00407
00408 error = thisFetchScheme( s, aScheme )<0 ? 2 : 0;
00409 return aScheme;
00410 }
00411
00412 int gURI::thisFetchScheme (char* s, eScheme& foundScheme)
00413 {
00414 int i;
00415 short rfcCode;
00416 char* name;
00417
00418 ASSERTION(s!=nil,"s!=nil");
00419 foundScheme = e_invalid;
00420
00421 for (i=0; (rfcCode = schemeTbl[i].rfcCode)>=0; i++) {
00422 name = schemeTbl[i].name;
00423 if ( gStrControl::Self().Match( s, name ) ) {
00424 foundScheme = schemeTbl[i].theScheme;
00425 return i;
00426 }
00427 }
00428 return -1;
00429 }
00430
00431 gHttpGeneric::gHttpGeneric (gTcpConnect& connection)
00432 : pConnection( &connection )
00433 {
00434 }
00435
00436 gHttpGeneric::~gHttpGeneric ()
00437 {
00438 }
00439
00440 gUCharBuffer& gHttpGeneric::GetBaseBuffer ()
00441 {
00442 gUCharBuffer* sBuf;
00443 sBuf = GetBuffer().baseBuf;
00444 ASSERTION(sBuf!=nil,"sBuf!=nil");
00445 return *sBuf;
00446 }
00447
00448 gBigBuffer& gHttpGeneric::GetBuffer ()
00449 {
00450 ASSERTION_FALSE("TODO");
00451 return biffBuffer;
00452 }
00453
00454